diff --git a/.github/workflows/TestCompile.yml b/.github/workflows/TestCompile.yml new file mode 100644 index 000000000..56ee19679 --- /dev/null +++ b/.github/workflows/TestCompile.yml @@ -0,0 +1,84 @@ +# TestCompile.yml +# Github workflow script to test compile all examples of an Arduino core repository. +# +# Copyright (C) 2020 Armin Joachimsmeyer +# https://github.com/ArminJo/Github-Actions +# + +# This is the name of the workflow, visible on GitHub UI. +name: TestCompile +on: + workflow_dispatch: # To run it manually + description: 'manual build check' + push: # see: https://help.github.com/en/actions/reference/events-that-trigger-workflows#pull-request-event-pull_request + paths: + - '**.ino' + - '**.cpp' + - '**.h' + - '**TestCompile.yml' + pull_request: +jobs: + build: + name: Test compiling examples for Arduino_STM32 + runs-on: ubuntu-latest + env: + # PLATFORM_DEFAULT_URL: http://dan.drown.org/stm32duino/package_STM32duino_index.json + # Comma separated list without double quotes around the list. + REQUIRED_LIBRARIES: SdFat,Streaming,Adafruit GFX Library,Adafruit SSD1306,Adafruit STMPE610,Adafruit TouchScreen,SD + + strategy: + matrix: + # The matrix will produce one job for each configuration parameter of type `arduino-boards-fqbn` + # In the Arduino IDE, the fqbn is printed in the first line of the verbose output for compilation as parameter -fqbn=... for the "arduino-builder -dump-prefs" command + # + # Examples: arduino:avr:uno, arduino:avr:leonardo, arduino:avr:nano, arduino:avr:mega + # arduino:sam:arduino_due_x, arduino:samd:arduino_zero_native" + # ATTinyCore:avr:attinyx5:chip=85,clock=1internal, digistump:avr:digispark-tiny, digistump:avr:digispark-pro + # STM32:stm32:GenF1:pnum=BLUEPILL_F103C8 + # esp8266:esp8266:huzzah:eesz=4M3M,xtal=80, esp32:esp32:featheresp32:FlashFreq=80 + # You may add a suffix behind the fqbn with "|" to specify one board for e.g. different compile options like arduino:avr:uno|trace + ############################################################################################################# + arduino-boards-fqbn: + - stm32duino:STM32F1:genericSTM32F103C + #- stm32duino:STM32F1:nucleo_f103rb + #- stm32duino:STM32F1:mapleMini + + # Specify parameters for each board. + # With sketches-exclude you may exclude specific examples for a board. Use a comma separated list. + ############################################################################################################# + include: + - arduino-boards-fqbn: stm32duino:STM32F1:genericSTM32F103C + # errors: BOARD_BUTTON_PIN not defined, 'textsize' was not declared in this scope, 'A0' was not declared in this scope, 'BOARD_LED_PIN' was not declared in this scope, no matching function for call to 'SPIClass::transfer(uint8_t*&, size_t&) + sketches-exclude: Debounce,StateChangeDetection,Button,QASlave,InteractiveTest,WhileStatementConditional,HardwareTimerOnePulseMode,HardwareTimerPWMInput,StringEx_Parsing,hello_STM,MIDI_Classic_Mode,JeeUdp,multipacketSD,udpListener,etherNode,SingleChannelContinuousConversion,OLED_I2C_NumberFonts,OLED_I2C_TinyFont_View,OLED_I2C_Scrolling_Text,OLED_I2C_Bitmap,OLED_I2C_3D_Cube,OLED_I2C_ViewFont,OLED_I2C_Graph_Demo,OLED_I2C_Brightness,OLED_I2C_NumberFonts,OLED_I2C_TinyFont_View,coos_display_blink,rtos_blink,rtos_display_blink,Twitter_Serial_GW,XivelyClientString,XivelyClient,ssd1306_128x64_i2c_STM32,breakouttouchpaint,graphicstest,stm32_graphicstest,TFT_Rainbow_ILI9341,TFT_Clock_ILI9341,TFT_Clock_Digital_ILI9341,TFT_Show_Font_ILI9341,graphicstest,stm32_graphicstest,onoffbutton_breakout,onoffbutton_breakout,onoffbutton,spitftbitmap,ssd1306_128x64_spi,ssd1306_128x32_i2c,ssd1306_128x32_spi,sdreader + + #- arduino-boards-fqbn: stm32duino:STM32F1:nucleo_f103rb + # Examples to exclude because of ... + #sketches-exclude: WiiClassicJoystick,BasicUsage,DigisparkOLED,SoftPwm13Pins,TinySoftPwmDemo,DigiUSB2LCD,DigisparkUSBDemo,ArduinoNunchukDemo,DigisparkJoystickDemo + + # Do not cancel all jobs / architectures if one job fails + fail-fast: false + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Use this repo as Arduino core + run: | + mkdir --parents $HOME/.arduino15/packages/stm32duino/hardware/STM32F1/0.0.7 # dummy release number + # cannot move, since we want to compile the examples in the library subfolder :-) + ln -s $GITHUB_WORKSPACE/STM32F1/* $HOME/.arduino15/packages/stm32duino/hardware/STM32F1/0.0.7 + #cp --recursive $GITHUB_WORKSPACE/STM32F1/* $HOME/.arduino15/packages/stm32duino/hardware/STM32F1/0.0.7/ + #ls -l --dereference --recursive --all $HOME/.arduino15/packages/stm32duino/hardware/STM32F1/0.0.7/ + + - name: Compile all examples + uses: ArminJo/arduino-test-compile@master + with: + required-libraries: ${{ env.REQUIRED_LIBRARIES }} + arduino-board-fqbn: ${{ matrix.arduino-boards-fqbn }} + arduino-platform: stm32duino:STM32F1,arduino:sam # we require the C compiler from it. See dependencies of package_STM32duino_index.json + #platform-default-url: ${{ env.PLATFORM_DEFAULT_URL }} + #platform-url: ${{ matrix.platform-url }} + sketches-exclude: ${{ matrix.sketches-exclude }} + build-properties: ${{ toJson(matrix.build-properties) }} + sketch-names: "*.ino" + sketch-names-find-start: STM32F1/libraries/*/examples/ + #debug-install: true diff --git a/.gitignore b/.gitignore index 078faf600..ef5aee566 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ other/maple-bootloader/*~ *.o *.bak *.1 +platform.local.txt +boards.local.txt diff --git a/README.md b/README.md index 9493be94e..7e931db80 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,37 @@ -Arduino STM32 -============= +Arduino STM32 +============= ## Notice - This software is experimental and a work in progress. Under no circumstances should these files be used in relation to any critical system(s). Use of these files is at your own risk. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -## Summary: -This repo contains, the "Hardware" files to support STM32 based boards on Arduino version 1.8.x (some older versions may also work) including [LeafLabs Maple, and Maple mini](http://www.leaflabs.com/about-maple/), and other generic STM32F103 boards - -***PRIMARY SUPPORT FORUM: http://www.stm32duino.com/*** +## Summary: +This repo contains the "Hardware" files to support STM32 based boards on Arduino version 1.8.x (some older versions may also work) including [LeafLabs Maple, and Maple mini](http://www.leaflabs.com/about-maple/), and other generic STM32F103 boards. -***We are also on Gitter https://gitter.im/stm32duino/Lobby/*** -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/stm32duino/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -## Background & Support: -* Based on https://github.com/bobc/maple-asp, which is in turn based on LibMaple by Leaflabs +## Background & Support: +* Based on https://github.com/bobc/maple-asp, which is in turn based on LibMaple by Leaflabs * **Please read the wiki (https://github.com/rogerclarkmelbourne/Arduino_STM32/wiki) for full details** -* See also my blog: http://www.rogerclark.net/stm32f103-and-maple-maple-mini-with-arduino-1-5-x-ide/ -* **NEW: Main support site for using STM32 boards with the Arduino IDE: http://www.stm32duino.com/** +* See also my blog: http://www.rogerclark.net/stm32f103-and-maple-maple-mini-with-arduino-1-5-x-ide/ +* **NEW: Main support site for using STM32 boards with the Arduino IDE: http://www.stm32duino.com/** * Original LeafLabs "Docs:" http://docs.leaflabs.com/docs.leaflabs.com/index.html +## Known issues +* Use of static variables inside functions greatly increase the code size becuase additional code is needed for thread-safe handling of these statics. +If this is a problem for your application, please edit platform.txt and add -fno-threadsafe-statics the compiler.cpp.flags -**YouTube Videos:** -* 20141116: [Arduino 1.5.8 IDE with STM32 board](https://www.youtube.com/watch?v=-zwGnytGT8M) -* 20150413: [STM32 for Arduino 1.6.2 or newer (update)](https://www.youtube.com/watch?v=TePglhSkghg) -* 20150419: [Uploading via USB to Serial to STM32F103 boards](https://www.youtube.com/watch?v=G_RF0a0hrak) -## Additional Links & Info: -* https://www.hackster.io/rayburne/4-dollar-90-mips-32-bit-72-mhz-arm-arduino +## Additional Links & Info: +* https://www.hackster.io/rayburne/4-dollar-90-mips-32-bit-72-mhz-arm-arduino -## Purchase info: +## Purchase info: ### Entry level boards - * [Ebay search for "arduino maple"](http://www.ebay.com/sch/i.html?_from=R40&_sacat=0&LH_BIN=1&_nkw=arduino+maple&_sop=15) (currently costs <$5 with shipping) -* [AliExpress search for "leaflabs maple"] (http://www.aliexpress.com/wholesale?catId=0&initiative_id=SB_20150607085526&SearchText=leaflabs+maple) +* [AliExpress search for "leaflabs maple"](http://www.aliexpress.com/wholesale?catId=0&initiative_id=SB_20150607085526&SearchText=leaflabs+maple) ### Bigger boards (You need to load the stm32duino bootloader) - -Some supplier have this board e.g. - -*[ STM32F103VET ](http://www.ebay.com.au/itm/1PCS-STM32F103VET6-ARM-STM32-Minimum-System-Development-Board-Arduino-M77-/301433302819) - -*[There is also a STM32F103ZET board which also works, however they are not always available. They have been listed as "STM32F103ZET6 Minimum System Development Board ARM STM32 Cortex-m3 M75"] -(http://www.ebay.com.au/itm/1pcs-STM32F103ZET6-Minimum-System-Development-Board-ARM-STM32-Cortex-m3-M75-/291305557264) - +Some suppliers have this board e.g. +* [ STM32F103VET ](http://www.ebay.com.au/itm/1PCS-STM32F103VET6-ARM-STM32-Minimum-System-Development-Board-Arduino-M77-/301433302819) +* [There is also a STM32F103ZET board which also works, however they are not always available. They have been listed as "STM32F103ZET6 Minimum System Development Board ARM STM32 Cortex-m3 M75"](http://www.ebay.com.au/itm/1pcs-STM32F103ZET6-Minimum-System-Development-Board-ARM-STM32-Cortex-m3-M75-/291305557264) diff --git a/STM32F1/boards.txt b/STM32F1/boards.txt index 49c12932a..2cb207231 100644 --- a/STM32F1/boards.txt +++ b/STM32F1/boards.txt @@ -38,40 +38,38 @@ mapleMini.menu.bootloader_version.bootloader20.upload.maximum_data_size=20480 mapleMini.menu.bootloader_version.bootloader20.upload.altID=2 #-- CPU Clock frequency -mapleMini.menu.cpu_speed.speed_72mhz=72Mhz (Normal) +mapleMini.menu.cpu_speed.speed_72mhz=72MHz (Normal) mapleMini.menu.cpu_speed.speed_72mhz.build.f_cpu=72000000L -mapleMini.menu.cpu_speed.speed_48mhz=48Mhz (Slow - with USB) +mapleMini.menu.cpu_speed.speed_48mhz=48MHz (Slow - with USB) mapleMini.menu.cpu_speed.speed_48mhz.build.f_cpu=48000000L -mapleMini.menu.cpu_speed.speed_128mhz=Overclocked 128Mhz NO USB SERIAL. MANUAL RESET NEEDED TO UPLOAD +mapleMini.menu.cpu_speed.speed_128mhz=Overclocked 128MHz NO USB SERIAL. MANUAL RESET NEEDED TO UPLOAD mapleMini.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations mapleMini.menu.opt.osstd=Smallest (default) -mapleMini.menu.opt.osstd.build.flags.optimize=-Os -mapleMini.menu.opt.osstd.build.flags.ldspecs= -mapleMini.menu.opt.oslto=Smallest Code with LTO -mapleMini.menu.opt.oslto.build.flags.optimize=-Os -flto -mapleMini.menu.opt.oslto.build.flags.ldspecs=-flto +#mapleMini.menu.opt.oslto=Smallest Code with LTO +#mapleMini.menu.opt.oslto.build.flags.optimize=-Os -flto +#mapleMini.menu.opt.oslto.build.flags.ldspecs=-flto mapleMini.menu.opt.o1std=Fast (-O1) mapleMini.menu.opt.o1std.build.flags.optimize=-O1 mapleMini.menu.opt.o1std.build.flags.ldspecs= -mapleMini.menu.opt.o1lto=Fast (-O1) with LTO -mapleMini.menu.opt.o1lto.build.flags.optimize=-O1 -flto -mapleMini.menu.opt.o1lto.build.flags.ldspecs=-flto +#mapleMini.menu.opt.o1lto=Fast (-O1) with LTO +#mapleMini.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#mapleMini.menu.opt.o1lto.build.flags.ldspecs=-flto mapleMini.menu.opt.o2std=Faster (-O2) mapleMini.menu.opt.o2std.build.flags.optimize=-O2 mapleMini.menu.opt.o2std.build.flags.ldspecs= -mapleMini.menu.opt.o2lto=Faster (-O2) with LTO -mapleMini.menu.opt.o2lto.build.flags.optimize=-O2 -flto -mapleMini.menu.opt.o2lto.build.flags.ldspecs=-flto +#mapleMini.menu.opt.o2lto=Faster (-O2) with LTO +#mapleMini.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#mapleMini.menu.opt.o2lto.build.flags.ldspecs=-flto mapleMini.menu.opt.o3std=Fastest (-O3) mapleMini.menu.opt.o3std.build.flags.optimize=-O3 mapleMini.menu.opt.o3std.build.flags.ldspecs= -mapleMini.menu.opt.o3lto=Fastest (-O3) with LTO -mapleMini.menu.opt.o3lto.build.flags.optimize=-O3 -flto -mapleMini.menu.opt.o3lto.build.flags.ldspecs=-flto +#mapleMini.menu.opt.o3lto=Fastest (-O3) with LTO +#mapleMini.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#mapleMini.menu.opt.o3lto.build.flags.ldspecs=-flto mapleMini.menu.opt.ogstd=Debug (-g) mapleMini.menu.opt.ogstd.build.flags.optimize=-Og mapleMini.menu.opt.ogstd.build.flags.ldspecs= @@ -111,29 +109,27 @@ maple.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations maple.menu.opt.osstd=Smallest (default) -maple.menu.opt.osstd.build.flags.optimize=-Os -maple.menu.opt.osstd.build.flags.ldspecs= -maple.menu.opt.oslto=Smallest Code with LTO -maple.menu.opt.oslto.build.flags.optimize=-Os -flto -maple.menu.opt.oslto.build.flags.ldspecs=-flto +#maple.menu.opt.oslto=Smallest Code with LTO +#maple.menu.opt.oslto.build.flags.optimize=-Os -flto +#maple.menu.opt.oslto.build.flags.ldspecs=-flto maple.menu.opt.o1std=Fast (-O1) maple.menu.opt.o1std.build.flags.optimize=-O1 maple.menu.opt.o1std.build.flags.ldspecs= -maple.menu.opt.o1lto=Fast (-O1) with LTO -maple.menu.opt.o1lto.build.flags.optimize=-O1 -flto -maple.menu.opt.o1lto.build.flags.ldspecs=-flto +#maple.menu.opt.o1lto=Fast (-O1) with LTO +#maple.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#maple.menu.opt.o1lto.build.flags.ldspecs=-flto maple.menu.opt.o2std=Faster (-O2) maple.menu.opt.o2std.build.flags.optimize=-O2 maple.menu.opt.o2std.build.flags.ldspecs= -maple.menu.opt.o2lto=Faster (-O2) with LTO -maple.menu.opt.o2lto.build.flags.optimize=-O2 -flto -maple.menu.opt.o2lto.build.flags.ldspecs=-flto +#maple.menu.opt.o2lto=Faster (-O2) with LTO +#maple.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#maple.menu.opt.o2lto.build.flags.ldspecs=-flto maple.menu.opt.o3std=Fastest (-O3) maple.menu.opt.o3std.build.flags.optimize=-O3 maple.menu.opt.o3std.build.flags.ldspecs= -maple.menu.opt.o3lto=Fastest (-O3) with LTO -maple.menu.opt.o3lto.build.flags.optimize=-O3 -flto -maple.menu.opt.o3lto.build.flags.ldspecs=-flto +#maple.menu.opt.o3lto=Fastest (-O3) with LTO +#maple.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#maple.menu.opt.o3lto.build.flags.ldspecs=-flto maple.menu.opt.ogstd=Debug (-g) maple.menu.opt.ogstd.build.flags.optimize=-Og maple.menu.opt.ogstd.build.flags.ldspecs= @@ -174,30 +170,28 @@ mapleRET6.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations mapleRET6.menu.opt.osstd=Smallest (default) -mapleRET6.menu.opt.osstd.build.flags.optimize=-Os -mapleRET6.menu.opt.osstd.build.flags.ldspecs= -mapleRET6.menu.opt.oslto=Smallest Code with LTO -mapleRET6.menu.opt.oslto.build.flags.optimize=-Os -flto -mapleRET6.menu.opt.oslto.build.flags.ldspecs=-flto +#mapleRET6.menu.opt.oslto=Smallest Code with LTO +#mapleRET6.menu.opt.oslto.build.flags.optimize=-Os -flto +#mapleRET6.menu.opt.oslto.build.flags.ldspecs=-flto mapleRET6.menu.opt.o1std=Fast (-O1) mapleRET6.menu.opt.o1std.build.flags.optimize=-O1 mapleRET6.menu.opt.o1std.build.flags.ldspecs= -mapleRET6.menu.opt.o1lto=Fast (-O1) with LTO -mapleRET6.menu.opt.o1lto.build.flags.optimize=-O1 -flto -mapleRET6.menu.opt.o1lto.build.flags.ldspecs=-flto +#mapleRET6.menu.opt.o1lto=Fast (-O1) with LTO +#mapleRET6.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#mapleRET6.menu.opt.o1lto.build.flags.ldspecs=-flto mapleRET6.menu.opt.o2std=Faster (-O2) mapleRET6.menu.opt.o2std.build.flags.optimize=-O2 mapleRET6.menu.opt.o2std.build.flags.ldspecs= -mapleRET6.menu.opt.o2lto=Faster (-O2) with LTO -mapleRET6.menu.opt.o2lto.build.flags.optimize=-O2 -flto -mapleRET6.menu.opt.o2lto.build.flags.ldspecs=-flto +#mapleRET6.menu.opt.o2lto=Faster (-O2) with LTO +#mapleRET6.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#mapleRET6.menu.opt.o2lto.build.flags.ldspecs=-flto mapleRET6.menu.opt.o3std=Fastest (-O3) mapleRET6.menu.opt.o3std.build.flags.optimize=-O3 mapleRET6.menu.opt.o3std.build.flags.ldspecs= -mapleRET6.menu.opt.o3lto=Fastest (-O3) with LTO -mapleRET6.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#mapleRET6.menu.opt.o3lto=Fastest (-O3) with LTO +#mapleRET6.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#mapleRET6.menu.opt.o3lto.build.flags.ldspecs=-flto mapleRET6.menu.opt.ogstd=Debug (-g) -mapleRET6.menu.opt.o3lto.build.flags.ldspecs=-flto mapleRET6.menu.opt.ogstd.build.flags.optimize=-Og mapleRET6.menu.opt.ogstd.build.flags.ldspecs= @@ -244,30 +238,28 @@ microduino32_flash.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations microduino32_flash.menu.opt.osstd=Smallest (default) -microduino32_flash.menu.opt.osstd.build.flags.optimize=-Os -microduino32_flash.menu.opt.osstd.build.flags.ldspecs= -microduino32_flash.menu.opt.oslto=Smallest Code with LTO -microduino32_flash.menu.opt.oslto.build.flags.optimize=-Os -flto -microduino32_flash.menu.opt.oslto.build.flags.ldspecs=-flto +#microduino32_flash.menu.opt.oslto=Smallest Code with LTO +#microduino32_flash.menu.opt.oslto.build.flags.optimize=-Os -flto +#microduino32_flash.menu.opt.oslto.build.flags.ldspecs=-flto microduino32_flash.menu.opt.o1std=Fast (-O1) microduino32_flash.menu.opt.o1std.build.flags.optimize=-O1 microduino32_flash.menu.opt.o1std.build.flags.ldspecs= -microduino32_flash.menu.opt.o1lto=Fast (-O1) with LTO -microduino32_flash.menu.opt.o1lto.build.flags.optimize=-O1 -flto -microduino32_flash.menu.opt.o1lto.build.flags.ldspecs=-flto +#microduino32_flash.menu.opt.o1lto=Fast (-O1) with LTO +#microduino32_flash.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#microduino32_flash.menu.opt.o1lto.build.flags.ldspecs=-flto microduino32_flash.menu.opt.o2std=Faster (-O2) microduino32_flash.menu.opt.o2std.build.flags.optimize=-O2 microduino32_flash.menu.opt.o2std.build.flags.ldspecs= -microduino32_flash.menu.opt.o2lto=Faster (-O2) with LTO -microduino32_flash.menu.opt.o2lto.build.flags.optimize=-O2 -flto -microduino32_flash.menu.opt.o2lto.build.flags.ldspecs=-flto +#microduino32_flash.menu.opt.o2lto=Faster (-O2) with LTO +#microduino32_flash.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#microduino32_flash.menu.opt.o2lto.build.flags.ldspecs=-flto microduino32_flash.menu.opt.o3std=Fastest (-O3) microduino32_flash.menu.opt.o3std.build.flags.optimize=-O3 microduino32_flash.menu.opt.o3std.build.flags.ldspecs= -microduino32_flash.menu.opt.o3lto=Fastest (-O3) with LTO -microduino32_flash.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#microduino32_flash.menu.opt.o3lto=Fastest (-O3) with LTO +#microduino32_flash.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#microduino32_flash.menu.opt.o3lto.build.flags.ldspecs=-flto microduino32_flash.menu.opt.ogstd=Debug (-g) -microduino32_flash.menu.opt.o3lto.build.flags.ldspecs=-flto microduino32_flash.menu.opt.ogstd.build.flags.optimize=-Og microduino32_flash.menu.opt.ogstd.build.flags.ldspecs= @@ -310,30 +302,28 @@ nucleo_f103rb.menu.device_variant.NucleoF103_HSE.build.extra_flags=-DNUCLEO_HSE_ #-- Optimizations nucleo_f103rb.menu.opt.osstd=Smallest (default) -nucleo_f103rb.menu.opt.osstd.build.flags.optimize=-Os -nucleo_f103rb.menu.opt.osstd.build.flags.ldspecs= -nucleo_f103rb.menu.opt.oslto=Smallest Code with LTO -nucleo_f103rb.menu.opt.oslto.build.flags.optimize=-Os -flto -nucleo_f103rb.menu.opt.oslto.build.flags.ldspecs=-flto +#nucleo_f103rb.menu.opt.oslto=Smallest Code with LTO +#nucleo_f103rb.menu.opt.oslto.build.flags.optimize=-Os -flto +#nucleo_f103rb.menu.opt.oslto.build.flags.ldspecs=-flto nucleo_f103rb.menu.opt.o1std=Fast (-O1) nucleo_f103rb.menu.opt.o1std.build.flags.optimize=-O1 nucleo_f103rb.menu.opt.o1std.build.flags.ldspecs= -nucleo_f103rb.menu.opt.o1lto=Fast (-O1) with LTO -nucleo_f103rb.menu.opt.o1lto.build.flags.optimize=-O1 -flto -nucleo_f103rb.menu.opt.o1lto.build.flags.ldspecs=-flto +#nucleo_f103rb.menu.opt.o1lto=Fast (-O1) with LTO +#nucleo_f103rb.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#nucleo_f103rb.menu.opt.o1lto.build.flags.ldspecs=-flto nucleo_f103rb.menu.opt.o2std=Faster (-O2) nucleo_f103rb.menu.opt.o2std.build.flags.optimize=-O2 nucleo_f103rb.menu.opt.o2std.build.flags.ldspecs= -nucleo_f103rb.menu.opt.o2lto=Faster (-O2) with LTO -nucleo_f103rb.menu.opt.o2lto.build.flags.optimize=-O2 -flto -nucleo_f103rb.menu.opt.o2lto.build.flags.ldspecs=-flto +#nucleo_f103rb.menu.opt.o2lto=Faster (-O2) with LTO +#nucleo_f103rb.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#nucleo_f103rb.menu.opt.o2lto.build.flags.ldspecs=-flto nucleo_f103rb.menu.opt.o3std=Fastest (-O3) nucleo_f103rb.menu.opt.o3std.build.flags.optimize=-O3 nucleo_f103rb.menu.opt.o3std.build.flags.ldspecs= -nucleo_f103rb.menu.opt.o3lto=Fastest (-O3) with LTO -nucleo_f103rb.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#nucleo_f103rb.menu.opt.o3lto=Fastest (-O3) with LTO +#nucleo_f103rb.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#nucleo_f103rb.menu.opt.o3lto.build.flags.ldspecs=-flto nucleo_f103rb.menu.opt.ogstd=Debug (-g) -nucleo_f103rb.menu.opt.o3lto.build.flags.ldspecs=-flto nucleo_f103rb.menu.opt.ogstd.build.flags.optimize=-Og nucleo_f103rb.menu.opt.ogstd.build.flags.ldspecs= @@ -346,6 +336,8 @@ genericSTM32F103C.build.variant=generic_stm32f103c genericSTM32F103C.build.vect=VECT_TAB_ADDR=0x8000000 genericSTM32F103C.build.core=maple genericSTM32F103C.build.board=GENERIC_STM32F103C +genericSTM32F103C.build.error_led_port=GPIOC +genericSTM32F103C.build.error_led_pin=13 genericSTM32F103C.upload.use_1200bps_touch=false genericSTM32F103C.upload.file_type=bin genericSTM32F103C.upload.auto_reset=true @@ -397,10 +389,25 @@ genericSTM32F103C.menu.upload_method.jlinkMethod.upload.protocol=jlink genericSTM32F103C.menu.upload_method.jlinkMethod.upload.tool=jlink_upload genericSTM32F103C.menu.upload_method.jlinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DSERIAL_USB -DGENERIC_BOOTLOADER +genericSTM32F103C.menu.upload_method.HIDUploadMethod=HID bootloader 2.0 +genericSTM32F103C.menu.upload_method.HIDUploadMethod.upload.tool=hid_upload +genericSTM32F103C.menu.upload_method.HIDUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER +genericSTM32F103C.menu.upload_method.HIDUploadMethod.build.vect=VECT_TAB_ADDR=0x8001000 +genericSTM32F103C.menu.upload_method.HIDUploadMethod.build.ldscript=ld/hid_bootloader.ld + #-- CPU Clock frequency + genericSTM32F103C.menu.cpu_speed.speed_72mhz=72Mhz (Normal) genericSTM32F103C.menu.cpu_speed.speed_72mhz.build.f_cpu=72000000L +genericSTM32F103C.menu.cpu_speed.speed_hsi_64mhz=64Mhz (HSI) +genericSTM32F103C.menu.cpu_speed.speed_hsi_64mhz.build.f_cpu=64000000L +genericSTM32F103C.menu.cpu_speed.speed_hsi_64mhz.build.hs_flag=-DUSE_HSI_CLOCK + +genericSTM32F103C.menu.cpu_speed.speed_hsi_48mhz=48Mhz (HSI- USB) +genericSTM32F103C.menu.cpu_speed.speed_hsi_48mhz.build.f_cpu=48000000L +genericSTM32F103C.menu.cpu_speed.speed_hsi_48mhz.build.hs_flag=-DUSE_HSI_CLOCK -DHSI_USB_SPEED + genericSTM32F103C.menu.cpu_speed.speed_48mhz=48Mhz (Slow - with USB) genericSTM32F103C.menu.cpu_speed.speed_48mhz.build.f_cpu=48000000L @@ -409,33 +416,127 @@ genericSTM32F103C.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations genericSTM32F103C.menu.opt.osstd=Smallest (default) -genericSTM32F103C.menu.opt.osstd.build.flags.optimize=-Os -genericSTM32F103C.menu.opt.osstd.build.flags.ldspecs= -genericSTM32F103C.menu.opt.oslto=Smallest Code with LTO -genericSTM32F103C.menu.opt.oslto.build.flags.optimize=-Os -flto -genericSTM32F103C.menu.opt.oslto.build.flags.ldspecs=-flto +#genericSTM32F103C.menu.opt.oslto=Smallest Code with LTO +#genericSTM32F103C.menu.opt.oslto.build.flags.optimize=-Os -flto +#genericSTM32F103C.menu.opt.oslto.build.flags.ldspecs=-flto genericSTM32F103C.menu.opt.o1std=Fast (-O1) genericSTM32F103C.menu.opt.o1std.build.flags.optimize=-O1 genericSTM32F103C.menu.opt.o1std.build.flags.ldspecs= -genericSTM32F103C.menu.opt.o1lto=Fast (-O1) with LTO -genericSTM32F103C.menu.opt.o1lto.build.flags.optimize=-O1 -flto -genericSTM32F103C.menu.opt.o1lto.build.flags.ldspecs=-flto +#genericSTM32F103C.menu.opt.o1lto=Fast (-O1) with LTO +#genericSTM32F103C.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#genericSTM32F103C.menu.opt.o1lto.build.flags.ldspecs=-flto genericSTM32F103C.menu.opt.o2std=Faster (-O2) genericSTM32F103C.menu.opt.o2std.build.flags.optimize=-O2 genericSTM32F103C.menu.opt.o2std.build.flags.ldspecs= -genericSTM32F103C.menu.opt.o2lto=Faster (-O2) with LTO -genericSTM32F103C.menu.opt.o2lto.build.flags.optimize=-O2 -flto -genericSTM32F103C.menu.opt.o2lto.build.flags.ldspecs=-flto +#genericSTM32F103C.menu.opt.o2lto=Faster (-O2) with LTO +#genericSTM32F103C.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#genericSTM32F103C.menu.opt.o2lto.build.flags.ldspecs=-flto genericSTM32F103C.menu.opt.o3std=Fastest (-O3) genericSTM32F103C.menu.opt.o3std.build.flags.optimize=-O3 genericSTM32F103C.menu.opt.o3std.build.flags.ldspecs= -genericSTM32F103C.menu.opt.o3lto=Fastest (-O3) with LTO -genericSTM32F103C.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103C.menu.opt.o3lto=Fastest (-O3) with LTO +#genericSTM32F103C.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103C.menu.opt.o3lto.build.flags.ldspecs=-flto genericSTM32F103C.menu.opt.ogstd=Debug (-g) -genericSTM32F103C.menu.opt.o3lto.build.flags.ldspecs=-flto genericSTM32F103C.menu.opt.ogstd.build.flags.optimize=-Og genericSTM32F103C.menu.opt.ogstd.build.flags.ldspecs= +###################### Generic STM32F103C6 ######################################## + +genericSTM32F103C6.name=Generic STM32F103C6/fake STM32F103C8 +genericSTM32F103C6.vid.0=0x1EAF +genericSTM32F103C6.pid.0=0x0004 +genericSTM32F103C6.build.variant=generic_stm32f103c +genericSTM32F103C6.build.vect=VECT_TAB_ADDR=0x8000000 +genericSTM32F103C6.build.core=maple +genericSTM32F103C6.build.board=GENERIC_STM32F103C +genericSTM32F103C6.build.error_led_port=GPIOC +genericSTM32F103C6.build.error_led_pin=13 +genericSTM32F103C6.upload.use_1200bps_touch=false +genericSTM32F103C6.upload.file_type=bin +genericSTM32F103C6.upload.auto_reset=true +genericSTM32F103C6.upload.tool=maple_upload +genericSTM32F103C6.upload.protocol=maple_dfu +genericSTM32F103C6.build.cpu_flags=-DMCU_STM32F103C6 +genericSTM32F103C6.build.ldscript=ld/jtag_c6.ld +genericSTM32F103C6.upload.maximum_size=32768 +genericSTM32F103C6.upload.maximum_data_size=10240 + +#---------------------------- UPLOAD METHODS --------------------------- + +genericSTM32F103C6.menu.upload_method.DFUUploadMethod=STM32duino bootloader +genericSTM32F103C6.menu.upload_method.DFUUploadMethod.upload.protocol=maple_dfu +genericSTM32F103C6.menu.upload_method.DFUUploadMethod.upload.tool=maple_upload +genericSTM32F103C6.menu.upload_method.DFUUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER +genericSTM32F103C6.menu.upload_method.DFUUploadMethod.build.vect=VECT_TAB_ADDR=0x8002000 +genericSTM32F103C6.menu.upload_method.DFUUploadMethod.build.ldscript=ld/bootloader_20_c6.ld +genericSTM32F103C6.menu.upload_method.DFUUploadMethod.upload.usbID=1EAF:0003 +genericSTM32F103C6.menu.upload_method.DFUUploadMethod.upload.altID=2 +genericSTM32F103C6.menu.upload_method.DFUUploadMethod.upload.maximum_size=24576 + +genericSTM32F103C6.menu.upload_method.serialMethod=Serial +genericSTM32F103C6.menu.upload_method.serialMethod.upload.protocol=maple_serial +genericSTM32F103C6.menu.upload_method.serialMethod.upload.tool=serial_upload +genericSTM32F103C6.menu.upload_method.serialMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG + +genericSTM32F103C6.menu.upload_method.STLinkMethod=STLink +genericSTM32F103C6.menu.upload_method.STLinkMethod.upload.protocol=STLink +genericSTM32F103C6.menu.upload_method.STLinkMethod.upload.tool=stlink_upload +genericSTM32F103C6.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DSERIAL_USB -DGENERIC_BOOTLOADER + +genericSTM32F103C6.menu.upload_method.BMPMethod=BMP (Black Magic Probe) +genericSTM32F103C6.menu.upload_method.BMPMethod.upload.protocol=gdb_bmp +genericSTM32F103C6.menu.upload_method.BMPMethod.upload.tool=bmp_upload +genericSTM32F103C6.menu.upload_method.BMPMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG + +genericSTM32F103C6.menu.upload_method.jlinkMethod=JLink +genericSTM32F103C6.menu.upload_method.jlinkMethod.upload.protocol=jlink +genericSTM32F103C6.menu.upload_method.jlinkMethod.upload.tool=jlink_upload +genericSTM32F103C6.menu.upload_method.jlinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DSERIAL_USB -DGENERIC_BOOTLOADER + +#genericSTM32F103C6.menu.upload_method.HIDUploadMethod=HID bootloader 2.0 +#genericSTM32F103C6.menu.upload_method.HIDUploadMethod.upload.tool=hid_upload +#genericSTM32F103C6.menu.upload_method.HIDUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER +#genericSTM32F103C6.menu.upload_method.HIDUploadMethod.build.vect=VECT_TAB_ADDR=0x8001000 +#genericSTM32F103C6.menu.upload_method.HIDUploadMethod.build.ldscript=ld/hid_bootloader_c6.ld + +#-- CPU Clock frequency +genericSTM32F103C6.menu.cpu_speed.speed_72mhz=72Mhz (Normal) +genericSTM32F103C6.menu.cpu_speed.speed_72mhz.build.f_cpu=72000000L + +genericSTM32F103C6.menu.cpu_speed.speed_48mhz=48Mhz (Slow - with USB) +genericSTM32F103C6.menu.cpu_speed.speed_48mhz.build.f_cpu=48000000L + +genericSTM32F103C6.menu.cpu_speed.speed_128mhz=Overclocked 128Mhz NO USB SERIAL. MANUAL RESET NEEDED TO UPLOAD +genericSTM32F103C6.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L + +#-- Optimizations +genericSTM32F103C6.menu.opt.osstd=Smallest (default) +#genericSTM32F103C6.menu.opt.oslto=Smallest Code with LTO +#genericSTM32F103C6.menu.opt.oslto.build.flags.optimize=-Os -flto +#genericSTM32F103C6.menu.opt.oslto.build.flags.ldspecs=-flto +genericSTM32F103C6.menu.opt.o1std=Fast (-O1) +genericSTM32F103C6.menu.opt.o1std.build.flags.optimize=-O1 +genericSTM32F103C6.menu.opt.o1std.build.flags.ldspecs= +#genericSTM32F103C6.menu.opt.o1lto=Fast (-O1) with LTO +#genericSTM32F103C6.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#genericSTM32F103C6.menu.opt.o1lto.build.flags.ldspecs=-flto +genericSTM32F103C6.menu.opt.o2std=Faster (-O2) +genericSTM32F103C6.menu.opt.o2std.build.flags.optimize=-O2 +genericSTM32F103C6.menu.opt.o2std.build.flags.ldspecs= +#genericSTM32F103C6.menu.opt.o2lto=Faster (-O2) with LTO +#genericSTM32F103C6.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#genericSTM32F103C6.menu.opt.o2lto.build.flags.ldspecs=-flto +genericSTM32F103C6.menu.opt.o3std=Fastest (-O3) +genericSTM32F103C6.menu.opt.o3std.build.flags.optimize=-O3 +genericSTM32F103C6.menu.opt.o3std.build.flags.ldspecs= +#genericSTM32F103C6.menu.opt.o3lto=Fastest (-O3) with LTO +#genericSTM32F103C6.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103C6.menu.opt.o3lto.build.flags.ldspecs=-flto +genericSTM32F103C6.menu.opt.ogstd=Debug (-g) +genericSTM32F103C6.menu.opt.ogstd.build.flags.optimize=-Og +genericSTM32F103C6.menu.opt.ogstd.build.flags.ldspecs= + ########################### Generic STM32F103R ########################### genericSTM32F103R.name=Generic STM32F103R series @@ -520,30 +621,28 @@ genericSTM32F103R.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations genericSTM32F103R.menu.opt.osstd=Smallest (default) -genericSTM32F103R.menu.opt.osstd.build.flags.optimize=-Os -genericSTM32F103R.menu.opt.osstd.build.flags.ldspecs= -genericSTM32F103R.menu.opt.oslto=Smallest Code with LTO -genericSTM32F103R.menu.opt.oslto.build.flags.optimize=-Os -flto -genericSTM32F103R.menu.opt.oslto.build.flags.ldspecs=-flto +#genericSTM32F103R.menu.opt.oslto=Smallest Code with LTO +#genericSTM32F103R.menu.opt.oslto.build.flags.optimize=-Os -flto +#genericSTM32F103R.menu.opt.oslto.build.flags.ldspecs=-flto genericSTM32F103R.menu.opt.o1std=Fast (-O1) genericSTM32F103R.menu.opt.o1std.build.flags.optimize=-O1 genericSTM32F103R.menu.opt.o1std.build.flags.ldspecs= -genericSTM32F103R.menu.opt.o1lto=Fast (-O1) with LTO -genericSTM32F103R.menu.opt.o1lto.build.flags.optimize=-O1 -flto -genericSTM32F103R.menu.opt.o1lto.build.flags.ldspecs=-flto +#genericSTM32F103R.menu.opt.o1lto=Fast (-O1) with LTO +#genericSTM32F103R.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#genericSTM32F103R.menu.opt.o1lto.build.flags.ldspecs=-flto genericSTM32F103R.menu.opt.o2std=Faster (-O2) genericSTM32F103R.menu.opt.o2std.build.flags.optimize=-O2 genericSTM32F103R.menu.opt.o2std.build.flags.ldspecs= -genericSTM32F103R.menu.opt.o2lto=Faster (-O2) with LTO -genericSTM32F103R.menu.opt.o2lto.build.flags.optimize=-O2 -flto -genericSTM32F103R.menu.opt.o2lto.build.flags.ldspecs=-flto +#genericSTM32F103R.menu.opt.o2lto=Faster (-O2) with LTO +#genericSTM32F103R.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#genericSTM32F103R.menu.opt.o2lto.build.flags.ldspecs=-flto genericSTM32F103R.menu.opt.o3std=Fastest (-O3) genericSTM32F103R.menu.opt.o3std.build.flags.optimize=-O3 genericSTM32F103R.menu.opt.o3std.build.flags.ldspecs= -genericSTM32F103R.menu.opt.o3lto=Fastest (-O3) with LTO -genericSTM32F103R.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103R.menu.opt.o3lto=Fastest (-O3) with LTO +#genericSTM32F103R.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103R.menu.opt.o3lto.build.flags.ldspecs=-flto genericSTM32F103R.menu.opt.ogstd=Debug (-g) -genericSTM32F103R.menu.opt.o3lto.build.flags.ldspecs=-flto genericSTM32F103R.menu.opt.ogstd.build.flags.optimize=-Og genericSTM32F103R.menu.opt.ogstd.build.flags.ldspecs= @@ -614,30 +713,28 @@ genericSTM32F103T.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations genericSTM32F103T.menu.opt.osstd=Smallest (default) -genericSTM32F103T.menu.opt.osstd.build.flags.optimize=-Os -genericSTM32F103T.menu.opt.osstd.build.flags.ldspecs= -genericSTM32F103T.menu.opt.oslto=Smallest Code with LTO -genericSTM32F103T.menu.opt.oslto.build.flags.optimize=-Os -flto -genericSTM32F103T.menu.opt.oslto.build.flags.ldspecs=-flto +#genericSTM32F103T.menu.opt.oslto=Smallest Code with LTO +#genericSTM32F103T.menu.opt.oslto.build.flags.optimize=-Os -flto +#genericSTM32F103T.menu.opt.oslto.build.flags.ldspecs=-flto genericSTM32F103T.menu.opt.o1std=Fast (-O1) genericSTM32F103T.menu.opt.o1std.build.flags.optimize=-O1 genericSTM32F103T.menu.opt.o1std.build.flags.ldspecs= -genericSTM32F103T.menu.opt.o1lto=Fast (-O1) with LTO -genericSTM32F103T.menu.opt.o1lto.build.flags.optimize=-O1 -flto -genericSTM32F103T.menu.opt.o1lto.build.flags.ldspecs=-flto +#genericSTM32F103T.menu.opt.o1lto=Fast (-O1) with LTO +#genericSTM32F103T.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#genericSTM32F103T.menu.opt.o1lto.build.flags.ldspecs=-flto genericSTM32F103T.menu.opt.o2std=Faster (-O2) genericSTM32F103T.menu.opt.o2std.build.flags.optimize=-O2 genericSTM32F103T.menu.opt.o2std.build.flags.ldspecs= -genericSTM32F103T.menu.opt.o2lto=Faster (-O2) with LTO -genericSTM32F103T.menu.opt.o2lto.build.flags.optimize=-O2 -flto -genericSTM32F103T.menu.opt.o2lto.build.flags.ldspecs=-flto +#genericSTM32F103T.menu.opt.o2lto=Faster (-O2) with LTO +#genericSTM32F103T.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#genericSTM32F103T.menu.opt.o2lto.build.flags.ldspecs=-flto genericSTM32F103T.menu.opt.o3std=Fastest (-O3) genericSTM32F103T.menu.opt.o3std.build.flags.optimize=-O3 genericSTM32F103T.menu.opt.o3std.build.flags.ldspecs= -genericSTM32F103T.menu.opt.o3lto=Fastest (-O3) with LTO -genericSTM32F103T.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103T.menu.opt.o3lto=Fastest (-O3) with LTO +#genericSTM32F103T.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103T.menu.opt.o3lto.build.flags.ldspecs=-flto genericSTM32F103T.menu.opt.ogstd=Debug (-g) -genericSTM32F103T.menu.opt.o3lto.build.flags.ldspecs=-flto genericSTM32F103T.menu.opt.ogstd.build.flags.optimize=-Og genericSTM32F103T.menu.opt.ogstd.build.flags.ldspecs= @@ -646,7 +743,7 @@ genericSTM32F103T.menu.opt.ogstd.build.flags.ldspecs= genericSTM32F103V.name=Generic STM32F103V series genericSTM32F103V.vid.0=0x1EAF genericSTM32F103V.pid.0=0x0004 -genericSTM32F103V.build.variant=generic_stm32f103v +#genericSTM32F103V.build.variant=generic_stm32f103v genericSTM32F103V.build.vect=VECT_TAB_ADDR=0x8000000 genericSTM32F103V.build.core=maple genericSTM32F103V.build.board=GENERIC_STM32F103V @@ -659,19 +756,29 @@ genericSTM32F103V.upload.protocol=maple_dfu genericSTM32F103V.build.error_led_port=GPIOE genericSTM32F103V.build.error_led_pin=6 +genericSTM32F103V.menu.device_variant.STM32F103VB=STM32F103VB +genericSTM32F103V.menu.device_variant.STM32F103VB.build.variant=generic_stm32f103vb +genericSTM32F103V.menu.device_variant.STM32F103VB.build.cpu_flags=-DMCU_STM32F103VB +genericSTM32F103V.menu.device_variant.STM32F103VB.upload.maximum_size=131072 +genericSTM32F103V.menu.device_variant.STM32F103VB.upload.maximum_data_size=20480 +genericSTM32F103V.menu.device_variant.STM32F103VB.build.ldscript=ld/stm32f103vb.ld + genericSTM32F103V.menu.device_variant.STM32F103VC=STM32F103VC +genericSTM32F103V.menu.device_variant.STM32F103VC.build.variant=generic_stm32f103v genericSTM32F103V.menu.device_variant.STM32F103VC.build.cpu_flags=-DMCU_STM32F103VC genericSTM32F103V.menu.device_variant.STM32F103VC.upload.maximum_size=262144 genericSTM32F103V.menu.device_variant.STM32F103VC.upload.maximum_data_size=49152 genericSTM32F103V.menu.device_variant.STM32F103VC.build.ldscript=ld/stm32f103vc.ld genericSTM32F103V.menu.device_variant.STM32F103VD=STM32F103VD +genericSTM32F103V.menu.device_variant.STM32F103VD.build.variant=generic_stm32f103v genericSTM32F103V.menu.device_variant.STM32F103VD.build.cpu_flags=-DMCU_STM32F103VD genericSTM32F103V.menu.device_variant.STM32F103VD.upload.maximum_size=393216 genericSTM32F103V.menu.device_variant.STM32F103VD.upload.maximum_data_size=65536 genericSTM32F103V.menu.device_variant.STM32F103VD.build.ldscript=ld/stm32f103vd.ld genericSTM32F103V.menu.device_variant.STM32F103VE=STM32F103VE +genericSTM32F103V.menu.device_variant.STM32F103VE.build.variant=generic_stm32f103v genericSTM32F103V.menu.device_variant.STM32F103VE.build.cpu_flags=-DMCU_STM32F103VE genericSTM32F103V.menu.device_variant.STM32F103VE.upload.maximum_size=524288 genericSTM32F103V.menu.device_variant.STM32F103VE.upload.maximum_data_size=65536 @@ -715,30 +822,28 @@ genericSTM32F103V.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations genericSTM32F103V.menu.opt.osstd=Smallest (default) -genericSTM32F103V.menu.opt.osstd.build.flags.optimize=-Os -genericSTM32F103V.menu.opt.osstd.build.flags.ldspecs= -genericSTM32F103V.menu.opt.oslto=Smallest Code with LTO -genericSTM32F103V.menu.opt.oslto.build.flags.optimize=-Os -flto -genericSTM32F103V.menu.opt.oslto.build.flags.ldspecs=-flto +#genericSTM32F103V.menu.opt.oslto=Smallest Code with LTO +#genericSTM32F103V.menu.opt.oslto.build.flags.optimize=-Os -flto +#genericSTM32F103V.menu.opt.oslto.build.flags.ldspecs=-flto genericSTM32F103V.menu.opt.o1std=Fast (-O1) genericSTM32F103V.menu.opt.o1std.build.flags.optimize=-O1 genericSTM32F103V.menu.opt.o1std.build.flags.ldspecs= -genericSTM32F103V.menu.opt.o1lto=Fast (-O1) with LTO -genericSTM32F103V.menu.opt.o1lto.build.flags.optimize=-O1 -flto -genericSTM32F103V.menu.opt.o1lto.build.flags.ldspecs=-flto +#genericSTM32F103V.menu.opt.o1lto=Fast (-O1) with LTO +#genericSTM32F103V.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#genericSTM32F103V.menu.opt.o1lto.build.flags.ldspecs=-flto genericSTM32F103V.menu.opt.o2std=Faster (-O2) genericSTM32F103V.menu.opt.o2std.build.flags.optimize=-O2 genericSTM32F103V.menu.opt.o2std.build.flags.ldspecs= -genericSTM32F103V.menu.opt.o2lto=Faster (-O2) with LTO -genericSTM32F103V.menu.opt.o2lto.build.flags.optimize=-O2 -flto -genericSTM32F103V.menu.opt.o2lto.build.flags.ldspecs=-flto +#genericSTM32F103V.menu.opt.o2lto=Faster (-O2) with LTO +#genericSTM32F103V.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#genericSTM32F103V.menu.opt.o2lto.build.flags.ldspecs=-flto genericSTM32F103V.menu.opt.o3std=Fastest (-O3) genericSTM32F103V.menu.opt.o3std.build.flags.optimize=-O3 genericSTM32F103V.menu.opt.o3std.build.flags.ldspecs= -genericSTM32F103V.menu.opt.o3lto=Fastest (-O3) with LTO -genericSTM32F103V.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103V.menu.opt.o3lto=Fastest (-O3) with LTO +#genericSTM32F103V.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103V.menu.opt.o3lto.build.flags.ldspecs=-flto genericSTM32F103V.menu.opt.ogstd=Debug (-g) -genericSTM32F103V.menu.opt.o3lto.build.flags.ldspecs=-flto genericSTM32F103V.menu.opt.ogstd.build.flags.optimize=-Og genericSTM32F103V.menu.opt.ogstd.build.flags.ldspecs= @@ -813,30 +918,28 @@ genericSTM32F103Z.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations genericSTM32F103Z.menu.opt.osstd=Smallest (default) -genericSTM32F103Z.menu.opt.osstd.build.flags.optimize=-Os -genericSTM32F103Z.menu.opt.osstd.build.flags.ldspecs= -genericSTM32F103Z.menu.opt.oslto=Smallest Code with LTO -genericSTM32F103Z.menu.opt.oslto.build.flags.optimize=-Os -flto -genericSTM32F103Z.menu.opt.oslto.build.flags.ldspecs=-flto +#genericSTM32F103Z.menu.opt.oslto=Smallest Code with LTO +#genericSTM32F103Z.menu.opt.oslto.build.flags.optimize=-Os -flto +#genericSTM32F103Z.menu.opt.oslto.build.flags.ldspecs=-flto genericSTM32F103Z.menu.opt.o1std=Fast (-O1) genericSTM32F103Z.menu.opt.o1std.build.flags.optimize=-O1 genericSTM32F103Z.menu.opt.o1std.build.flags.ldspecs= -genericSTM32F103Z.menu.opt.o1lto=Fast (-O1) with LTO -genericSTM32F103Z.menu.opt.o1lto.build.flags.optimize=-O1 -flto -genericSTM32F103Z.menu.opt.o1lto.build.flags.ldspecs=-flto +#genericSTM32F103Z.menu.opt.o1lto=Fast (-O1) with LTO +#genericSTM32F103Z.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#genericSTM32F103Z.menu.opt.o1lto.build.flags.ldspecs=-flto genericSTM32F103Z.menu.opt.o2std=Faster (-O2) genericSTM32F103Z.menu.opt.o2std.build.flags.optimize=-O2 genericSTM32F103Z.menu.opt.o2std.build.flags.ldspecs= -genericSTM32F103Z.menu.opt.o2lto=Faster (-O2) with LTO -genericSTM32F103Z.menu.opt.o2lto.build.flags.optimize=-O2 -flto -genericSTM32F103Z.menu.opt.o2lto.build.flags.ldspecs=-flto +#genericSTM32F103Z.menu.opt.o2lto=Faster (-O2) with LTO +#genericSTM32F103Z.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#genericSTM32F103Z.menu.opt.o2lto.build.flags.ldspecs=-flto genericSTM32F103Z.menu.opt.o3std=Fastest (-O3) genericSTM32F103Z.menu.opt.o3std.build.flags.optimize=-O3 genericSTM32F103Z.menu.opt.o3std.build.flags.ldspecs= -genericSTM32F103Z.menu.opt.o3lto=Fastest (-O3) with LTO -genericSTM32F103Z.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103Z.menu.opt.o3lto=Fastest (-O3) with LTO +#genericSTM32F103Z.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#genericSTM32F103Z.menu.opt.o3lto.build.flags.ldspecs=-flto genericSTM32F103Z.menu.opt.ogstd=Debug (-g) -genericSTM32F103Z.menu.opt.o3lto.build.flags.ldspecs=-flto genericSTM32F103Z.menu.opt.ogstd.build.flags.optimize=-Og genericSTM32F103Z.menu.opt.ogstd.build.flags.ldspecs= @@ -903,30 +1006,28 @@ hytiny-stm32f103t.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations hytiny-stm32f103t.menu.opt.osstd=Smallest (default) -hytiny-stm32f103t.menu.opt.osstd.build.flags.optimize=-Os -hytiny-stm32f103t.menu.opt.osstd.build.flags.ldspecs= -hytiny-stm32f103t.menu.opt.oslto=Smallest Code with LTO -hytiny-stm32f103t.menu.opt.oslto.build.flags.optimize=-Os -flto -hytiny-stm32f103t.menu.opt.oslto.build.flags.ldspecs=-flto +#hytiny-stm32f103t.menu.opt.oslto=Smallest Code with LTO +#hytiny-stm32f103t.menu.opt.oslto.build.flags.optimize=-Os -flto +#hytiny-stm32f103t.menu.opt.oslto.build.flags.ldspecs=-flto hytiny-stm32f103t.menu.opt.o1std=Fast (-O1) hytiny-stm32f103t.menu.opt.o1std.build.flags.optimize=-O1 hytiny-stm32f103t.menu.opt.o1std.build.flags.ldspecs= -hytiny-stm32f103t.menu.opt.o1lto=Fast (-O1) with LTO -hytiny-stm32f103t.menu.opt.o1lto.build.flags.optimize=-O1 -flto -hytiny-stm32f103t.menu.opt.o1lto.build.flags.ldspecs=-flto +#hytiny-stm32f103t.menu.opt.o1lto=Fast (-O1) with LTO +#hytiny-stm32f103t.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#hytiny-stm32f103t.menu.opt.o1lto.build.flags.ldspecs=-flto hytiny-stm32f103t.menu.opt.o2std=Faster (-O2) hytiny-stm32f103t.menu.opt.o2std.build.flags.optimize=-O2 hytiny-stm32f103t.menu.opt.o2std.build.flags.ldspecs= -hytiny-stm32f103t.menu.opt.o2lto=Faster (-O2) with LTO -hytiny-stm32f103t.menu.opt.o2lto.build.flags.optimize=-O2 -flto -hytiny-stm32f103t.menu.opt.o2lto.build.flags.ldspecs=-flto +#hytiny-stm32f103t.menu.opt.o2lto=Faster (-O2) with LTO +#hytiny-stm32f103t.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#hytiny-stm32f103t.menu.opt.o2lto.build.flags.ldspecs=-flto hytiny-stm32f103t.menu.opt.o3std=Fastest (-O3) hytiny-stm32f103t.menu.opt.o3std.build.flags.optimize=-O3 hytiny-stm32f103t.menu.opt.o3std.build.flags.ldspecs= -hytiny-stm32f103t.menu.opt.o3lto=Fastest (-O3) with LTO -hytiny-stm32f103t.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#hytiny-stm32f103t.menu.opt.o3lto=Fastest (-O3) with LTO +#hytiny-stm32f103t.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#hytiny-stm32f103t.menu.opt.o3lto.build.flags.ldspecs=-flto hytiny-stm32f103t.menu.opt.ogstd=Debug (-g) -hytiny-stm32f103t.menu.opt.o3lto.build.flags.ldspecs=-flto hytiny-stm32f103t.menu.opt.ogstd.build.flags.optimize=-Og hytiny-stm32f103t.menu.opt.ogstd.build.flags.ldspecs= @@ -970,30 +1071,28 @@ STM32VLD.menu.cpu_speed.speed_128mhz.build.f_cpu=128000000L #-- Optimizations STM32VLD.menu.opt.osstd=Smallest (default) -STM32VLD.menu.opt.osstd.build.flags.optimize=-Os -STM32VLD.menu.opt.osstd.build.flags.ldspecs= -STM32VLD.menu.opt.oslto=Smallest Code with LTO -STM32VLD.menu.opt.oslto.build.flags.optimize=-Os -flto -STM32VLD.menu.opt.oslto.build.flags.ldspecs=-flto +#STM32VLD.menu.opt.oslto=Smallest Code with LTO +#STM32VLD.menu.opt.oslto.build.flags.optimize=-Os -flto +#STM32VLD.menu.opt.oslto.build.flags.ldspecs=-flto STM32VLD.menu.opt.o1std=Fast (-O1) STM32VLD.menu.opt.o1std.build.flags.optimize=-O1 STM32VLD.menu.opt.o1std.build.flags.ldspecs= -STM32VLD.menu.opt.o1lto=Fast (-O1) with LTO -STM32VLD.menu.opt.o1lto.build.flags.optimize=-O1 -flto -STM32VLD.menu.opt.o1lto.build.flags.ldspecs=-flto +#STM32VLD.menu.opt.o1lto=Fast (-O1) with LTO +#STM32VLD.menu.opt.o1lto.build.flags.optimize=-O1 -flto +#STM32VLD.menu.opt.o1lto.build.flags.ldspecs=-flto STM32VLD.menu.opt.o2std=Faster (-O2) STM32VLD.menu.opt.o2std.build.flags.optimize=-O2 STM32VLD.menu.opt.o2std.build.flags.ldspecs= -STM32VLD.menu.opt.o2lto=Faster (-O2) with LTO -STM32VLD.menu.opt.o2lto.build.flags.optimize=-O2 -flto -STM32VLD.menu.opt.o2lto.build.flags.ldspecs=-flto +#STM32VLD.menu.opt.o2lto=Faster (-O2) with LTO +#STM32VLD.menu.opt.o2lto.build.flags.optimize=-O2 -flto +#STM32VLD.menu.opt.o2lto.build.flags.ldspecs=-flto STM32VLD.menu.opt.o3std=Fastest (-O3) STM32VLD.menu.opt.o3std.build.flags.optimize=-O3 STM32VLD.menu.opt.o3std.build.flags.ldspecs= -STM32VLD.menu.opt.o3lto=Fastest (-O3) with LTO -STM32VLD.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#STM32VLD.menu.opt.o3lto=Fastest (-O3) with LTO +#STM32VLD.menu.opt.o3lto.build.flags.optimize=-O3 -flto +#STM32VLD.menu.opt.o3lto.build.flags.ldspecs=-flto STM32VLD.menu.opt.ogstd=Debug (-g) -STM32VLD.menu.opt.o3lto.build.flags.ldspecs=-flto STM32VLD.menu.opt.ogstd.build.flags.optimize=-Og STM32VLD.menu.opt.ogstd.build.flags.ldspecs= diff --git a/STM32F1/cores/maple/HardwareSerial.cpp b/STM32F1/cores/maple/HardwareSerial.cpp index 024efbc7d..89ccc97c6 100644 --- a/STM32F1/cores/maple/HardwareSerial.cpp +++ b/STM32F1/cores/maple/HardwareSerial.cpp @@ -37,59 +37,6 @@ #include #include -#if 0 - - #define DEFINE_HWSERIAL(name, n) \ - HardwareSerial name(USART##n, \ - BOARD_USART##n##_TX_PIN, \ - BOARD_USART##n##_RX_PIN) - - #define DEFINE_HWSERIAL_UART(name, n) \ - HardwareSerial name(UART##n, \ - BOARD_USART##n##_TX_PIN, \ - BOARD_USART##n##_RX_PIN) - - #ifdef SERIAL_USB - #if BOARD_HAVE_USART1 - DEFINE_HWSERIAL(Serial1, 1); - #endif - #if BOARD_HAVE_USART2 - DEFINE_HWSERIAL(Serial2, 2); - #endif - #if BOARD_HAVE_USART3 - DEFINE_HWSERIAL(Serial3, 3); - #endif - #if BOARD_HAVE_UART4 - DEFINE_HWSERIAL_UART(Serial4, 4); - #endif - #if BOARD_HAVE_UART5 - DEFINE_HWSERIAL_UART(Serial5, 5); - #endif - #if BOARD_HAVE_USART6 - DEFINE_HWSERIAL_UART(Serial6, 6); - #endif - #else - #if BOARD_HAVE_USART1 - DEFINE_HWSERIAL(Serial, 1); - #endif - #if BOARD_HAVE_USART2 - DEFINE_HWSERIAL(Serial1, 2); - #endif - #if BOARD_HAVE_USART3 - DEFINE_HWSERIAL(Serial2, 3); - #endif - #if BOARD_HAVE_UART4 - DEFINE_HWSERIAL_UART(Serial3, 4); - #endif - #if BOARD_HAVE_UART5 - DEFINE_HWSERIAL_UART(Serial4, 5); - #endif - #if BOARD_HAVE_USART6 - DEFINE_HWSERIAL_UART(Serial5, 6); - #endif - #endif - -#endif HardwareSerial::HardwareSerial(usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin) { @@ -179,12 +126,7 @@ int HardwareSerial::peek(void) int HardwareSerial::availableForWrite(void) { -/* Roger Clark. - * Currently there isn't an output ring buffer, chars are sent straight to the hardware. - * so just return 1, meaning that 1 char can be written - * This will be slower than a ring buffer implementation, but it should at least work ! - */ - return 1; + return this->usart_device->wb->size-rb_full_count(this->usart_device->wb); } size_t HardwareSerial::write(unsigned char ch) { diff --git a/STM32F1/cores/maple/HardwareSerial.h b/STM32F1/cores/maple/HardwareSerial.h index b8b8dd6fd..620e14cf2 100644 --- a/STM32F1/cores/maple/HardwareSerial.h +++ b/STM32F1/cores/maple/HardwareSerial.h @@ -181,44 +181,27 @@ class HardwareSerial : public Stream { #endif }; -#ifdef SERIAL_USB - #if BOARD_HAVE_USART1 - extern HardwareSerial Serial1; - #endif - #if BOARD_HAVE_USART2 - extern HardwareSerial Serial2; - #endif - #if BOARD_HAVE_USART3 - extern HardwareSerial Serial3; - #endif - #if BOARD_HAVE_UART4 - extern HardwareSerial Serial4; - #endif - #if BOARD_HAVE_UART5 - extern HardwareSerial Serial5; - #endif - #if BOARD_HAVE_USART6 - extern HardwareSerial Serial6; - #endif -#else - #if BOARD_HAVE_USART1 - extern HardwareSerial Serial; - #endif - #if BOARD_HAVE_USART2 - extern HardwareSerial Serial1; - #endif - #if BOARD_HAVE_USART3 - extern HardwareSerial Serial2; - #endif - #if BOARD_HAVE_UART4 - extern HardwareSerial Serial3; - #endif - #if BOARD_HAVE_UART5 - extern HardwareSerial Serial4; - #endif - #if BOARD_HAVE_USART6 - extern HardwareSerial Serial5; - #endif +#ifndef SERIAL_USB +#define Serial Serial1 #endif +#if BOARD_HAVE_USART1 +extern HardwareSerial Serial1; +#endif +#if BOARD_HAVE_USART2 +extern HardwareSerial Serial2; +#endif +#if BOARD_HAVE_USART3 +extern HardwareSerial Serial3; +#endif +#if BOARD_HAVE_UART4 +extern HardwareSerial Serial4; #endif +#if BOARD_HAVE_UART5 +extern HardwareSerial Serial5; +#endif +#if BOARD_HAVE_USART6 +extern HardwareSerial Serial6; +#endif + +#endif //_WIRISH_HARDWARESERIAL_H_ diff --git a/STM32F1/cores/maple/HardwareTimer.cpp b/STM32F1/cores/maple/HardwareTimer.cpp index abf1e623f..dd96d0512 100644 --- a/STM32F1/cores/maple/HardwareTimer.cpp +++ b/STM32F1/cores/maple/HardwareTimer.cpp @@ -30,6 +30,7 @@ #include "ext_interrupts.h" // for noInterrupts(), interrupts() #include "wirish_math.h" #include // for CYCLES_PER_MICROSECOND +#include // TODO [0.1.0] Remove deprecated pieces @@ -138,7 +139,6 @@ void HardwareTimer::detachInterrupt(int channel) { timer_detach_interrupt(this->dev, (uint8)channel); } - void HardwareTimer::enableDMA(int channel) { timer_dma_enable_req(this->dev, (uint8)channel); } @@ -156,28 +156,7 @@ void HardwareTimer::setMasterModeTrGo(uint32_t mode) { this->dev->regs.bas->CR2 |= mode; } -/* CARLOS Changes to add encoder mode.*/ - -//direction of movement. (to be better described). - uint8 HardwareTimer::getDirection(){ - return get_direction(this->dev); - } - -//set if the encoder will count edges on one, which or both channels. - void HardwareTimer::setEdgeCounting(uint32 counting) { - (dev->regs).gen->SMCR = counting;//TIMER_SMCR_SMS_ENCODER3; //choose encoder 3, counting on - - } - uint8 HardwareTimer::getEdgeCounting() { - return (dev->regs).gen->SMCR; - } - - - -//set the polarity of counting... not sure how interesting this is.. - void HardwareTimer::setPolarity(){} - /* -- Deprecated predefined instances -------------------------------------- */ HardwareTimer Timer1(1); diff --git a/STM32F1/cores/maple/HardwareTimer.h b/STM32F1/cores/maple/HardwareTimer.h index bb40dba0f..3be152ae5 100644 --- a/STM32F1/cores/maple/HardwareTimer.h +++ b/STM32F1/cores/maple/HardwareTimer.h @@ -56,6 +56,7 @@ class HardwareTimer { */ HardwareTimer(uint8 timerNum); + void init(void) { timer_init(this->dev); timer_pause(this->dev); } /** * @brief Stop the counter, without affecting its configuration. * @@ -227,32 +228,53 @@ class HardwareTimer { * TIMER_CR2_MMS_COMPARE_OC4REF */ void setMasterModeTrGo(uint32_t mode); - + + void setSlaveFlags(uint32 flags) { + ((this->dev)->regs).gen->SMCR = flags; + } + //CARLOS. /* added these functions to make sense for the encoder mode. */ //direction of movement. (to be better described). - uint8 getDirection(); - + uint8 getDirection() { + return get_direction(this->dev); + } + //set if the encoder will count edges on one, which or both channels. - void setEdgeCounting(uint32 counting); - uint8 getEdgeCounting(); //not sure if needed. + void setEdgeCounting(uint32 counting) { + setSlaveFlags(counting); + } //set the polarity of counting... not sure how interesting this is.. - void setPolarity(); - + void setPolarity(uint8 channel, uint8 pol) { + timer_cc_set_pol(this->dev, channel, pol); + } + + void setInputCaptureMode(uint8 channel, timer_ic_input_select input) { + input_capture_mode(this->dev, channel, input); + } + + uint8_t getInputCaptureFlag(uint8 channel) { + return ( timer_get_status(this->dev) >> channel ) & 0x1; + } + + uint8_t getInputCaptureFlagOverflow(uint8 channel) { + uint8 ret = ( timer_get_status(this->dev) >> (8+channel) ) & 0x1; + if ( ret ) timer_reset_status_bit(this->dev, (8+channel)); // clear flag + return ret; + } + //add the filtering definition for the input channel. - /* Escape hatch */ - - /** + /** * @brief Enable/disable DMA request for the input channel. */ - void enableDMA(int channel); - void disableDMA(int channel); - + void enableDMA(int channel); + void disableDMA(int channel); + /** * @brief Get a pointer to the underlying libmaple timer_dev for * this HardwareTimer instance. diff --git a/STM32F1/cores/maple/Print.cpp b/STM32F1/cores/maple/Print.cpp index 0a71cf018..a8aa07d69 100644 --- a/STM32F1/cores/maple/Print.cpp +++ b/STM32F1/cores/maple/Print.cpp @@ -47,12 +47,8 @@ */ size_t Print::write(const char *str) { - size_t n = 0; - while (*str) { - write(*str++); - n++; - } - return n; + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); } size_t Print::write(const void *buffer, uint32 size) { diff --git a/STM32F1/cores/maple/Stream.cpp b/STM32F1/cores/maple/Stream.cpp index 991fa87d9..c682daeef 100644 --- a/STM32F1/cores/maple/Stream.cpp +++ b/STM32F1/cores/maple/Stream.cpp @@ -177,7 +177,7 @@ float Stream::parseFloat(char skipChar){ boolean isFraction = false; long value = 0; int c; - float fraction = 1.0; + float fraction = 1.0f; c = peekNextDigit(); // ignore non numeric leading characters @@ -194,7 +194,7 @@ float Stream::parseFloat(char skipChar){ else if(c >= '0' && c <= '9') { // is c a digit? value = value * 10 + c - '0'; if(isFraction) - fraction *= 0.1; + fraction *= 0.1f; } read(); // consume the character we got with peek c = timedPeek(); diff --git a/STM32F1/cores/maple/avr/dtostrf.c b/STM32F1/cores/maple/avr/dtostrf.c index 7f90154fb..b53834532 100644 --- a/STM32F1/cores/maple/avr/dtostrf.c +++ b/STM32F1/cores/maple/avr/dtostrf.c @@ -1,7 +1,7 @@ /* dtostrf - Emulation for dtostrf function from avr-libc Copyright (c) 2013 Arduino. All rights reserved. - Written by Cristian Maglie + Written by Cristian Maglie This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -19,11 +19,76 @@ */ #include +#include +#include -char *dtostrf (double val, signed char width, unsigned char prec, char *sout) { - char fmt[20]; +char *dtostrf(double val, signed char width, unsigned char prec, char *sout) +{ + //Commented code is the original version + /*char fmt[20]; sprintf(fmt, "%%%d.%df", width, prec); sprintf(sout, fmt, val); + return sout;*/ + + // Handle negative numbers + unsigned char negative = 0; + if (val < 0.0) { + negative = 1; + val = -val; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (int i = 0; i < prec; ++i) { + rounding /= 10.0; + } + + val += rounding; + + // Extract the integer part of the number + unsigned long int_part = (unsigned long)val; + double remainder = val - (double)int_part; + + // Extract digits from the remainder + unsigned long dec_part = 0; + double decade = 1.0; + for (int i = 0; i < prec; i++) { + decade *= 10.0; + } + remainder *= decade; + dec_part = (int)remainder; + + if (negative) { + sprintf(sout, "-%ld.%0*ld", int_part, prec, dec_part); + } else { + sprintf(sout, "%ld.%0*ld", int_part, prec, dec_part); + } + // Handle minimum field width of the output string + // width is signed value, negative for left adjustment. + // Range -128,127 + char fmt[129] = ""; + unsigned int w = width; + if (width < 0) { + negative = 1; + w = -width; + } else { + negative = 0; + } + + if (strlen(sout) < w) { + memset(fmt, ' ', 128); + fmt[w - strlen(sout)] = '\0'; + if (negative == 0) { + char *tmp = malloc(strlen(sout) + 1); + strcpy(tmp, sout); + strcpy(sout, fmt); + strcat(sout, tmp); + free(tmp); + } else { + // left adjustment + strcat(sout, fmt); + } + } + return sout; } - diff --git a/STM32F1/cores/maple/avr/pgmspace.h b/STM32F1/cores/maple/avr/pgmspace.h index 9b344c9b8..97d060628 100644 --- a/STM32F1/cores/maple/avr/pgmspace.h +++ b/STM32F1/cores/maple/avr/pgmspace.h @@ -21,16 +21,22 @@ typedef uint32_t prog_uint32_t; #define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) #define strcpy_P(dest, src) strcpy((dest), (src)) +#define strncpy_P(dest, src, size) strncpy((dest), (src), (size)) #define strcat_P(dest, src) strcat((dest), (src)) +#define strchr_P(s, c) strchr((s), (c)) #define strcmp_P(a, b) strcmp((a), (b)) +#define strncmp_P(a, b, c) strncmp((a), (b), (c)) #define strstr_P(a, b) strstr((a), (b)) #define strlen_P(a) strlen((a)) #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) +#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) +#define strcasecmp_P(a, b) strcasecmp((a), (b)) #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr)) +#define pgm_read_ptr(addr) (*(const void **)(addr)) #define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_word_near(addr) pgm_read_word(addr) @@ -40,5 +46,6 @@ typedef uint32_t prog_uint32_t; #define pgm_read_word_far(addr) pgm_read_word(addr) #define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_float_far(addr) pgm_read_float(addr) +#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) #endif diff --git a/STM32F1/cores/maple/boards.h b/STM32F1/cores/maple/boards.h index 518f9a025..568e675b4 100644 --- a/STM32F1/cores/maple/boards.h +++ b/STM32F1/cores/maple/boards.h @@ -125,6 +125,8 @@ bool boardUsesPin(uint8 pin); #define BOARD_BUTTON_PRESSED_LEVEL HIGH #endif +#include "series/usart.h" + /** * @brief Does the board break out a USART/UART's RX and TX pins? * diff --git a/STM32F1/cores/maple/cxxabi-compat.cpp b/STM32F1/cores/maple/cxxabi-compat.cpp index 516b112ac..39905d176 100644 --- a/STM32F1/cores/maple/cxxabi-compat.cpp +++ b/STM32F1/cores/maple/cxxabi-compat.cpp @@ -1,6 +1,20 @@ +#include +#include + /* We compile with nodefaultlibs, so we need to provide an error * handler for an empty pure virtual function */ extern "C" void __cxa_pure_virtual(void) { while(1) ; } + +/* We need to override it in order to avoid bloat binaries + * due to using demangling of symbols in backtraces */ +extern "C" char * __cxa_demangle (const char *mangled_name, + char *output_buffer, + size_t *length, + int *status) { + (void)length; (void)status; + strcpy((char*)mangled_name, output_buffer); + return output_buffer; +} diff --git a/STM32F1/cores/maple/ext_interrupts.h b/STM32F1/cores/maple/ext_interrupts.h index a406868e0..45e70bafa 100644 --- a/STM32F1/cores/maple/ext_interrupts.h +++ b/STM32F1/cores/maple/ext_interrupts.h @@ -106,7 +106,7 @@ void detachInterrupt(uint8 pin); * * @see noInterrupts() */ -static inline __always_inline void interrupts() { +inline void interrupts() { nvic_globalirq_enable(); } @@ -120,7 +120,7 @@ static inline __always_inline void interrupts() { * * @see interrupts() */ -static inline __always_inline void noInterrupts() { +inline void noInterrupts() { nvic_globalirq_disable(); } diff --git a/STM32F1/cores/maple/libmaple/adc_f1.c b/STM32F1/cores/maple/libmaple/adc_f1.c index 5305b02af..a8ea30b52 100644 --- a/STM32F1/cores/maple/libmaple/adc_f1.c +++ b/STM32F1/cores/maple/libmaple/adc_f1.c @@ -72,7 +72,7 @@ adc_dev *ADC3 = &adc3; adc irq routine. Added by bubulindo. */ -void __irq_adc() { +__weak void __irq_adc() { //get status uint32 adc_sr = ADC1->regs->SR; //End Of Conversion @@ -107,7 +107,7 @@ void __irq_adc() { added by bubulindo */ #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) -void __irq_adc3() { +__weak void __irq_adc3() { //get status uint32 adc_sr = ADC3->regs->SR; //End Of Conversion @@ -175,8 +175,8 @@ void adc_attach_interrupt(adc_dev *dev, * @param dev adc device */ void adc_calibrate(adc_dev *dev) { - __io uint32 *rstcal_bit = bb_perip(&(dev->regs->CR2), 3); - __io uint32 *cal_bit = bb_perip(&(dev->regs->CR2), 2); + __IO uint32 *rstcal_bit = bb_perip(&(dev->regs->CR2), 3); + __IO uint32 *cal_bit = bb_perip(&(dev->regs->CR2), 2); *rstcal_bit = 1; while (*rstcal_bit) diff --git a/STM32F1/cores/maple/libmaple/bkp_f1.c b/STM32F1/cores/maple/libmaple/bkp_f1.c index 01ad419ab..741f5eb90 100644 --- a/STM32F1/cores/maple/libmaple/bkp_f1.c +++ b/STM32F1/cores/maple/libmaple/bkp_f1.c @@ -34,7 +34,7 @@ #include #include -static inline __io uint32* data_register(uint8 reg); +static inline __IO uint32* data_register(uint8 reg); bkp_dev bkp = { .regs = BKP_BASE, @@ -78,7 +78,7 @@ void bkp_disable_writes(void) { * medium-density devices, 42 on high-density devices). */ uint16 bkp_read(uint8 reg) { - __io uint32* dr = data_register(reg); + __IO uint32* dr = data_register(reg); if (!dr) { ASSERT(0); /* nonexistent register */ return 0; @@ -97,7 +97,7 @@ uint16 bkp_read(uint8 reg) { * @see bkp_enable_writes() */ void bkp_write(uint8 reg, uint16 val) { - __io uint32* dr = data_register(reg); + __IO uint32* dr = data_register(reg); if (!dr) { ASSERT(0); /* nonexistent register */ return; @@ -112,7 +112,7 @@ void bkp_write(uint8 reg, uint16 val) { */ #define NR_LOW_DRS 10 -static inline __io uint32* data_register(uint8 reg) { +static inline __IO uint32* data_register(uint8 reg) { if (reg < 1 || reg > BKP_NR_DATA_REGS) { return 0; } diff --git a/STM32F1/cores/maple/libmaple/dma.c b/STM32F1/cores/maple/libmaple/dma.c index d13de1081..1dc875e3b 100644 --- a/STM32F1/cores/maple/libmaple/dma.c +++ b/STM32F1/cores/maple/libmaple/dma.c @@ -52,7 +52,7 @@ void dma_init(dma_dev *dev) { * Private API */ -enum dma_atype _dma_addr_type(__io void *addr) { +enum dma_atype _dma_addr_type(__IO void *addr) { switch (stm32_block_purpose((void*)addr)) { /* Notice we're treating the code block as memory here. That's * correct for addresses in Flash and in [0x0, 0x7FFFFFF] diff --git a/STM32F1/cores/maple/libmaple/dma_f1.c b/STM32F1/cores/maple/libmaple/dma_f1.c index c7c3c0072..861f1d176 100644 --- a/STM32F1/cores/maple/libmaple/dma_f1.c +++ b/STM32F1/cores/maple/libmaple/dma_f1.c @@ -86,7 +86,7 @@ static int cfg_dev_ok(dma_dev *dev, dma_tube_config *cfg) { } /* Is addr acceptable for use as DMA src/dst? */ -static int cfg_mem_ok(__io void *addr) { +static int cfg_mem_ok(__IO void *addr) { enum dma_atype atype = _dma_addr_type(addr); return atype == DMA_ATYPE_MEM || atype == DMA_ATYPE_PER; } @@ -236,15 +236,25 @@ void dma_set_num_transfers(dma_dev *dev, channel_regs = dma_channel_regs(dev, channel); channel_regs->CNDTR = num_transfers; } - +// stevstrong: handle DMA2 ch 4 and 5 IRQ enable/disable - they share common IRQ line +uint32 dma2Ch4_5 = 0; void dma_attach_interrupt(dma_dev *dev, dma_channel channel, void (*handler)(void)) { DMA_GET_HANDLER(dev, channel) = handler; nvic_irq_enable(dev->handlers[channel - 1].irq_line); + // stevstrong: mark ch 4 or 5 IRQ set if DMA2 + if (dev->handlers[channel - 1].irq_line==NVIC_DMA2_CH_4_5) + dma2Ch4_5 |= BIT(channel-1); } void dma_detach_interrupt(dma_dev *dev, dma_channel channel) { - /* Don't use nvic_irq_disable()! Think about DMA2 channels 4 and 5. */ + // stevstrong: disable IRQ for DMA2 only if none of ch 4 or 5 is set + if (dev->handlers[channel - 1].irq_line==NVIC_DMA2_CH_4_5) { + dma2Ch4_5 &= BIT(channel-1); + if (dma2Ch4_5==0) + nvic_irq_disable(dev->handlers[channel - 1].irq_line); + } else + nvic_irq_disable(dev->handlers[channel - 1].irq_line); dma_channel_regs(dev, channel)->CCR &= ~0xF; DMA_GET_HANDLER(dev, channel) = NULL; } @@ -293,7 +303,7 @@ dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) { return DMA_TRANSFER_ERROR; } -void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *addr) { +void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __IO void *addr) { dma_channel_reg_map *chan_regs; ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); @@ -302,7 +312,7 @@ void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *addr) { chan_regs->CMAR = (uint32)addr; } -void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *addr) { +void dma_set_per_addr(dma_dev *dev, dma_channel channel, __IO void *addr) { dma_channel_reg_map *chan_regs; ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); @@ -343,9 +353,9 @@ void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *addr) { */ void dma_setup_transfer(dma_dev *dev, dma_channel channel, - __io void *peripheral_address, + __IO void *peripheral_address, dma_xfer_size peripheral_size, - __io void *memory_address, + __IO void *memory_address, dma_xfer_size memory_size, uint32 mode) { dma_channel_reg_map *channel_regs = dma_channel_regs(dev, channel); @@ -360,48 +370,48 @@ void dma_setup_transfer(dma_dev *dev, * IRQ handlers */ -void __irq_dma1_channel1(void) { +__weak void __irq_dma1_channel1(void) { dma_irq_handler(DMA1, DMA_CH1); } -void __irq_dma1_channel2(void) { +__weak void __irq_dma1_channel2(void) { dma_irq_handler(DMA1, DMA_CH2); } -void __irq_dma1_channel3(void) { +__weak void __irq_dma1_channel3(void) { dma_irq_handler(DMA1, DMA_CH3); } -void __irq_dma1_channel4(void) { +__weak void __irq_dma1_channel4(void) { dma_irq_handler(DMA1, DMA_CH4); } -void __irq_dma1_channel5(void) { +__weak void __irq_dma1_channel5(void) { dma_irq_handler(DMA1, DMA_CH5); } -void __irq_dma1_channel6(void) { +__weak void __irq_dma1_channel6(void) { dma_irq_handler(DMA1, DMA_CH6); } -void __irq_dma1_channel7(void) { +__weak void __irq_dma1_channel7(void) { dma_irq_handler(DMA1, DMA_CH7); } #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) -void __irq_dma2_channel1(void) { +__weak void __irq_dma2_channel1(void) { dma_irq_handler(DMA2, DMA_CH1); } -void __irq_dma2_channel2(void) { +__weak void __irq_dma2_channel2(void) { dma_irq_handler(DMA2, DMA_CH2); } -void __irq_dma2_channel3(void) { +__weak void __irq_dma2_channel3(void) { dma_irq_handler(DMA2, DMA_CH3); } -void __irq_dma2_channel4_5(void) { +__weak void __irq_dma2_channel4_5(void) { if ((DMA2_BASE->CCR4 & DMA_CCR_EN) && (DMA2_BASE->ISR & DMA_ISR_GIF4)) { dma_irq_handler(DMA2, DMA_CH4); } diff --git a/STM32F1/cores/maple/libmaple/exc.S b/STM32F1/cores/maple/libmaple/exc.S index 7631e4885..24153fc51 100644 --- a/STM32F1/cores/maple/libmaple/exc.S +++ b/STM32F1/cores/maple/libmaple/exc.S @@ -41,7 +41,6 @@ # SP--> r0 .text -.globl __exc_hardfault .globl __exc_nmi .globl __exc_hardfault .globl __exc_memmanage diff --git a/STM32F1/cores/maple/libmaple/exti.c b/STM32F1/cores/maple/libmaple/exti.c index 402bec655..0babc2acc 100644 --- a/STM32F1/cores/maple/libmaple/exti.c +++ b/STM32F1/cores/maple/libmaple/exti.c @@ -35,8 +35,6 @@ #include #include -static inline void dispatch_single_exti(uint32 exti_num); -static inline void dispatch_extis(uint32 start, uint32 stop); /* * Internal state @@ -47,7 +45,7 @@ typedef struct exti_channel { void *arg; } exti_channel; -static exti_channel exti_channels[] = { +exti_channel exti_channels[] = { { .handler = NULL, .arg = NULL }, // EXTI0 { .handler = NULL, .arg = NULL }, // EXTI1 { .handler = NULL, .arg = NULL }, // EXTI2 @@ -200,7 +198,7 @@ void exti_detach_interrupt(exti_num num) { * Private routines */ -void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port) { +void exti_do_select(__IO uint32 *exti_cr, exti_num num, exti_cfg port) { uint32 shift = 4 * (num % 4); uint32 cr = *exti_cr; cr &= ~(0xF << shift); @@ -208,57 +206,9 @@ void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port) { *exti_cr = cr; } -/* - * Interrupt handlers - */ - -void __irq_exti0(void) { - dispatch_single_exti(EXTI0); -} - -void __irq_exti1(void) { - dispatch_single_exti(EXTI1); -} - -void __irq_exti2(void) { - dispatch_single_exti(EXTI2); -} - -void __irq_exti3(void) { - dispatch_single_exti(EXTI3); -} - -void __irq_exti4(void) { - dispatch_single_exti(EXTI4); -} - -void __irq_exti9_5(void) { - dispatch_extis(5, 9); -} - -void __irq_exti15_10(void) { - dispatch_extis(10, 15); -} - -/* - * Auxiliary functions - */ - -/* Clear the pending bits for EXTIs whose bits are set in exti_msk. - * - * If a pending bit is cleared as the last instruction in an ISR, it - * won't actually be cleared in time and the ISR will fire again. To - * compensate, this function NOPs for 2 cycles after clearing the - * pending bits to ensure it takes effect. */ -static inline __always_inline void clear_pending_msk(uint32 exti_msk) { - EXTI_BASE->PR = exti_msk; - asm volatile("nop"); - asm volatile("nop"); -} - /* This dispatch routine is for non-multiplexed EXTI lines only; i.e., * it doesn't check EXTI_PR. */ -static inline __always_inline void dispatch_single_exti(uint32 exti) { +void dispatch_single_exti(uint32 exti) { voidArgumentFuncPtr handler = exti_channels[exti].handler; if (!handler) { @@ -266,11 +216,13 @@ static inline __always_inline void dispatch_single_exti(uint32 exti) { } handler(exti_channels[exti].arg); - clear_pending_msk(1U << exti); + EXTI_BASE->PR = (1U << exti); + asm volatile("nop"); + asm volatile("nop"); } /* Dispatch routine for EXTIs which share an IRQ. */ -static inline __always_inline void dispatch_extis(uint32 start, uint32 stop) { +void dispatch_extis(uint32 start, uint32 stop) { uint32 pr = EXTI_BASE->PR; uint32 handled_msk = 0; uint32 exti; @@ -288,5 +240,45 @@ static inline __always_inline void dispatch_extis(uint32 start, uint32 stop) { } /* Clear the pending bits for handled EXTIs. */ - clear_pending_msk(handled_msk); + EXTI_BASE->PR = (handled_msk); + asm volatile("nop"); + asm volatile("nop"); +} + + +/* + * Interrupt handlers + */ + +__weak void __irq_exti0(void) { + dispatch_single_exti(EXTI0); +} + +__weak void __irq_exti1(void) { + dispatch_single_exti(EXTI1); +} + +__weak void __irq_exti2(void) { + dispatch_single_exti(EXTI2); } + +__weak void __irq_exti3(void) { + dispatch_single_exti(EXTI3); +} + +__weak void __irq_exti4(void) { + dispatch_single_exti(EXTI4); +} + +__weak void __irq_exti9_5(void) { + dispatch_extis(5, 9); +} + +__weak void __irq_exti15_10(void) { + dispatch_extis(10, 15); +} + +/* + * Auxiliary functions + */ + diff --git a/STM32F1/cores/maple/libmaple/gpio_f1.c b/STM32F1/cores/maple/libmaple/gpio_f1.c index 6de16f55a..2a5f37a63 100644 --- a/STM32F1/cores/maple/libmaple/gpio_f1.c +++ b/STM32F1/cores/maple/libmaple/gpio_f1.c @@ -68,7 +68,7 @@ gpio_dev gpiod = { /** GPIO port D device. */ gpio_dev* const GPIOD = &gpiod; -#ifdef STM32_HIGH_DENSITY +#if STM32_NR_GPIO_PORTS > 4 gpio_dev gpioe = { .regs = GPIOE_BASE, .clk_id = RCC_GPIOE, @@ -106,7 +106,7 @@ void gpio_init_all(void) { gpio_init(GPIOB); gpio_init(GPIOC); gpio_init(GPIOD); -#ifdef STM32_HIGH_DENSITY +#if STM32_NR_GPIO_PORTS > 4 gpio_init(GPIOE); gpio_init(GPIOF); gpio_init(GPIOG); @@ -123,7 +123,7 @@ void gpio_init_all(void) { */ void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) { gpio_reg_map *regs = dev->regs; - __io uint32 *cr = ®s->CRL + (pin >> 3); + __IO uint32 *cr = ®s->CRL + (pin >> 3); uint32 shift = (pin & 0x7) * 4; uint32 tmp = *cr; @@ -140,7 +140,7 @@ void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) { gpio_pin_mode gpio_get_mode(gpio_dev *dev, uint8 pin) { gpio_reg_map *regs = dev->regs; - __io uint32 *cr = ®s->CRL + (pin >> 3); + __IO uint32 *cr = ®s->CRL + (pin >> 3); uint32 shift = (pin & 0x7) * 4; uint32 crMode = (*cr>>shift) & 0x0F; @@ -180,3 +180,12 @@ void afio_remap(afio_remap_peripheral remapping) { AFIO_BASE->MAPR |= remapping; } } + +int8_t afio_is_remapped(afio_remap_peripheral remapping) { + if (remapping & AFIO_REMAP_USE_MAPR2) { + remapping &= ~AFIO_REMAP_USE_MAPR2; + return AFIO_BASE->MAPR2 & remapping; + } else { + return AFIO_BASE->MAPR & remapping; + } +} diff --git a/STM32F1/cores/maple/libmaple/i2c.c b/STM32F1/cores/maple/libmaple/i2c.c index c4ed2458f..fd2530070 100644 --- a/STM32F1/cores/maple/libmaple/i2c.c +++ b/STM32F1/cores/maple/libmaple/i2c.c @@ -28,11 +28,19 @@ /** * @file libmaple/i2c.c * @author Perry Hung + * @author Barry Carter * @brief Inter-Integrated Circuit (I2C) support. * - * Currently, only master mode is supported. + * Master and Slave supported + * I2C slave support added 2012 by Barry Carter. barry.carter@gmail.com, headfuzz.co.uk + * + * Modified 2019 by Donna Whisnant to merge WireSlave changes with the core to + * make slave mode work and without having conflicting data type defintions, + * and rewrote logic to function better. + * */ +#include #include "i2c_private.h" #include @@ -44,10 +52,13 @@ #include -static inline int32 wait_for_state_change(i2c_dev *dev, - i2c_state state, - uint32 timeout); -static void set_ccr_trise(i2c_dev *dev, uint32 flags); +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +#ifndef I2C_TIMEOUT_BUSY_FLAG +#define I2C_TIMEOUT_BUSY_FLAG 25U +#endif /** * @brief Fill data register with slave address @@ -64,7 +75,15 @@ static inline void i2c_send_slave_addr(i2c_dev *dev, uint32 addr, uint32 rw) { */ #ifdef I2C_DEBUG +// TODO : Add back DEBUG support to the IRQ functions to set these crumbs + #define NR_CRUMBS 128 +struct crumb { + uint32 event; + uint32 arg0; + uint32 arg1; + uint32 arg2; // filler to make the data fit GDB memory dump screen +}; static struct crumb crumbs[NR_CRUMBS]; static uint32 cur_crumb = 0; @@ -74,6 +93,7 @@ static inline void i2c_drop_crumb(uint32 event, uint32 arg0, uint32 arg1) { crumb->event = event; crumb->arg0 = arg0; crumb->arg1 = arg1; + crumb->arg2 = cur_crumb-1; } } #define I2C_CRUMB(event, arg0, arg1) i2c_drop_crumb(event, arg0, arg1) @@ -82,11 +102,6 @@ static inline void i2c_drop_crumb(uint32 event, uint32 arg0, uint32 arg1) { #define I2C_CRUMB(event, arg0, arg1) #endif -struct crumb { - uint32 event; - uint32 arg0; - uint32 arg1; -}; enum { IRQ_ENTRY = 1, @@ -115,7 +130,10 @@ enum { */ void i2c_bus_reset(const i2c_dev *dev) { /* Release both lines */ - i2c_master_release_bus(dev); + i2c_master_release_bus(dev); // Note: This configures the pins as GPIO instead of AF + + /* Software Reset the I2C device: */ + dev->regs->CR1 |= I2C_CR1_SWRST; /* * Make sure the bus is free by clocking it until any slaves release the @@ -144,6 +162,74 @@ void i2c_bus_reset(const i2c_dev *dev) { gpio_write_bit(scl_port(dev), dev->scl_pin, 1); delay_us(10); gpio_write_bit(sda_port(dev), dev->sda_pin, 1); + + /* Release Software Reset: */ + dev->regs->CR1 = 0; +} + +/** + * 15-step process to clear stuck busy as outlined in the + * errata sheet. Even though the errata sheet describes + * it for not being able to enter master mode. It can + * also happen when entering slave mode. A normal reset + * will clear the stuck busy, but leave you with a stuck + * start mode, which prevents a master from starting its + * sequence and prevents a slave from acknowledging its + * addresses when presented on the bus. + * + * This stuck state can also be reset by external controllers. + * So if you are interfacing two of these micros together, + * this reset logic will also clear other STM32 controllers + * on the bus that are also in this stuck-state. + */ +static void i2c_clear_busy_flag_erratum(const i2c_dev *dev) { + // 1. Clear PE bit. + dev->regs->CR1 &= ~I2C_CR1_PE; + + // 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR). + i2c_master_release_bus(dev); + + // 3. Check SCL and SDA High level in GPIOx_IDR. + while (gpio_read_bit(scl_port(dev), dev->scl_pin) == 0) { } + while (gpio_read_bit(sda_port(dev), dev->sda_pin) == 0) { } + + // 4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR). + gpio_write_bit(sda_port(dev), dev->sda_pin, 0); + + // 5. Check SDA Low level in GPIOx_IDR. + while (gpio_read_bit(sda_port(dev), dev->sda_pin)) { } + + // 6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR). + gpio_write_bit(scl_port(dev), dev->scl_pin, 0); + + // 7. Check SCL Low level in GPIOx_IDR. + while (gpio_read_bit(scl_port(dev), dev->scl_pin)) { } + + // 8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR). + gpio_write_bit(scl_port(dev), dev->scl_pin, 1); + + // 9. Check SCL High level in GPIOx_IDR. + while (gpio_read_bit(scl_port(dev), dev->scl_pin) == 0) { } + + // 10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to GPIOx_ODR). + gpio_write_bit(sda_port(dev), dev->sda_pin, 1); + + // 11. Check SDA High level in GPIOx_IDR. + while (gpio_read_bit(sda_port(dev), dev->sda_pin) == 0) { } + + // 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain. + i2c_config_gpios(dev); + + // 13. Set SWRST bit in I2Cx_CR1 register. + dev->regs->CR1 |= I2C_CR1_SWRST; + delay_us(10); + + // 14. Clear SWRST bit in I2Cx_CR1 register. + dev->regs->CR1 &= ~I2C_CR1_SWRST; + delay_us(10); + + // 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register + // This step handled in i2c_master_enable } /** @@ -152,8 +238,9 @@ void i2c_bus_reset(const i2c_dev *dev) { * @param dev Device to initialize. */ void i2c_init(i2c_dev *dev) { + rcc_clk_enable(dev->clk_id); // The device's clock should enabled before we reset it rcc_reset_dev(dev->clk_id); - rcc_clk_enable(dev->clk_id); + _i2c_irq_priority_fixup(dev); } /* Hack for deprecated bit of STM32F1 functionality */ @@ -162,10 +249,9 @@ void i2c_init(i2c_dev *dev) { #endif /** - * @brief Initialize an I2C device as bus master + * @brief Initialize an I2C device as bus master or slave * @param dev Device to enable * @param flags Bitwise or of the following I2C options: - * I2C_FAST_MODE: 400 khz operation, * I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for * fast mode), * I2C_BUS_RESET: Reset the bus and clock out any hung slaves on @@ -173,37 +259,93 @@ void i2c_init(i2c_dev *dev) { * I2C_10BIT_ADDRESSING: Enable 10-bit addressing, * I2C_REMAP: (deprecated, STM32F1 only) Remap I2C1 to SCL/PB8 * SDA/PB9. + * I2C_SLAVE_MODE: Configure as Slave + * I2C_SLAVE_DUAL_ADDRESS: Slave can respond on 2 i2C addresses + * I2C_SLAVE_GENERAL_CALL: SLA+W broadcast to all general call + * listeners on bus. Addr 0x00 */ -void i2c_master_enable(i2c_dev *dev, uint32 flags) { - /* PE must be disabled to configure the device */ - ASSERT(!(dev->regs->CR1 & I2C_CR1_PE)); - - /* Ugh */ +void i2c_master_enable(i2c_dev *dev, uint32 flags, uint32 freq) { + /* Remap I2C if needed */ _i2c_handle_remap(dev, flags); + /* Turn on clock */ + i2c_init(dev); // If clocks aren't running here, the reset and clear logic below doesn't work + + /* If the device is already enabled, disable so we can reconfigure it */ + i2c_disable(dev); + /* Reset the bus. Clock out any hung slaves. */ + /* Note that this call reconfigs the port pins as GPIO instead of AF */ if (flags & I2C_BUS_RESET) { i2c_bus_reset(dev); + flags &= ~I2C_BUS_RESET; } - /* Turn on clock and set GPIO modes */ - i2c_init(dev); + if (flags & I2C_PUP_RESET) { + i2c_clear_busy_flag_erratum(dev); + flags &= ~I2C_PUP_RESET; + } + + /* Set GPIO modes to AF */ i2c_config_gpios(dev); - /* Configure clock and rise time */ - set_ccr_trise(dev, flags); + /* Configure clock and rise time, for both master and slave devices. + * As per ST specs, CR2 must be set for both. CCR and TRISE is only + * needed on master devices, but doesn't hurt to be set for slaves + * too. + */ + i2c_set_ccr_trise(dev, flags, freq); /* Enable event and buffer interrupts */ nvic_irq_enable(dev->ev_nvic_line); nvic_irq_enable(dev->er_nvic_line); - i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_BUFFER | I2C_IRQ_ERROR); + + /* store all of the flags */ + dev->config_flags = flags; /* Make it go! */ - i2c_peripheral_enable(dev); + dev->regs->CR1 |= I2C_CR1_PE; // This has to be done before setting the flags below for slave + + /* Configure the slave unit */ + if (flags & I2C_SLAVE_MODE) { + if (flags & I2C_SLAVE_GENERAL_CALL) { + dev->regs->CR1 |= I2C_CR1_ENGC; + } + dev->regs->CR1 &= ~I2C_CR1_POS; // Disable POS + dev->regs->CR1 |= I2C_CR1_ACK; // Slave mode needs to acknowledge address matches + + /* Enable interrupts immediately for slave input, + * for master, we'll wait until transmitting. + */ + i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_ERROR); + } dev->state = I2C_STATE_IDLE; } + +/** + * @brief Initialize an I2C device as slave + * @param dev Device to enable + * @param flags Bitwise or of the following I2C options: + * I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for + * fast mode), + * I2C_BUS_RESET: Reset the bus and clock out any hung slaves on + * initialization, + * I2C_10BIT_ADDRESSING: Enable 10-bit addressing, + * I2C_REMAP: (deprecated, STM32F1 only) Remap I2C1 to SCL/PB8 + * SDA/PB9. + * I2C_SLAVE_MODE: Configure as Slave + * I2C_SLAVE_DUAL_ADDRESS: Slave can respond on 2 i2C addresses + * I2C_SLAVE_GENERAL_CALL: SLA+W broadcast to all general call + * listeners on bus. Addr 0x00 + */ +void i2c_slave_enable(i2c_dev *dev, uint32 flags, uint32 freq) +{ + i2c_master_enable(dev, flags | I2C_SLAVE_MODE, freq); +} + + /** * @brief Process an i2c transaction. * @@ -228,21 +370,67 @@ int32 i2c_master_xfer(i2c_dev *dev, ASSERT(dev->state == I2C_STATE_IDLE); + if (num == 0) return 0; + + // Wait for I2C to not be busy: + uint32_t count = I2C_TIMEOUT_BUSY_FLAG * (F_CPU / 25U /1000U); + do { + if (count-- == 0U) { + return I2C_ERROR_TIMEOUT; + } + } while (dev->regs->SR2 & I2C_SR2_BUSY); + + dev->error_flags = 0; dev->msg = msgs; dev->msgs_left = num; + do { + dev->msg[num-1].xferred = 0; + } while (--num); dev->timestamp = systick_uptime(); dev->state = I2C_STATE_BUSY; - i2c_enable_irq(dev, I2C_IRQ_EVENT); - i2c_start_condition(dev); - + dev->regs->CR1 = I2C_CR1_PE; // Enable but reset special flags + dev->regs->SR1 = 0; // Reset error/status flags + i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_ERROR); + if (dev->msg[0].flags & I2C_MSG_READ) { + dev->regs->CR1 = I2C_CR1_PE | I2C_CR1_START | I2C_CR1_ACK; + } else { + dev->regs->CR1 = I2C_CR1_PE | I2C_CR1_START; + } + rc = wait_for_state_change(dev, I2C_STATE_XFER_DONE, timeout); - if (rc < 0) { - goto out; + + i2c_disable_irq(dev, I2C_IRQ_BUFFER | I2C_IRQ_EVENT | I2C_IRQ_ERROR); + + if (rc != 0) { + // If we had an error, make sure the device state reflects that + // and make use of the smb I2C_SR1_TIMEOUT flag. These have to be + // done here after disabling the IRQ above to avoid a race-condition + // with state changes in the IRQ handlers: + dev->state = I2C_STATE_ERROR; + if (rc == I2C_ERROR_TIMEOUT) dev->error_flags |= I2C_SR1_TIMEOUT; + if (!(dev->config_flags & I2C_SLAVE_MODE) && + (dev->error_flags & (I2C_SR1_AF | I2C_SR1_BERR | I2C_SR1_TIMEOUT)) + ) { // In Master Mode, we need to abort the transmission with a STOP + // for NACK, Bus Error, or Timeout + uint32 cr1; + while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | + I2C_CR1_STOP | + I2C_CR1_PEC)) { + ; // Must wait for pending start/stop/pec before setting stop to avoid + // accidental restart condition. See ST RM0008 Note in 26.6.1 (I2C_CR1) + } + dev->regs->CR1 |= I2C_CR1_STOP; + while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | + I2C_CR1_STOP | + I2C_CR1_PEC)) { + ; + } + } + } else { + dev->state = I2C_STATE_IDLE; } - dev->state = I2C_STATE_IDLE; -out: return rc; } @@ -253,26 +441,34 @@ int32 i2c_master_xfer(i2c_dev *dev, * @param timeout Timeout, in milliseconds * @return 0 if target state is reached, a negative value on error. */ -static inline int32 wait_for_state_change(i2c_dev *dev, - i2c_state state, - uint32 timeout) { - i2c_state tmp; +int32 wait_for_state_change(i2c_dev *dev, + i2c_state state, + uint32 timeout) { + volatile i2c_state devState; + volatile uint32 devTimestamp; while (1) { - tmp = dev->state; - - if (tmp == I2C_STATE_ERROR) { - return I2C_STATE_ERROR; + // Avoid race condition with interrupt handler while reading state and timestamp + // Note: Since the IRQs have to be enabled in the first place for + // I2C to even work, we don't need to save/restore the state of IRQ + // enable here -- a single disable and re-enable is fine: + nvic_irq_disable(dev->ev_nvic_line); + nvic_irq_disable(dev->er_nvic_line); + devState = dev->state; + devTimestamp = dev->timestamp; + nvic_irq_enable(dev->er_nvic_line); + nvic_irq_enable(dev->ev_nvic_line); + + if (devState == I2C_STATE_ERROR) { + return I2C_ERROR_PROTOCOL; } - if (tmp == state) { + if (devState == state) { return 0; } if (timeout) { - if (systick_uptime() > (dev->timestamp + timeout)) { - /* TODO: overflow? */ - /* TODO: racy? */ + if ((uint32)(systick_uptime() - devTimestamp) > timeout) { return I2C_ERROR_TIMEOUT; } } @@ -284,206 +480,348 @@ static inline int32 wait_for_state_change(i2c_dev *dev, */ /* - * IRQ handler for I2C master. Handles transmission/reception. + * IRQ handler for I2C master and slave. + * Handles transmission/reception. */ void _i2c_irq_handler(i2c_dev *dev) { - /* WTFs: - * - Where is I2C_MSG_10BIT_ADDR handled? - */ - i2c_msg *msg = dev->msg; - - uint8 read = msg->flags & I2C_MSG_READ; - - uint32 sr1 = dev->regs->SR1; - uint32 sr2 = dev->regs->SR2; - I2C_CRUMB(IRQ_ENTRY, sr1, sr2); + // See Note in ST Specs: + // Reading I2C_SR2 after reading I2C_SR1 clears the ADDR flag, even if the ADDR flag was + // set after reading I2C_SR1. Consequently, I2C_SR2 must be read only when ADDR is found + // set in I2C_SR1 or when the STOPF bit is cleared. + + __IO uint32_t cr1 = dev->regs->CR1; // initial control register + __IO uint32_t sr1 = dev->regs->SR1; // read status register + __IO uint32_t sr2 = 0; // reserved for reading the SR2 register, but save it for latter since reading it clears ADDR + + dev->timestamp = systick_uptime(); // Reset timeout counter + + if (!(dev->config_flags & I2C_SLAVE_MODE)) { // Handle Master Mode Here: + int8_t bDone = 0; // Set to true when we're done with this transfer unit + i2c_msg *curMsg = dev->msg; + if (curMsg != NULL) { + int todo = curMsg->length; // Bytes to transfer + if (curMsg->flags & I2C_MSG_READ) { // read transaction: + if (sr1 & I2C_SR1_SB) { // start bit + // TODO : Add support for 10-bit address + i2c_send_slave_addr(dev, curMsg->addr, 1); + } else { + if (sr1 & I2C_SR1_ADDR) { // address sent + if (todo <= 1) { + dev->regs->CR1 = (cr1 &= ~I2C_CR1_ACK); // Disable ACK + sr2 = dev->regs->SR2; // Clear ADDR bit + dev->regs->CR1 = (cr1 |= I2C_CR1_STOP); // Stop after last byte + } else if (todo == 2) { + dev->regs->CR1 = (cr1 |= I2C_CR1_POS); // Enable POS + sr2 = dev->regs->SR2; // Clear ADDR bit + dev->regs->CR1 = (cr1 &= ~I2C_CR1_ACK); // Disable ACK + } else { + dev->regs->CR1 = (cr1 |= I2C_CR1_ACK); // Enable ACK + sr2 = dev->regs->SR2; // Clear ADDR bit + } + if (todo >= 1) { + i2c_enable_irq(dev, I2C_IRQ_BUFFER); // Enable I2C_SR1_RXNE interrupt + } else { + bDone = 1; + } + } else { + int8_t bFlgRXNE = ((sr1 & I2C_SR1_RXNE) != 0); + int8_t bFlgBTF = ((sr1 & I2C_SR1_BTF) != 0); + + if (bFlgRXNE && !bFlgBTF) { + if ((todo > 3) || (todo == 1)) { + curMsg->data[curMsg->xferred++] = (uint8_t)(dev->regs->DR); // read/save data + curMsg->length--; // Decrement bytes left to read + } else if ((todo == 2) || (todo == 3)) { + i2c_disable_irq(dev, I2C_IRQ_BUFFER); // Disable I2C_SR1_RXNE interrupt and Switch to BTF mode + } + if (todo <= 1) { + bDone = 1; + } + } else if (bFlgBTF) { + if (todo == 3) { + dev->regs->CR1 = (cr1 &= ~I2C_CR1_ACK); // Disable ACK + } else if (todo == 2) { + dev->regs->CR1 = (cr1 |= I2C_CR1_STOP); // Generate stop + } + + curMsg->data[curMsg->xferred++] = (uint8_t)(dev->regs->DR); // read/save data + curMsg->length--; // Decrement bytes left to read + + if (todo == 2) { + // If there were 2 bytes, read/save last byte -- we're done: + curMsg->data[curMsg->xferred++] = (uint8_t)(dev->regs->DR); // read/save data + curMsg->length--; // Decrement bytes left to read + + bDone = 1; + } + } + } + } + } else { // write transaction + if (sr1 & I2C_SR1_SB) { // start bit + if (todo != 0) { + i2c_enable_irq(dev, I2C_IRQ_BUFFER); // Enable I2C_SR1_TXE interrupt + } + // TODO : Add support for 10-bit address + i2c_send_slave_addr(dev, curMsg->addr, 0); + } else { + int8_t bFlgTXE = 0; + int8_t bFlgBTF = 0; + + if (sr1 & I2C_SR1_ADDR) { + sr2 = dev->regs->SR2; // Clear ADDR bit + } + + bFlgTXE = ((sr1 & I2C_SR1_TXE) != 0); + bFlgBTF = (((sr1 & I2C_SR1_BTF) != 0) || (todo == 0)); + + if (bFlgTXE || bFlgBTF) { + if (todo > 0) { + // Write data to DR + dev->regs->DR = curMsg->data[curMsg->xferred++]; + curMsg->length = --todo; // update todo too + + if (bFlgTXE && (todo == 0)) { + i2c_disable_irq(dev, I2C_IRQ_BUFFER); // Disable I2C_SR1_TXE interrupt and Switch to BTF mode + } + } else if (bFlgBTF) { + // Generate Stop + if ((curMsg->flags & I2C_MSG_NOSTOP) == 0) { + dev->regs->CR1 = (cr1 |= I2C_CR1_STOP); + } + + bDone = 1; + } + } + } + } - /* - * Reset timeout counter - */ - dev->timestamp = systick_uptime(); + if (bDone) { + if (--dev->msgs_left != 0) { // Check to see if there's another back-to-back message + i2c_disable_irq(dev, I2C_IRQ_BUFFER); // Disable I2C_SR1_RXNE/I2C_SR1_TXE interrupt + ++dev->msg; + curMsg = dev->msg; + if (curMsg->flags & I2C_MSG_READ) { // Send restart, disable POS, and enable ACK as necessary + dev->regs->CR1 = I2C_CR1_PE | I2C_CR1_START | I2C_CR1_ACK; + } else { + dev->regs->CR1 = I2C_CR1_PE | I2C_CR1_START; + } + } else { + dev->msg = NULL; + dev->state = I2C_STATE_XFER_DONE; + } + } + } // curMsg != NULL - /* - * EV5: Start condition sent - */ - if (sr1 & I2C_SR1_SB) { - msg->xferred = 0; - i2c_enable_irq(dev, I2C_IRQ_BUFFER); + } else { // Handle Slave Mode: + if (sr1 & I2C_SR1_ADDR) { // Address Match + uint16_t nAddr; - /* - * Master receiver - */ - if (read) { - i2c_enable_ack(dev); - } + sr2 = dev->regs->SR2; // Clear ADDR bit and get remaining status bits - i2c_send_slave_addr(dev, msg->addr, read); - sr1 = sr2 = 0; - } + dev->error_flags = 0; // New error flags for the new message - /* - * EV6: Slave address sent - */ - if (sr1 & I2C_SR1_ADDR) { - /* - * Special case event EV6_1 for master receiver. - * Generate NACK and restart/stop condition after ADDR - * is cleared. - */ - if (read) { - if (msg->length == 1) { - i2c_disable_ack(dev); - if (dev->msgs_left > 1) { - i2c_start_condition(dev); - I2C_CRUMB(RX_ADDR_START, 0, 0); + if (sr2 & I2C_SR2_GENCALL) { // We matched the General Call Address + nAddr = 0; + } else if (sr2 & I2C_SR2_DUALF) { // We matched the Secondary Slave address + if (dev->regs->OAR1 & I2C_OAR1_ADDMODE) { + // 10-bit address: + nAddr = (dev->regs->OAR1 & 0x0301) | (dev->regs->OAR2 & 0xFE); } else { - i2c_stop_condition(dev); - I2C_CRUMB(RX_ADDR_STOP, 0, 0); + // 7-bit address: + nAddr = ((dev->regs->OAR2 >> 1) & 0x7F); + } + } else { // We matched the Primary Slave address + if (dev->regs->OAR1 & I2C_OAR1_ADDMODE) { + // 10-bit address: + nAddr = (dev->regs->OAR1 & 0x03FF); + } else { + // 7-bit address: + nAddr = ((dev->regs->OAR1 >> 1) & 0x7F); } } - } else { - /* - * Master transmitter: write first byte to fill shift - * register. We should get another TXE interrupt - * immediately to fill DR again. - */ - if (msg->length > 1) { - i2c_write(dev, msg->data[msg->xferred++]); - } else if (msg->length == 0) { /* We're just sending an address */ - i2c_stop_condition(dev); - /* - * Turn off event interrupts to keep BTF from firing until - * the end of the stop condition. Why on earth they didn't - * have a start/stop condition request clear BTF is beyond - * me. - */ - i2c_disable_irq(dev, I2C_IRQ_EVENT); - I2C_CRUMB(STOP_SENT, 0, 0); - dev->state = I2C_STATE_XFER_DONE; - } /* else we're just sending one byte */ - } - sr1 = sr2 = 0; - } - /* - * EV8: Master transmitter - * Transmit buffer empty, but we haven't finished transmitting the last - * byte written. - */ - if ((sr1 & I2C_SR1_TXE) && !(sr1 & I2C_SR1_BTF)) { - I2C_CRUMB(TXE_ONLY, 0, 0); - if (dev->msgs_left) { - i2c_write(dev, msg->data[msg->xferred++]); - if (msg->xferred == msg->length) { - /* - * End of this message. Turn off TXE/RXNE and wait for - * BTF to send repeated start or stop condition. - */ - i2c_disable_irq(dev, I2C_IRQ_BUFFER); - dev->msgs_left--; + if (sr2 & I2C_SR2_TRA) { + // If we still have data we received in the turn-around, we + // sometimes get this interrupt ahead of the error interrupt, + // in which case we need to give the received data to its + // callback first so that the request data is ready to send: + if ((dev->i2c_slave_recv_msg != NULL) && (dev->i2c_slave_recv_msg->xferred)) { + if (dev->i2c_slave_recv_callback) { + dev->i2c_slave_recv_callback(dev->i2c_slave_recv_msg); // Callback and process the buffer + } + dev->i2c_slave_recv_msg->xferred = 0; // Release message buffer for another read + } + + // Prepare for transmit: + if (dev->i2c_slave_xmit_msg != NULL) { + dev->i2c_slave_xmit_msg->addr = nAddr; + dev->i2c_slave_xmit_msg->length = 0; // Clear length in case we don't have a callback + if (dev->i2c_slave_xmit_callback) { + dev->i2c_slave_xmit_callback(dev->i2c_slave_xmit_msg); // Callback and fill buffer to send + } + dev->i2c_slave_xmit_msg->xferred = 0; + } + } else { + // Prepare for receive: + if (dev->i2c_slave_recv_msg != NULL) { + dev->i2c_slave_recv_msg->addr = nAddr; + dev->i2c_slave_recv_msg->xferred = 0; + } } - } else { - /* - * This should be impossible... - */ - ASSERT(0); + + i2c_enable_irq(dev, I2C_IRQ_BUFFER); // Enabled I2C_SR1_RXNE/I2C_SR1_TXE interupt + dev->state = I2C_STATE_BUSY; } - sr1 = sr2 = 0; - } + else if (sr1 & I2C_SR1_STOPF) { + sr2 = dev->regs->SR2; + + // If we received data we haven't returned, report it to the client, + // and resume IDLE state. This handles the case where the master + // didn't properly send a NACK but sent a STOP instead. The normal + // path is handled in the error interrupter with the AF bit. + if ((dev->i2c_slave_recv_msg != NULL) && (dev->i2c_slave_recv_msg->xferred)) { + if (dev->i2c_slave_recv_callback) { + dev->i2c_slave_recv_callback(dev->i2c_slave_recv_msg); // Callback and process the buffer + } + dev->i2c_slave_recv_msg->xferred = 0; // Release message buffer for another read + } - /* - * EV8_2: Master transmitter - * Last byte sent, program repeated start/stop - */ - if ((sr1 & I2C_SR1_TXE) && (sr1 & I2C_SR1_BTF)) { - I2C_CRUMB(TXE_BTF, 0, 0); - if (dev->msgs_left) { - I2C_CRUMB(TEST, 0, 0); - /* - * Repeated start insanity: We can't disable ITEVTEN or else SB - * won't interrupt, but if we don't disable ITEVTEN, BTF will - * continually interrupt us. What the fuck ST? - */ - i2c_start_condition(dev); - while (!(dev->regs->SR1 & I2C_SR1_SB)) - ; - dev->msg++; + // Clearing STOPF requires reading SR1 (which we've already done), followed by writing CR1 + dev->regs->CR1 |= (cr1 |= I2C_CR1_ACK); // Make sure ACK is reenabled for next incoming address + dev->state = I2C_STATE_IDLE; } else { - i2c_stop_condition(dev); - - /* - * Turn off event interrupts to keep BTF from firing until - * the end of the stop condition. Why on earth they didn't - * have a start/stop condition request clear BTF is beyond - * me. - */ - i2c_disable_irq(dev, I2C_IRQ_EVENT); - I2C_CRUMB(STOP_SENT, 0, 0); - dev->state = I2C_STATE_XFER_DONE; - } - sr1 = sr2 = 0; - } + int8_t bFlgBTF = ((sr1 & I2C_SR1_BTF) != 0); + int8_t bFlgTXE = (((sr1 & I2C_SR1_TXE) != 0) && ((dev->regs->CR2 & I2C_CR2_ITBUFEN) != 0)); + int todo = 0; // Bytes remaining to transfer for Xmit or bytes of remaining buffer for Recv - /* - * EV7: Master Receiver - */ - if (sr1 & I2C_SR1_RXNE) { - I2C_CRUMB(RXNE_ONLY, 0, 0); - msg->data[msg->xferred++] = dev->regs->DR; - - /* - * EV7_1: Second to last byte in the reception? Set NACK and generate - * stop/restart condition in time for the last byte. We'll get one more - * RXNE interrupt before shutting things down. - */ - if (msg->xferred == (msg->length - 1)) { - i2c_disable_ack(dev); - if (dev->msgs_left > 2) { - i2c_start_condition(dev); - I2C_CRUMB(RXNE_START_SENT, 0, 0); - } else { - i2c_stop_condition(dev); - I2C_CRUMB(RXNE_STOP_SENT, 0, 0); - } - } else if (msg->xferred == msg->length) { - dev->msgs_left--; - if (dev->msgs_left == 0) { - /* - * We're done. - */ - I2C_CRUMB(RXNE_DONE, 0, 0); - dev->state = I2C_STATE_XFER_DONE; + sr2 = dev->regs->SR2; + + if (sr2 & I2C_SR2_TRA) { + // In Transmit Mode: + if (dev->i2c_slave_xmit_msg) { + todo = (dev->i2c_slave_xmit_msg->length - dev->i2c_slave_xmit_msg->xferred); + } + + if (bFlgTXE || bFlgBTF) { + // Send next byte of data: + __IO uint8_t nData = 0; + if ((dev->i2c_slave_xmit_msg) && (todo)) { + nData = dev->i2c_slave_xmit_msg->data[dev->i2c_slave_xmit_msg->xferred++]; + } + dev->regs->DR = nData; + + if (todo) --todo; + if (bFlgTXE && (todo == 0)) { + i2c_disable_irq(dev, I2C_IRQ_BUFFER); // Disable I2C_SR1_TXE interrupt and switch to BTF mode + } + } } else { - dev->msg++; + // In Receive Mode: + __IO uint8_t nData = 0; + int8_t bFlgRXNE = (((sr1 & I2C_SR1_RXNE) != 0) && ((dev->regs->CR2 & I2C_CR2_ITBUFEN) != 0)); + + if (dev->i2c_slave_recv_msg) { + todo = (dev->i2c_slave_recv_msg->length - dev->i2c_slave_recv_msg->xferred); + } + + if (bFlgRXNE && !bFlgBTF) { + if (todo > 0) { + // Note: We already know the i2c_slave_recv_msg isn't null because todo!=0 + nData = dev->regs->DR; // Clears I2C_SR1_RXNE flag + dev->i2c_slave_recv_msg->data[dev->i2c_slave_recv_msg->xferred++] = nData; + } + if (todo <= 3) { + i2c_disable_irq(dev, I2C_IRQ_BUFFER); // Disable I2C_SR1_RXNE interrupt and Switch to BTF mode + } + } else if (bFlgBTF) { + // If our receive buffer is filling up, NAK and/or force Stop: + if (todo == 3) { + dev->regs->CR1 = (cr1 &= ~I2C_CR1_ACK); // Disable ACK + } else if (todo == 2) { + dev->regs->CR1 = (cr1 |= I2C_CR1_STOP); // Generate stop + } + + nData = dev->regs->DR; + if (todo > 0) { + // Note: We already know the i2c_slave_recv_msg isn't null because todo>0 + dev->i2c_slave_recv_msg->data[dev->i2c_slave_recv_msg->xferred++] = nData; + } + + if (bFlgRXNE) { + // If there were 2 bytes (both flags set), read/save last byte: + nData = dev->regs->DR; + if (todo > 1) { // Compare with >1 here because we already read one byte above + // Note: We already know the i2c_slave_recv_msg isn't null because todo>1 + dev->i2c_slave_recv_msg->data[dev->i2c_slave_recv_msg->xferred++] = nData; + } + i2c_disable_irq(dev, I2C_IRQ_BUFFER); // Disable I2C_SR1_RXNE/I2C_SR1_TXE interrupt + } + } } } - } + + } // End of Slave Mode } + /* * Interrupt handler for I2C error conditions. Aborts any pending I2C * transactions. */ void _i2c_irq_error_handler(i2c_dev *dev) { - I2C_CRUMB(ERROR_ENTRY, dev->regs->SR1, dev->regs->SR2); + __IO uint32_t sr1 = dev->regs->SR1; + __IO uint32_t sr2 = dev->regs->SR2; - dev->error_flags = dev->regs->SR1 & (I2C_SR1_BERR | - I2C_SR1_ARLO | - I2C_SR1_AF | - I2C_SR1_OVR); + dev->timestamp = systick_uptime(); // Reset timeout counter + + dev->error_flags = sr1 & (I2C_SR1_BERR | + I2C_SR1_ARLO | + I2C_SR1_AF | + I2C_SR1_OVR); + + if (dev->config_flags & I2C_SLAVE_MODE) { + // Slave Mode: + i2c_disable_irq(dev, I2C_IRQ_BUFFER); // Disable I2C_SR1_RXNE/I2C_SR1_TXE interrupt in case it was still active + dev->regs->CR1 |= I2C_CR1_ACK; // Make sure ACK is reenabled for next incoming address + + if (sr1 & I2C_SR1_AF) { + // If we received data, report it to the client, + // Clear the NACK for the end of Transmit, and resume IDLE state: + dev->regs->SR1 = ~I2C_SR1_AF; + + if ((dev->i2c_slave_recv_msg != NULL) && (dev->i2c_slave_recv_msg->xferred)) { + if (dev->i2c_slave_recv_callback) { + dev->i2c_slave_recv_callback(dev->i2c_slave_recv_msg); // Callback and process the buffer + } + dev->i2c_slave_recv_msg->xferred = 0; // Release message buffer for another read + } + + dev->state = I2C_STATE_IDLE; + return; + } + } + + /* Catch any other strange errors while in slave mode and + * all errors in master mode (which are handled by outer loop). + * I have seen BERR caused by an over fast master device + * as well as several overflows and arbitration failures. + * We are going to reset SR flags and carry on at this point which + * is not the best thing to do, but stops the bus locking up completely + * If we carry on below and send the stop bit, the code spins forever */ /* Clear flags */ dev->regs->SR1 = 0; dev->regs->SR2 = 0; - - i2c_stop_condition(dev); - i2c_disable_irq(dev, I2C_IRQ_BUFFER | I2C_IRQ_EVENT | I2C_IRQ_ERROR); dev->state = I2C_STATE_ERROR; + + UNUSED(sr2); } + /* * CCR/TRISE configuration helper */ -static void set_ccr_trise(i2c_dev *dev, uint32 flags) { +void i2c_set_ccr_trise(i2c_dev *dev, uint32 flags, uint32 freq) { uint32 ccr = 0; uint32 trise = 0; uint32 clk_mhz = _i2c_bus_clk(dev); @@ -491,22 +829,22 @@ static void set_ccr_trise(i2c_dev *dev, uint32 flags) { i2c_set_input_clk(dev, clk_mhz); - if (flags & I2C_FAST_MODE) { + if (freq > 100000) { //FAST MODE & FAST MODE+ ccr |= I2C_CCR_FS; if (flags & I2C_DUTY_16_9) { /* Tlow/Thigh = 16/9 */ ccr |= I2C_CCR_DUTY_16_9; - ccr |= clk_hz / (400000 * 25); + ccr |= clk_hz / (freq * 25); } else { /* Tlow/Thigh = 2 */ - ccr |= clk_hz / (400000 * 3); + ccr |= clk_hz / (freq * 3); } trise = (300 * clk_mhz / 1000) + 1; } else { /* Tlow/Thigh = 1 */ - ccr = clk_hz / (100000 * 2); + ccr = clk_hz / (freq * 2); trise = clk_mhz + 1; } @@ -518,3 +856,31 @@ static void set_ccr_trise(i2c_dev *dev, uint32 flags) { i2c_set_clk_control(dev, ccr); i2c_set_trise(dev, trise); } + + +/** + * @brief callback for when the device acts as a slave. If using an rx buffer, this is triggered + * after the last byte, otherwise it is called for every incoming packet. + * @param dev I2C device + * @param msg The dev_msg to pass to the slave init code + * @param func The function pointer to call + */ +void i2c_slave_attach_recv_handler(i2c_dev *dev, i2c_msg *msg, i2c_slave_recv_callback_func func) { + dev->i2c_slave_recv_callback = func; + dev->i2c_slave_recv_msg = msg; + msg->xferred = 0; +} + + +/** + * @brief callback for when the device acts as a slave. If using a tx buffer, this is triggered + * after the device is successsfully addressed with SLA+R. + * @param dev I2C device + * @param msg The dev_msg to pass to the slave init code + * @param func The function pointer to call + */ +void i2c_slave_attach_transmit_handler(i2c_dev *dev, i2c_msg *msg, i2c_slave_xmit_callback_func func) { + dev->i2c_slave_xmit_callback = func; + dev->i2c_slave_xmit_msg = msg; + msg->xferred = 0; +} diff --git a/STM32F1/cores/maple/libmaple/i2c_f1.c b/STM32F1/cores/maple/libmaple/i2c_f1.c index 8439793da..a0c9db926 100644 --- a/STM32F1/cores/maple/libmaple/i2c_f1.c +++ b/STM32F1/cores/maple/libmaple/i2c_f1.c @@ -76,19 +76,19 @@ void i2c_master_release_bus(const i2c_dev *dev) { * IRQ handlers */ -void __irq_i2c1_ev(void) { +__weak void __irq_i2c1_ev(void) { _i2c_irq_handler(I2C1); } -void __irq_i2c2_ev(void) { +__weak void __irq_i2c2_ev(void) { _i2c_irq_handler(I2C2); } -void __irq_i2c1_er(void) { +__weak void __irq_i2c1_er(void) { _i2c_irq_error_handler(I2C1); } -void __irq_i2c2_er(void) { +__weak void __irq_i2c2_er(void) { _i2c_irq_error_handler(I2C2); } @@ -96,6 +96,7 @@ void __irq_i2c2_er(void) { * Internal APIs */ +#if defined(_I2C_HAVE_IRQ_FIXUP) && (_I2C_HAVE_IRQ_FIXUP) void _i2c_irq_priority_fixup(i2c_dev *dev) { /* * Important STM32 Errata: @@ -123,7 +124,14 @@ void _i2c_irq_priority_fixup(i2c_dev *dev) { * not be preempted. We set the i2c interrupt priority to be the highest * interrupt in the system (priority level 0). All other interrupts have * been initialized to priority level 16. See nvic_init(). + * + * TODO: Add alternate workaround in the Event Interrupt which involves + * switching the pins to GPIO mode and manually stretching the receive event. + * */ nvic_irq_set_priority(dev->ev_nvic_line, 0); - nvic_irq_set_priority(dev->er_nvic_line, 0); +// Note: The fixup only involves the Event Interrupt. +// There's no need to bump the Error Interrupt's priority: +// nvic_irq_set_priority(dev->er_nvic_line, 0); } +#endif diff --git a/STM32F1/cores/maple/libmaple/rcc.c b/STM32F1/cores/maple/libmaple/rcc.c index 8e7d1ea7d..144dcbcc4 100644 --- a/STM32F1/cores/maple/libmaple/rcc.c +++ b/STM32F1/cores/maple/libmaple/rcc.c @@ -61,7 +61,7 @@ void rcc_switch_sysclk(rcc_sysclk_src sysclk_src) { RCC_BASE->CFGR = cfgr; /* Wait for new source to come into use. */ - while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != (sysclk_src << 2)) + while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != (unsigned int)(sysclk_src << 2)) ; } @@ -94,8 +94,8 @@ void rcc_switch_sysclk(rcc_sysclk_src sysclk_src) { * won't work for you. */ /* Returns the RCC register which controls the clock source. */ -static inline __io uint32* rcc_clk_reg(rcc_clk clock) { - return (__io uint32*)((__io uint8*)RCC_BASE + (clock >> 8)); +static inline __IO uint32* rcc_clk_reg(rcc_clk clock) { + return (__IO uint32*)((__IO uint8*)RCC_BASE + (clock >> 8)); } /* Returns a mask in rcc_clk_reg(clock) to be used for turning the diff --git a/STM32F1/cores/maple/libmaple/rcc_f1.c b/STM32F1/cores/maple/libmaple/rcc_f1.c index f45f670e1..965d5ba1d 100644 --- a/STM32F1/cores/maple/libmaple/rcc_f1.c +++ b/STM32F1/cores/maple/libmaple/rcc_f1.c @@ -69,10 +69,12 @@ const struct rcc_dev_info rcc_dev_table[] = { [RCC_FLITF] = { .clk_domain = AHB, .line_num = 4}, [RCC_SRAM] = { .clk_domain = AHB, .line_num = 2}, [RCC_USB] = { .clk_domain = APB1, .line_num = 23}, -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) +#if STM32_NR_GPIO_PORTS > 4 [RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 }, [RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 }, [RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 }, +#endif +#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) [RCC_UART4] = { .clk_domain = APB1, .line_num = 19 }, [RCC_UART5] = { .clk_domain = APB1, .line_num = 20 }, [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, @@ -93,6 +95,7 @@ const struct rcc_dev_info rcc_dev_table[] = { [RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 }, [RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 }, #endif + [RCC_CAN] = { .clk_domain = APB1, .line_num = 25 }, //! JMD after X893 }; __deprecated @@ -132,11 +135,17 @@ void rcc_configure_pll(rcc_pll_cfg *pll_cfg) { cfgr &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL); cfgr |= pll_cfg->pllsrc | pll_mul; +#ifdef XTAL16M + // 16MHz crystal (HSE) + // in this case we additionally set the Bit 17 (PLLXTPRE=1) => then HSE clock is divided by 2 before PLL entry + cfgr |= RCC_CFGR_PLLXTPRE; +#endif + RCC_BASE->CFGR = cfgr; } void rcc_clk_enable(rcc_clk_id id) { - static __io uint32* enable_regs[] = { + static __IO uint32* enable_regs[] = { [APB1] = &RCC_BASE->APB1ENR, [APB2] = &RCC_BASE->APB2ENR, [AHB] = &RCC_BASE->AHBENR, @@ -145,7 +154,7 @@ void rcc_clk_enable(rcc_clk_id id) { } void rcc_reset_dev(rcc_clk_id id) { - static __io uint32* reset_regs[] = { + static __IO uint32* reset_regs[] = { [APB1] = &RCC_BASE->APB1RSTR, [APB2] = &RCC_BASE->APB2RSTR, }; @@ -164,7 +173,7 @@ void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { } void rcc_clk_disable(rcc_clk_id id) { - static __io uint32* enable_regs[] = { + static __IO uint32* enable_regs[] = { [APB1] = &RCC_BASE->APB1ENR, [APB2] = &RCC_BASE->APB2ENR, [AHB] = &RCC_BASE->AHBENR, diff --git a/STM32F1/cores/maple/libmaple/stm32f1/performance/isrs.S b/STM32F1/cores/maple/libmaple/stm32f1/performance/isrs.S index 8c1a44fcd..7a9b4aad5 100644 --- a/STM32F1/cores/maple/libmaple/stm32f1/performance/isrs.S +++ b/STM32F1/cores/maple/libmaple/stm32f1/performance/isrs.S @@ -76,9 +76,9 @@ __default_handler: .weak __exc_pendsv .globl __exc_pendsv .set __exc_pendsv, __default_handler - .weak __exc_systick - .globl __exc_systick - .set __exc_systick, __default_handler +// .weak __exc_systick // __exc_systick() defined in STM32F1/cores/maple/libmaple/systick.c +// .globl __exc_systick +// .set __exc_systick, __default_handler .weak __irq_wwdg .globl __irq_wwdg .set __irq_wwdg, __default_handler @@ -97,110 +97,110 @@ __default_handler: .weak __irq_rcc .globl __irq_rcc .set __irq_rcc, __default_handler - .weak __irq_exti0 - .globl __irq_exti0 - .set __irq_exti0, __default_handler - .weak __irq_exti1 - .globl __irq_exti1 - .set __irq_exti1, __default_handler - .weak __irq_exti2 - .globl __irq_exti2 - .set __irq_exti2, __default_handler - .weak __irq_exti3 - .globl __irq_exti3 - .set __irq_exti3, __default_handler - .weak __irq_exti4 - .globl __irq_exti4 - .set __irq_exti4, __default_handler - .weak __irq_dma1_channel1 - .globl __irq_dma1_channel1 - .set __irq_dma1_channel1, __default_handler - .weak __irq_dma1_channel2 - .globl __irq_dma1_channel2 - .set __irq_dma1_channel2, __default_handler - .weak __irq_dma1_channel3 - .globl __irq_dma1_channel3 - .set __irq_dma1_channel3, __default_handler - .weak __irq_dma1_channel4 - .globl __irq_dma1_channel4 - .set __irq_dma1_channel4, __default_handler - .weak __irq_dma1_channel5 - .globl __irq_dma1_channel5 - .set __irq_dma1_channel5, __default_handler - .weak __irq_dma1_channel6 - .globl __irq_dma1_channel6 - .set __irq_dma1_channel6, __default_handler - .weak __irq_dma1_channel7 - .globl __irq_dma1_channel7 - .set __irq_dma1_channel7, __default_handler - .weak __irq_adc - .globl __irq_adc - .set __irq_adc, __default_handler +// .weak __irq_exti0 // __irq_exti0() defined in STM32F1/cores/maple/libmaple/exti.c +// .globl __irq_exti0 +// .set __irq_exti0, __default_handler +// .weak __irq_exti1 // __irq_exti1() defined in STM32F1/cores/maple/libmaple/exti.c +// .globl __irq_exti1 +// .set __irq_exti1, __default_handler +// .weak __irq_exti2 // __irq_exti2() defined in STM32F1/cores/maple/libmaple/exti.c +// .globl __irq_exti2 +// .set __irq_exti2, __default_handler +// .weak __irq_exti3 // __irq_exti3() defined in STM32F1/cores/maple/libmaple/exti.c +// .globl __irq_exti3 +// .set __irq_exti3, __default_handler +// .weak __irq_exti4 // __irq_exti4() defined in STM32F1/cores/maple/libmaple/exti.c +// .globl __irq_exti4 +// .set __irq_exti4, __default_handler +// .weak __irq_dma1_channel1 // __irq_dma1_channel1() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma1_channel1 +// .set __irq_dma1_channel1, __default_handler +// .weak __irq_dma1_channel2 // __irq_dma1_channel2() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma1_channel2 +// .set __irq_dma1_channel2, __default_handler +// .weak __irq_dma1_channel3 // __irq_dma1_channel3() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma1_channel3 +// .set __irq_dma1_channel3, __default_handler +// .weak __irq_dma1_channel4 // __irq_dma1_channel4() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma1_channel4 +// .set __irq_dma1_channel4, __default_handler +// .weak __irq_dma1_channel5 // __irq_dma1_channel5() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma1_channel5 +// .set __irq_dma1_channel5, __default_handler +// .weak __irq_dma1_channel6 // __irq_dma1_channel6() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma1_channel6 +// .set __irq_dma1_channel6, __default_handler +// .weak __irq_dma1_channel7 // __irq_dma1_channel7() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma1_channel7 +// .set __irq_dma1_channel7, __default_handler +// .weak __irq_adc // __irq_adc() defined in STM32F1/cores/maple/libmaple/adc_f1.c +// .globl __irq_adc +// .set __irq_adc, __default_handler .weak __irq_usb_hp_can_tx .globl __irq_usb_hp_can_tx .set __irq_usb_hp_can_tx, __default_handler - .weak __irq_usb_lp_can_rx0 - .globl __irq_usb_lp_can_rx0 - .set __irq_usb_lp_can_rx0, __default_handler +// .weak __irq_usb_lp_can_rx0 // __irq_usb_lp_can_rx0() defined in STM32F1/cores/maple/libmaple/usb/stm32f1/usb.c +// .globl __irq_usb_lp_can_rx0 +// .set __irq_usb_lp_can_rx0, __default_handler .weak __irq_can_rx1 .globl __irq_can_rx1 .set __irq_can_rx1, __default_handler .weak __irq_can_sce .globl __irq_can_sce .set __irq_can_sce, __default_handler - .weak __irq_exti9_5 - .globl __irq_exti9_5 - .set __irq_exti9_5, __default_handler - .weak __irq_tim1_brk - .globl __irq_tim1_brk - .set __irq_tim1_brk, __default_handler - .weak __irq_tim1_up - .globl __irq_tim1_up - .set __irq_tim1_up, __default_handler - .weak __irq_tim1_trg_com - .globl __irq_tim1_trg_com - .set __irq_tim1_trg_com, __default_handler - .weak __irq_tim1_cc - .globl __irq_tim1_cc - .set __irq_tim1_cc, __default_handler - - .weakref __irq_tim2, __default_handler - .globl __irq_tim2 - .weakref __irq_tim3, __default_handler - .globl __irq_tim3 - .weakref __irq_tim4, __default_handler - .globl __irq_tim4 - - .weak __irq_i2c1_ev - .globl __irq_i2c1_ev - .set __irq_i2c1_ev, __default_handler - .weak __irq_i2c1_er - .globl __irq_i2c1_er - .set __irq_i2c1_er, __default_handler - .weak __irq_i2c2_ev - .globl __irq_i2c2_ev - .set __irq_i2c2_ev, __default_handler - .weak __irq_i2c2_er - .globl __irq_i2c2_er - .set __irq_i2c2_er, __default_handler +// .weak __irq_exti9_5 // __irq_exti9_5() defined in STM32F1/cores/maple/libmaple/exti.c +// .globl __irq_exti9_5 +// .set __irq_exti9_5, __default_handler +// .weak __irq_tim1_brk // __irq_tim1_brk() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim1_brk +// .set __irq_tim1_brk, __default_handler +// .weak __irq_tim1_up // __irq_tim1_up() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim1_up +// .set __irq_tim1_up, __default_handler +// .weak __irq_tim1_trg_com // __irq_tim1_trg_com() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim1_trg_com +// .set __irq_tim1_trg_com, __default_handler +// .weak __irq_tim1_cc // __irq_tim1_cc() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim1_cc +// .set __irq_tim1_cc, __default_handler +// +// .weakref __irq_tim2, __default_handler // __irq_tim2() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim2 +// .weakref __irq_tim3, __default_handler // __irq_tim3() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim3 +// .weakref __irq_tim4, __default_handler // __irq_tim4() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim4 +// +// .weak __irq_i2c1_ev // __irq_i2c1_ev() defined in STM32F1/cores/maple/libmaple/i2c_f1.c +// .globl __irq_i2c1_ev +// .set __irq_i2c1_ev, __default_handler +// .weak __irq_i2c1_er // __irq_i2c1_er() defined in STM32F1/cores/maple/libmaple/i2c_f1.c +// .globl __irq_i2c1_er +// .set __irq_i2c1_er, __default_handler +// .weak __irq_i2c2_ev // __irq_i2c2_ev() defined in STM32F1/cores/maple/libmaple/i2c_f1.c +// .globl __irq_i2c2_ev +// .set __irq_i2c2_ev, __default_handler +// .weak __irq_i2c2_er // __irq_i2c2_er() defined in STM32F1/cores/maple/libmaple/i2c_f1.c +// .globl __irq_i2c2_er +// .set __irq_i2c2_er, __default_handler .weak __irq_spi1 .globl __irq_spi1 .set __irq_spi1, __default_handler .weak __irq_spi2 .globl __irq_spi2 .set __irq_spi2, __default_handler - .weak __irq_usart1 - .globl __irq_usart1 - .set __irq_usart1, __default_handler - .weak __irq_usart2 - .globl __irq_usart2 - .set __irq_usart2, __default_handler - .weak __irq_usart3 - .globl __irq_usart3 - .set __irq_usart3, __default_handler - .weak __irq_exti15_10 - .globl __irq_exti15_10 - .set __irq_exti15_10, __default_handler +// .weak __irq_usart1 // __irq_usart1() defined in STM32F1/cores/maple/libmaple/usart_f1.c +// .globl __irq_usart1 +// .set __irq_usart1, __default_handler +// .weak __irq_usart2 // __irq_usart2() defined in STM32F1/cores/maple/libmaple/usart_f1.c +// .globl __irq_usart2 +// .set __irq_usart2, __default_handler +// .weak __irq_usart3 // __irq_usart3() defined in STM32F1/cores/maple/libmaple/usart_f1.c +// .globl __irq_usart3 +// .set __irq_usart3, __default_handler +// .weak __irq_exti15_10 // __irq_exti15_10() defined in STM32F1/cores/maple/libmaple/exti.c +// .globl __irq_exti15_10 +// .set __irq_exti15_10, __default_handler .weak __irq_rtcalarm .globl __irq_rtcalarm .set __irq_rtcalarm, __default_handler @@ -208,55 +208,55 @@ __default_handler: .globl __irq_usbwakeup .set __irq_usbwakeup, __default_handler #if defined (STM32_HIGH_DENSITY) - .weak __irq_tim8_brk - .globl __irq_tim8_brk - .set __irq_tim8_brk, __default_handler - .weak __irq_tim8_up - .globl __irq_tim8_up - .set __irq_tim8_up, __default_handler - .weak __irq_tim8_trg_com - .globl __irq_tim8_trg_com - .set __irq_tim8_trg_com, __default_handler - .weak __irq_tim8_cc - .globl __irq_tim8_cc - .set __irq_tim8_cc, __default_handler - .weak __irq_adc3 - .globl __irq_adc3 - .set __irq_adc3, __default_handler +// .weak __irq_tim8_brk // __irq_tim8_brk() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim8_brk +// .set __irq_tim8_brk, __default_handler +// .weak __irq_tim8_up // __irq_tim8_up() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim8_up +// .set __irq_tim8_up, __default_handler +// .weak __irq_tim8_trg_com // __irq_tim8_trg_com() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim8_trg_com +// .set __irq_tim8_trg_com, __default_handler +// .weak __irq_tim8_cc // __irq_tim8_cc() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim8_cc +// .set __irq_tim8_cc, __default_handler +// .weak __irq_adc3 // __irq_adc3() defined in STM32F1/cores/maple/libmaple/adc_f1.c +// .globl __irq_adc3 +// .set __irq_adc3, __default_handler .weak __irq_fsmc .globl __irq_fsmc .set __irq_fsmc, __default_handler .weak __irq_sdio .globl __irq_sdio .set __irq_sdio, __default_handler - .weak __irq_tim5 - .globl __irq_tim5 - .set __irq_tim5, __default_handler +// .weak __irq_tim5 // __irq_tim5() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim5 +// .set __irq_tim5, __default_handler .weak __irq_spi3 .globl __irq_spi3 .set __irq_spi3, __default_handler - .weak __irq_uart4 - .globl __irq_uart4 - .set __irq_uart4, __default_handler - .weak __irq_uart5 - .globl __irq_uart5 - .set __irq_uart5, __default_handler - .weak __irq_tim6 - .globl __irq_tim6 - .set __irq_tim6, __default_handler - .weak __irq_tim7 - .globl __irq_tim7 - .set __irq_tim7, __default_handler - .weak __irq_dma2_channel1 - .globl __irq_dma2_channel1 - .set __irq_dma2_channel1, __default_handler - .weak __irq_dma2_channel2 - .globl __irq_dma2_channel2 - .set __irq_dma2_channel2, __default_handler - .weak __irq_dma2_channel3 - .globl __irq_dma2_channel3 - .set __irq_dma2_channel3, __default_handler - .weak __irq_dma2_channel4_5 - .globl __irq_dma2_channel4_5 - .set __irq_dma2_channel4_5, __default_handler +// .weak __irq_uart4 // __irq_uart4() defined in STM32F1/cores/maple/libmaple/usart_f1.c +// .globl __irq_uart4 +// .set __irq_uart4, __default_handler +// .weak __irq_uart5 // __irq_uart5() defined in STM32F1/cores/maple/libmaple/usart_f1.c +// .globl __irq_uart5 +// .set __irq_uart5, __default_handler +// .weak __irq_tim6 // __irq_tim6() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim6 +// .set __irq_tim6, __default_handler +// .weak __irq_tim7 // __irq_tim7() defined in STM32F1/cores/maple/libmaple/timer.c +// .globl __irq_tim7 +// .set __irq_tim7, __default_handler +// .weak __irq_dma2_channel1 // __irq_dma2_channel1() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma2_channel1 +// .set __irq_dma2_channel1, __default_handler +// .weak __irq_dma2_channel2 // __irq_dma2_channel2() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma2_channel2 +// .set __irq_dma2_channel2, __default_handler +// .weak __irq_dma2_channel3 // __irq_dma2_channel3() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma2_channel3 +// .set __irq_dma2_channel3, __default_handler +// .weak __irq_dma2_channel4_5 // __irq_dma2_channel4_5() defined in STM32F1/cores/maple/libmaple/dma_f1.c +// .globl __irq_dma2_channel4_5 +// .set __irq_dma2_channel4_5, __default_handler #endif /* STM32_HIGH_DENSITY */ \ No newline at end of file diff --git a/STM32F1/cores/maple/libmaple/systick.c b/STM32F1/cores/maple/libmaple/systick.c index 7568abe06..1ac92f18f 100644 --- a/STM32F1/cores/maple/libmaple/systick.c +++ b/STM32F1/cores/maple/libmaple/systick.c @@ -80,7 +80,7 @@ void systick_attach_callback(void (*callback)(void)) { * SysTick ISR */ -void __exc_systick(void) { +__weak void __exc_systick(void) { systick_uptime_millis++; if (systick_user_callback) { systick_user_callback(); diff --git a/STM32F1/cores/maple/libmaple/timer.c b/STM32F1/cores/maple/libmaple/timer.c index 70e20654c..5f124301a 100644 --- a/STM32F1/cores/maple/libmaple/timer.c +++ b/STM32F1/cores/maple/libmaple/timer.c @@ -40,7 +40,6 @@ static void pwm_mode(timer_dev *dev, uint8 channel); static void output_compare_mode(timer_dev *dev, uint8 channel); static void encoder_mode(timer_dev *dev, uint8 channel) ;//CARLOS - static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid); /* @@ -236,6 +235,9 @@ void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) { case TIMER_ENCODER: encoder_mode(dev, channel); //find a way to pass all the needed stuff on the 8bit var break; + case TIMER_INPUT_CAPTURE:// code from @Cesco + input_capture_mode(dev, channel, TIMER_IC_INPUT_DEFAULT); + break; } } @@ -349,7 +351,10 @@ static void encoder_mode(timer_dev *dev, uint8 channel __attribute__((unused))) timer_resume(dev); } - +void input_capture_mode(timer_dev *dev, uint8 channel, timer_ic_input_select input) { + timer_oc_set_mode(dev, channel, 0, input); + timer_cc_enable(dev, channel); +} static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id); static void enable_bas_gen_irq(timer_dev *dev); @@ -473,78 +478,78 @@ static void enable_bas_gen_irq(timer_dev *dev) { * file. */ -void __irq_tim1_brk(void) { +__weak void __irq_tim1_brk(void) { dispatch_adv_brk(TIMER1); #if STM32_HAVE_TIMER(9) dispatch_tim_9_12(TIMER9); #endif } -void __irq_tim1_up(void) { +__weak void __irq_tim1_up(void) { dispatch_adv_up(TIMER1); #if STM32_HAVE_TIMER(10) dispatch_tim_10_11_13_14(TIMER10); #endif } -void __irq_tim1_trg_com(void) { +__weak void __irq_tim1_trg_com(void) { dispatch_adv_trg_com(TIMER1); #if STM32_HAVE_TIMER(11) dispatch_tim_10_11_13_14(TIMER11); #endif } -void __irq_tim1_cc(void) { +__weak void __irq_tim1_cc(void) { dispatch_adv_cc(TIMER1); } -void __irq_tim2(void) { +__weak void __irq_tim2(void) { dispatch_general(TIMER2); } -void __irq_tim3(void) { +__weak void __irq_tim3(void) { dispatch_general(TIMER3); } -void __irq_tim4(void) { +__weak void __irq_tim4(void) { dispatch_general(TIMER4); } #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) -void __irq_tim5(void) { +__weak void __irq_tim5(void) { dispatch_general(TIMER5); } -void __irq_tim6(void) { +__weak void __irq_tim6(void) { dispatch_basic(TIMER6); } -void __irq_tim7(void) { +__weak void __irq_tim7(void) { dispatch_basic(TIMER7); } -void __irq_tim8_brk(void) { +__weak void __irq_tim8_brk(void) { dispatch_adv_brk(TIMER8); #if STM32_HAVE_TIMER(12) dispatch_tim_9_12(TIMER12); #endif } -void __irq_tim8_up(void) { +__weak void __irq_tim8_up(void) { dispatch_adv_up(TIMER8); #if STM32_HAVE_TIMER(13) dispatch_tim_10_11_13_14(TIMER13); #endif } -void __irq_tim8_trg_com(void) { +__weak void __irq_tim8_trg_com(void) { dispatch_adv_trg_com(TIMER8); #if STM32_HAVE_TIMER(14) dispatch_tim_10_11_13_14(TIMER14); #endif } -void __irq_tim8_cc(void) { +__weak void __irq_tim8_cc(void) { dispatch_adv_cc(TIMER8); } #endif /* defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) */ \ No newline at end of file diff --git a/STM32F1/cores/maple/libmaple/usart_f1.c b/STM32F1/cores/maple/libmaple/usart_f1.c index 2b590fc74..30ce000fe 100644 --- a/STM32F1/cores/maple/libmaple/usart_f1.c +++ b/STM32F1/cores/maple/libmaple/usart_f1.c @@ -200,24 +200,24 @@ void usart_foreach(void (*fn)(usart_dev*)) { * Interrupt handlers. */ -void __irq_usart1(void) { +__weak void __irq_usart1(void) { usart_irq(&usart1_rb, &usart1_wb, USART1_BASE); } -void __irq_usart2(void) { +__weak void __irq_usart2(void) { usart_irq(&usart2_rb, &usart2_wb, USART2_BASE); } -void __irq_usart3(void) { +__weak void __irq_usart3(void) { usart_irq(&usart3_rb, &usart3_wb, USART3_BASE); } #ifdef STM32_HIGH_DENSITY -void __irq_uart4(void) { +__weak void __irq_uart4(void) { usart_irq(&uart4_rb, &uart4_wb, UART4_BASE); } -void __irq_uart5(void) { +__weak void __irq_uart5(void) { usart_irq(&uart5_rb, &uart5_wb, UART5_BASE); } #endif diff --git a/STM32F1/cores/maple/libmaple/usb/stm32f1/usb.c b/STM32F1/cores/maple/libmaple/usb/stm32f1/usb.c index f837eb64b..d6f72b04c 100644 --- a/STM32F1/cores/maple/libmaple/usb/stm32f1/usb.c +++ b/STM32F1/cores/maple/libmaple/usb/stm32f1/usb.c @@ -120,6 +120,12 @@ static void usb_suspend(void) { USBLIB->state = USB_SUSPENDED; } +void usb_power_off(void) { + USB_BASE->CNTR = USB_CNTR_FRES; + USB_BASE->ISTR = 0; + USB_BASE->CNTR = USB_CNTR_FRES + USB_CNTR_PDWN; +} + static void usb_resume_init(void) { uint16 cntr; @@ -183,10 +189,25 @@ static void usb_resume(RESUME_STATE eResumeSetVal) { } } +// JMD : default ISRs of CAN, to be overridden if HardwareCAN library is used in sketch +void __attribute__((weak)) USB_HP_CAN_TX_IRQHandler(void) +{ ; } // Dummy ISR + +void __irq_usb_hp_can_tx(void) +{ + USB_HP_CAN_TX_IRQHandler () ; +} + +uint8 __attribute__((weak)) CAN_RX0_IRQ_Handler(void) +{ return 0 ; } // Dummy ISR + #define SUSPEND_ENABLED 1 -void __irq_usb_lp_can_rx0(void) { +__weak void __irq_usb_lp_can_rx0(void) { uint16 istr = USB_BASE->ISTR; + if (CAN_RX0_IRQ_Handler()) //! JMD : Call to CAN ISR, returns 1 CAN is active + return; //! JMD + /* Use USB_ISR_MSK to only include code for bits we care about. */ #if (USB_ISR_MSK & USB_ISTR_RESET) @@ -268,6 +289,7 @@ static void handle_out0(void); static void dispatch_ctr_lp() { uint16 istr; + while (((istr = USB_BASE->ISTR) & USB_ISTR_CTR) != 0) { /* TODO WTF, figure this out: RM0008 says CTR is read-only, * but ST's firmware claims it's clear-only, and emphasizes @@ -288,6 +310,7 @@ static void dispatch_ctr_lp() { } } + /* FIXME Dataflow on endpoint 0 RX/TX status is based off of ST's * code, and is ugly/confusing in its use of SaveRState/SaveTState. * Fixing this requires filling in handle_in0(), handle_setup0(), diff --git a/STM32F1/cores/maple/libmaple/usb/stm32f1/usb_cdcacm.c b/STM32F1/cores/maple/libmaple/usb/stm32f1/usb_cdcacm.c index cba050f54..5ffaa229a 100644 --- a/STM32F1/cores/maple/libmaple/usb/stm32f1/usb_cdcacm.c +++ b/STM32F1/cores/maple/libmaple/usb/stm32f1/usb_cdcacm.c @@ -62,7 +62,7 @@ #if !(defined(BOARD_maple) || defined(BOARD_maple_RET6) || \ defined(BOARD_maple_mini) || defined(BOARD_maple_native)) -//#warning USB CDC ACM relies on LeafLabs board-specific configuration.\ +//#warning USB CDC ACM relies on LeafLabs board-specific configuration. // You may have problems on non-LeafLabs boards. #endif @@ -80,7 +80,6 @@ static uint8* usbGetConfigDescriptor(uint16 length); static uint8* usbGetStringDescriptor(uint16 length); static void usbSetConfiguration(void); static void usbSetDeviceAddress(void); - /* * Descriptors */ @@ -392,6 +391,8 @@ void usb_cdcacm_enable(gpio_dev *disc_dev, uint8 disc_bit) { } /* Initialize the USB peripheral. */ + /* One of the callbacks that will automatically happen from this will be to usbInit(), + which will power up the USB peripheral. */ usb_init_usblib(USBLIB, ep_int_in, ep_int_out); } @@ -403,6 +404,9 @@ void usb_cdcacm_disable(gpio_dev *disc_dev, uint8 disc_bit) { { gpio_write_bit(disc_dev, disc_bit, 1); } + /* Powerdown the USB peripheral. It gets powered up again with usbInit(), which + gets called when usb_cdcacm_enable() is called. */ + usb_power_off(); } void usb_cdcacm_putc(char ch) { @@ -452,6 +456,11 @@ uint8 usb_cdcacm_is_transmitting(void) { return ( transmitting>0 ? transmitting : 0); } +int usb_cdcacm_tx_available() +{ + return CDC_SERIAL_TX_BUFFER_SIZE - usb_cdcacm_get_pending() - 1; +} + uint16 usb_cdcacm_get_pending(void) { return (tx_head - tx_tail) & CDC_SERIAL_TX_BUFFER_SIZE_MASK; } @@ -483,9 +492,9 @@ uint32 usb_cdcacm_rx(uint8* buf, uint32 len) * Looks at unread bytes without marking them as read. */ uint32 usb_cdcacm_peek(uint8* buf, uint32 len) { - int i; + uint32 i; uint32 tail = rx_tail; - uint32 rx_unread = (rx_head-tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + uint32 rx_unread = (rx_head-tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; if (len > rx_unread) { len = rx_unread; @@ -501,12 +510,12 @@ uint32 usb_cdcacm_peek(uint8* buf, uint32 len) uint32 usb_cdcacm_peek_ex(uint8* buf, uint32 offset, uint32 len) { - int i; + uint32 i; uint32 tail = (rx_tail + offset) & CDC_SERIAL_RX_BUFFER_SIZE_MASK ; - uint32 rx_unread = (rx_head-tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + uint32 rx_unread = (rx_head - tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; - if (len + offset > rx_unread) { - len = rx_unread - offset; + if (len > rx_unread) { + len = rx_unread; } for (i = 0; i < len; i++) { @@ -579,7 +588,7 @@ static void vcomDataTxCb(void) uint32 *dst = usb_pma_ptr(USB_CDCACM_TX_ADDR); uint16 tmp = 0; uint16 val; - int i; + uint32 i; for (i = 0; i < tx_unsent; i++) { val = vcomBufferTx[tail]; tail = (tail + 1) & CDC_SERIAL_TX_BUFFER_SIZE_MASK; @@ -644,7 +653,8 @@ static uint8* vcomGetSetLineCoding(uint16 length) { static void usbInit(void) { pInformation->Current_Configuration = 0; - USB_BASE->CNTR = USB_CNTR_FRES; + // Reset and power up the peripheral. + USB_BASE->CNTR = USB_CNTR_FRES; USBLIB->irq_mask = 0; USB_BASE->CNTR = USBLIB->irq_mask; diff --git a/STM32F1/cores/maple/libmaple/usb/stm32f1/usb_reg_map.c b/STM32F1/cores/maple/libmaple/usb/stm32f1/usb_reg_map.c index 3f5446aa6..17cdab04a 100644 --- a/STM32F1/cores/maple/libmaple/usb/stm32f1/usb_reg_map.c +++ b/STM32F1/cores/maple/libmaple/usb/stm32f1/usb_reg_map.c @@ -66,14 +66,14 @@ static void usb_set_ep_rx_count_common(uint32 *rxc, uint16 count) { if ((count & 0x1F) == 0) { nblocks--; } - *rxc = (nblocks << 10) | 0x8000; + *rxc = (nblocks << 10) | 0x8000 | (count & 0x3FF); } else { /* use 2-byte memory block size */ nblocks = count >> 1; if ((count & 0x1) != 0) { nblocks++; } - *rxc = nblocks << 10; + *rxc = (nblocks << 10) | (count & 0x3FF); } } /* diff --git a/STM32F1/cores/maple/libmaple/usb/usb_lib/usb_mem.c b/STM32F1/cores/maple/libmaple/usb/usb_lib/usb_mem.c index ad9740a18..113e7e1cd 100644 --- a/STM32F1/cores/maple/libmaple/usb/usb_lib/usb_mem.c +++ b/STM32F1/cores/maple/libmaple/usb/usb_lib/usb_mem.c @@ -59,14 +59,15 @@ void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) *******************************************************************************/ void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) { - u32 n = (wNBytes + 1) >> 1;/* /2*/ - u32 i; - u32 *pdwVal; - pdwVal = (u32 *)(wPMABufAddr * 2 + PMAAddr); - for (i = n; i != 0; i--) + u16 * destPtr = (u16*)pbUsrBuf; + u32 * pdwVal = (u32 *)(wPMABufAddr * 2 + PMAAddr); + for (u16 i = wNBytes/2; i > 0; i--) { - *(u16*)pbUsrBuf++ = *pdwVal++; - pbUsrBuf++; + *destPtr++ = (u16)*pdwVal++; + } + if (wNBytes & 0x1) // odd value ? + { + *(u8*)destPtr = *(u8*)pdwVal; } } diff --git a/STM32F1/cores/maple/sdio.cpp b/STM32F1/cores/maple/sdio.cpp index 8bd94915b..d9b18f420 100644 --- a/STM32F1/cores/maple/sdio.cpp +++ b/STM32F1/cores/maple/sdio.cpp @@ -32,8 +32,8 @@ sdio_dev * SDIO = SDIO_BASE; -#define DELAY_LONG 10 -#define DELAY_SHORT 1 +#define DELAY_LONG 20 +#define DELAY_SHORT 2 uint8_t dly = DELAY_LONG; // microseconds delay after accessing registers @@ -43,9 +43,13 @@ uint8_t dly = DELAY_LONG; // microseconds delay after accessing registers void sdio_gpios_init(void) { gpio_set_mode(PIN_MAP[BOARD_SDIO_D0].gpio_device, PIN_MAP[BOARD_SDIO_D0].gpio_bit, GPIO_AF_OUTPUT_PP); - gpio_set_mode(PIN_MAP[BOARD_SDIO_D1].gpio_device, PIN_MAP[BOARD_SDIO_D1].gpio_bit, GPIO_AF_OUTPUT_PP); +/* gpio_set_mode(PIN_MAP[BOARD_SDIO_D1].gpio_device, PIN_MAP[BOARD_SDIO_D1].gpio_bit, GPIO_AF_OUTPUT_PP); gpio_set_mode(PIN_MAP[BOARD_SDIO_D2].gpio_device, PIN_MAP[BOARD_SDIO_D2].gpio_bit, GPIO_AF_OUTPUT_PP); gpio_set_mode(PIN_MAP[BOARD_SDIO_D3].gpio_device, PIN_MAP[BOARD_SDIO_D3].gpio_bit, GPIO_AF_OUTPUT_PP); +*/ + gpio_set_mode(PIN_MAP[BOARD_SDIO_D1].gpio_device, PIN_MAP[BOARD_SDIO_D1].gpio_bit, GPIO_INPUT_PU); + gpio_set_mode(PIN_MAP[BOARD_SDIO_D2].gpio_device, PIN_MAP[BOARD_SDIO_D2].gpio_bit, GPIO_INPUT_PU); + gpio_set_mode(PIN_MAP[BOARD_SDIO_D3].gpio_device, PIN_MAP[BOARD_SDIO_D3].gpio_bit, GPIO_INPUT_PU); gpio_set_mode(PIN_MAP[BOARD_SDIO_CLK].gpio_device, PIN_MAP[BOARD_SDIO_CLK].gpio_bit, GPIO_AF_OUTPUT_PP); gpio_set_mode(PIN_MAP[BOARD_SDIO_CMD].gpio_device, PIN_MAP[BOARD_SDIO_CMD].gpio_bit, GPIO_AF_OUTPUT_PP); /* @@ -63,12 +67,12 @@ void sdio_gpios_init(void) void sdio_gpios_deinit(void) { - gpio_set_mode(PIN_MAP[BOARD_SDIO_D0].gpio_device, PIN_MAP[BOARD_SDIO_D0].gpio_bit, GPIO_INPUT_FLOATING); - gpio_set_mode(PIN_MAP[BOARD_SDIO_D1].gpio_device, PIN_MAP[BOARD_SDIO_D1].gpio_bit, GPIO_INPUT_FLOATING); - gpio_set_mode(PIN_MAP[BOARD_SDIO_D2].gpio_device, PIN_MAP[BOARD_SDIO_D2].gpio_bit, GPIO_INPUT_FLOATING); - gpio_set_mode(PIN_MAP[BOARD_SDIO_D3].gpio_device, PIN_MAP[BOARD_SDIO_D3].gpio_bit, GPIO_INPUT_FLOATING); - gpio_set_mode(PIN_MAP[BOARD_SDIO_CLK].gpio_device, PIN_MAP[BOARD_SDIO_CLK].gpio_bit, GPIO_INPUT_FLOATING); - gpio_set_mode(PIN_MAP[BOARD_SDIO_CMD].gpio_device, PIN_MAP[BOARD_SDIO_CMD].gpio_bit, GPIO_INPUT_FLOATING); + gpio_set_mode(PIN_MAP[BOARD_SDIO_D0].gpio_device, PIN_MAP[BOARD_SDIO_D0].gpio_bit, GPIO_INPUT_PU); + gpio_set_mode(PIN_MAP[BOARD_SDIO_D1].gpio_device, PIN_MAP[BOARD_SDIO_D1].gpio_bit, GPIO_INPUT_PU); + gpio_set_mode(PIN_MAP[BOARD_SDIO_D2].gpio_device, PIN_MAP[BOARD_SDIO_D2].gpio_bit, GPIO_INPUT_PU); + gpio_set_mode(PIN_MAP[BOARD_SDIO_D3].gpio_device, PIN_MAP[BOARD_SDIO_D3].gpio_bit, GPIO_INPUT_PU); + gpio_set_mode(PIN_MAP[BOARD_SDIO_CLK].gpio_device, PIN_MAP[BOARD_SDIO_CLK].gpio_bit, GPIO_INPUT_PU); + gpio_set_mode(PIN_MAP[BOARD_SDIO_CMD].gpio_device, PIN_MAP[BOARD_SDIO_CMD].gpio_bit, GPIO_INPUT_PU); /* * Todo just remove it, not needed for F1. @@ -110,19 +114,35 @@ void sdio_power_off(void) void sdio_set_clock(uint32_t clk) { - if (clk>24000000UL) clk = 24000000UL; // limit the SDIO master clock to 24MHz + /* + * limit the SDIO master clock to 8/3 of PCLK2.See RM 22.3 + * Also limited to no more than 48Mhz + */ + clk = min(clk,((uint32_t)SDIOCLK/3)*8); + clk = min(clk,(uint32_t)36000000); if (clk<1000000) dly = DELAY_LONG; else dly = DELAY_SHORT; + /* + * round up divider, so we don't run the card over the speed supported. + + */ + uint32 div = SDIOCLK/clk + (SDIOCLK % clk != 0) - 2; + + sdio_disable(); - SDIO->CLKCR = (SDIO->CLKCR & (~(SDIO_CLKCR_CLKDIV|SDIO_CLKCR_BYPASS))) | SDIO_CLKCR_CLKEN | (((SDIOCLK/clk)-2)&SDIO_CLKCR_CLKDIV); + //Serial.println(div,DEC); + SDIO->CLKCR = (SDIO->CLKCR & (~(SDIO_CLKCR_CLKDIV|SDIO_CLKCR_BYPASS))) | SDIO_CLKCR_PWRSAV | SDIO_CLKCR_HWFC_EN | SDIO_CLKCR_CLKEN | (div & SDIO_CLKCR_CLKDIV); delay_us(dly); } void sdio_set_dbus_width(uint16_t bus_w) { SDIO->CLKCR = (SDIO->CLKCR & (~SDIO_CLKCR_WIDBUS)) | bus_w; + gpio_set_mode(PIN_MAP[BOARD_SDIO_D1].gpio_device, PIN_MAP[BOARD_SDIO_D1].gpio_bit, GPIO_AF_OUTPUT_PP); + gpio_set_mode(PIN_MAP[BOARD_SDIO_D2].gpio_device, PIN_MAP[BOARD_SDIO_D2].gpio_bit, GPIO_AF_OUTPUT_PP); + gpio_set_mode(PIN_MAP[BOARD_SDIO_D3].gpio_device, PIN_MAP[BOARD_SDIO_D3].gpio_bit, GPIO_AF_OUTPUT_PP); delay_us(dly); } @@ -149,9 +169,10 @@ void sdio_disable(void) */ void sdio_begin(void) { - sdio_gpios_init(); + sdio_init(); sdio_power_on(); + sdio_gpios_init(); // Set initial SCK rate. sdio_set_clock(400000); delay_us(200); // generate 80 pulses at 400kHz @@ -162,11 +183,11 @@ void sdio_begin(void) */ void sdio_end(void) { - sdio_disable(); - while ( sdio_cmd_xfer_ongoing() ); + while ( sdio_cmd_xfer_ongoing() ); + sdio_disable(); + sdio_gpios_deinit(); sdio_power_off(); rcc_clk_disable(RCC_SDIO); - sdio_gpios_deinit(); } /** diff --git a/STM32F1/cores/maple/stm32f1/wiring_pulse_f1.cpp b/STM32F1/cores/maple/stm32f1/wiring_pulse_f1.cpp index 5a5d8358e..bb7e2adc4 100644 --- a/STM32F1/cores/maple/stm32f1/wiring_pulse_f1.cpp +++ b/STM32F1/cores/maple/stm32f1/wiring_pulse_f1.cpp @@ -33,7 +33,7 @@ uint32_t pulseIn( uint32_t pin, uint32_t state, uint32_t timeout ) // pulse width measuring loop and achieve finer resolution. calling // digitalRead() instead yields much coarser resolution. - __io uint32_t * const idr = portInputRegister(digitalPinToPort(pin)); + __IO uint32_t * const idr = portInputRegister(digitalPinToPort(pin)); const uint32_t bit = digitalPinToBitMask(pin); const uint32_t stateMask = (state ? bit:0); diff --git a/STM32F1/cores/maple/stm32f1/wirish_debug.cpp b/STM32F1/cores/maple/stm32f1/wirish_debug.cpp index f0576165e..8f6cc98ee 100644 --- a/STM32F1/cores/maple/stm32f1/wirish_debug.cpp +++ b/STM32F1/cores/maple/stm32f1/wirish_debug.cpp @@ -37,5 +37,5 @@ void disableDebugPorts(void) { } void enableDebugPorts(void) { - afio_cfg_debug_ports(AFIO_DEBUG_FULL_SWJ); + afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); } diff --git a/STM32F1/cores/maple/tone.cpp b/STM32F1/cores/maple/tone.cpp index b249a784a..a0448a1ca 100644 --- a/STM32F1/cores/maple/tone.cpp +++ b/STM32F1/cores/maple/tone.cpp @@ -31,7 +31,7 @@ #define TONE_TIMER 8 #endif #ifndef TONE_CHANNEL - #define TONE_CHANNEL 8 + #define TONE_CHANNEL 4 #endif HardwareTimer TTimer1(1), TTimer2(2), TTimer3(3), TTimer4(4),TTimer5(5), TTimer6(6), TTimer7(7), TTimer8(8); @@ -60,7 +60,7 @@ uint8_t tone_ntimer = TONE_TIMER; // timer used to generate freque bool tone_state = true; // last pin state for toggling short tone_pin = -1; // pin for outputting sound short tone_freq = 444; // tone frequency (0=pause) -volatile uint32_t tone_nhw = 0; // tone duration in number of half waves +volatile uint32_t tone_nhw = 0; // tone duration in number of half waves uint16_t tone_tcount = 0; // time between handler calls in 1/36 usec uint16_t tone_ncount = 0; // handler call between toggling uint16_t tone_n = 0; // remaining handler calls before toggling @@ -151,7 +151,7 @@ void tone(uint32_t pin, uint32_t freq, uint32_t duration) { tone_ncount = tone_n = (count>>16)+1; // number of 16-bit count chunk tone_tcount = count/tone_ncount; // size of count chunk if(duration > 0) // number of half waves to be generated - tone_nhw = ((duration*freq)/1000)<<1; + tone_nhw = duration*freq*2/1000; else // no duration specified, continuous sound until noTone() called tone_nhw = 0; diff --git a/STM32F1/cores/maple/usb_serial.cpp b/STM32F1/cores/maple/usb_serial.cpp index e6d5cb0e5..08e8a0de4 100644 --- a/STM32F1/cores/maple/usb_serial.cpp +++ b/STM32F1/cores/maple/usb_serial.cpp @@ -37,7 +37,7 @@ #include #include #include - +#include #include "wirish.h" /* @@ -56,6 +56,7 @@ static void ifaceSetupHook(unsigned, void*); #define USB_TIMEOUT 50 #if BOARD_HAVE_SERIALUSB bool USBSerial::_hasBegun = false; +bool USBSerial::_isBlocking = false; #endif USBSerial::USBSerial(void) { @@ -105,30 +106,37 @@ void USBSerial::end(void) { } size_t USBSerial::write(uint8 ch) { -size_t n = 0; - this->write(&ch, 1); - return n; + + return this->write(&ch, 1); } size_t USBSerial::write(const char *str) { -size_t n = 0; - this->write((const uint8*)str, strlen(str)); - return n; + return this->write((const uint8*)str, strlen(str)); } size_t USBSerial::write(const uint8 *buf, uint32 len) { -size_t n = 0; - if (!(bool) *this || !buf) { +#ifdef USB_SERIAL_REQUIRE_DTR + if (!(bool) *this || !buf) { return 0; } +#else + if (!buf || !(usb_is_connected(USBLIB) && usb_is_configured(USBLIB))) { + return 0; + } +#endif uint32 txed = 0; - while (txed < len) { - txed += usb_cdcacm_tx((const uint8*)buf + txed, len - txed); - } + if (!_isBlocking) { + txed = usb_cdcacm_tx((const uint8*)buf + txed, len - txed); + } + else { + while (txed < len) { + txed += usb_cdcacm_tx((const uint8*)buf + txed, len - txed); + } + } - return n; + return txed; } int USBSerial::available(void) { @@ -148,6 +156,8 @@ int USBSerial::peek(void) } } +int USBSerial::availableForWrite(void) { return usb_cdcacm_tx_available(); } + void USBSerial::flush(void) { /*Roger Clark. Rather slow method. Need to improve this */ @@ -184,10 +194,6 @@ size_t USBSerial::readBytes(char *buf, const size_t& len) /* Blocks forever until 1 byte is received */ int USBSerial::read(void) { uint8 b; - /* - this->read(&b, 1); - return b; - */ if (usb_cdcacm_rx(&b, 1)==0) { @@ -215,6 +221,16 @@ USBSerial::operator bool() { return usb_is_connected(USBLIB) && usb_is_configured(USBLIB) && usb_cdcacm_get_dtr(); } +void USBSerial::enableBlockingTx(void) +{ + _isBlocking=true; +} +void USBSerial::disableBlockingTx(void) +{ + _isBlocking=false; +} + + #if BOARD_HAVE_SERIALUSB #ifdef SERIAL_USB USBSerial Serial; @@ -264,96 +280,41 @@ static void ifaceSetupHook(unsigned hook __attribute__((unused)), void *requestv } #endif -#if defined(BOOTLOADER_robotis) - uint8 dtr = usb_cdcacm_get_dtr(); - uint8 rts = usb_cdcacm_get_rts(); - - if (rts && !dtr) { - reset_state = DTR_NEGEDGE; - } -#endif - - if ((usb_cdcacm_get_baud() == 1200) && (reset_state == DTR_NEGEDGE)) { - iwdg_init(IWDG_PRE_4, 10); - while (1); - } -} - -#define RESET_DELAY 100000 -#ifdef SERIAL_USB -static void wait_reset(void) { - delay_us(RESET_DELAY); - nvic_sys_reset(); } -#endif -#define STACK_TOP 0x20000800 -#define EXC_RETURN 0xFFFFFFF9 -#define DEFAULT_CPSR 0x61000000 static void rxHook(unsigned hook __attribute__((unused)), void *ignored __attribute__((unused))) { +static const uint8 magic[4] = {'1', 'E', 'A', 'F'}; /* FIXME this is mad buggy; we need a new reset sequence. E.g. NAK * after each RX means you can't reset if any bytes are waiting. */ if (reset_state == DTR_NEGEDGE) { - reset_state = DTR_LOW; - - if (usb_cdcacm_data_available() >= 4) { - // The magic reset sequence is "1EAF". -#ifdef SERIAL_USB - static const uint8 magic[4] = {'1', 'E', 'A', 'F'}; -#else - #if defined(BOOTLOADER_robotis) - static const uint8 magic[4] = {'C', 'M', '9', 'X'}; - #else - static const uint8 magic[4] = {'1', 'E', 'A', 'F'}; - #endif -#endif + if (usb_cdcacm_data_available() >= 4) + { uint8 chkBuf[4]; // Peek at the waiting bytes, looking for reset sequence, // bailing on mismatch. usb_cdcacm_peek_ex(chkBuf, usb_cdcacm_data_available() - 4, 4); for (unsigned i = 0; i < sizeof(magic); i++) { - if (chkBuf[i] != magic[i]) { + if (chkBuf[i] != magic[i]) + { + reset_state = DTR_LOW; return; } } #ifdef SERIAL_USB + // The magic reset sequence is "1EAF". // Got the magic sequence -> reset, presumably into the bootloader. - // Return address is wait_reset, but we must set the thumb bit. - uintptr_t target = (uintptr_t)wait_reset | 0x1; - asm volatile("mov r0, %[stack_top] \n\t" // Reset stack - "mov sp, r0 \n\t" - "mov r0, #1 \n\t" - "mov r1, %[target_addr] \n\t" - "mov r2, %[cpsr] \n\t" - "push {r2} \n\t" // Fake xPSR - "push {r1} \n\t" // PC target addr - "push {r0} \n\t" // Fake LR - "push {r0} \n\t" // Fake R12 - "push {r0} \n\t" // Fake R3 - "push {r0} \n\t" // Fake R2 - "push {r0} \n\t" // Fake R1 - "push {r0} \n\t" // Fake R0 - "mov lr, %[exc_return] \n\t" - "bx lr" - : - : [stack_top] "r" (STACK_TOP), - [target_addr] "r" (target), - [exc_return] "r" (EXC_RETURN), - [cpsr] "r" (DEFAULT_CPSR) - : "r0", "r1", "r2"); + bkp_init(); + bkp_enable_writes(); + bkp_write(10, 0x424C); + bkp_disable_writes(); + nvic_sys_reset(); #endif - -#if defined(BOOTLOADER_robotis) - iwdg_init(IWDG_PRE_4, 10); -#endif - /* Can't happen. */ ASSERT_FAULT(0); } } } - -#endif // BOARD_HAVE_SERIALUSB +#endif // BOARD_HAVE_SERIALUSB \ No newline at end of file diff --git a/STM32F1/cores/maple/usb_serial.h b/STM32F1/cores/maple/usb_serial.h index 835159370..0ff8bd1c8 100644 --- a/STM32F1/cores/maple/usb_serial.h +++ b/STM32F1/cores/maple/usb_serial.h @@ -69,6 +69,10 @@ class USBSerial : public Stream { uint8 getRTS(); uint8 getDTR(); uint8 pending(); + + + void enableBlockingTx(void); + void disableBlockingTx(void); /* SukkoPera: This is the Arduino way to check if an USB CDC serial * connection is open. @@ -85,6 +89,7 @@ class USBSerial : public Stream { protected: static bool _hasBegun; + static bool _isBlocking; }; #ifdef SERIAL_USB diff --git a/STM32F1/cores/maple/wiring_pulse.h b/STM32F1/cores/maple/wiring_pulse.h index abc2463d3..c369aa0ec 100644 --- a/STM32F1/cores/maple/wiring_pulse.h +++ b/STM32F1/cores/maple/wiring_pulse.h @@ -33,5 +33,6 @@ uint32_t pulseIn( uint32_t ulPin, uint32_t ulState, uint32_t ulTimeout = 1000000L ) ; +#define pulseInLong pulseIn #endif diff --git a/STM32F1/cores/maple/wirish.h b/STM32F1/cores/maple/wirish.h index eb07c771c..78593978f 100644 --- a/STM32F1/cores/maple/wirish.h +++ b/STM32F1/cores/maple/wirish.h @@ -40,7 +40,8 @@ */ #include #include - +#include +#include #include @@ -48,6 +49,7 @@ #include #include #include +#include "itoa.h" #include @@ -55,36 +57,36 @@ #include #include #include + +#ifdef __cplusplus #include #include #include -#include #include #include -#if STM32_MCU_SERIES == STM32_SERIES_F1 /* FIXME [0.0.13?] port to F2 */ -//#include -#endif +#include +#include #include #include #include +#endif // __cplusplus + #include +#include #include -#include - -#include -#include - typedef unsigned int word; // typedef uint16 word;// definition from Arduino website, now appears to be incorrect for 32 bit devices /* Wiring macros and bit defines */ +#ifndef true #define true 0x1 #define false 0x0 +#endif #define lowByte(w) ((w) & 0xFF) #define highByte(w) (((w) >> 8) & 0xFF) diff --git a/STM32F1/cores/maple/wirish_math.h b/STM32F1/cores/maple/wirish_math.h index b85253fb5..ab02e0690 100644 --- a/STM32F1/cores/maple/wirish_math.h +++ b/STM32F1/cores/maple/wirish_math.h @@ -47,7 +47,7 @@ void randomSeed(unsigned int seed); * @return A pseudo-random number in the range [0,max). * @see randomSeed() */ -long random(long max); +long random(long max = __LONG_MAX__); /** * @brief Generate a pseudo-random number with lower and upper bounds. @@ -105,8 +105,20 @@ long random(long min, long max); #define SERIAL 0x0 #define DISPLAY 0x1 -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) +#if (__GNUC__ > 4) && defined(__cplusplus) + #include + using namespace std; +#else // C + #include + #ifndef min + #define min(a,b) ((a)<(b)?(a):(b)) + #endif // min + + #ifndef max + #define max(a,b) ((a)>(b)?(a):(b)) + #endif // max +#endif // __cplusplus + #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) #define radians(deg) ((deg)*DEG_TO_RAD) diff --git a/STM32F1/cores/maple/wirish_time.cpp b/STM32F1/cores/maple/wirish_time.cpp index 6404bec15..fb49bd2b5 100644 --- a/STM32F1/cores/maple/wirish_time.cpp +++ b/STM32F1/cores/maple/wirish_time.cpp @@ -34,15 +34,24 @@ #include #include "Arduino.h" -void delay(unsigned long ms) { - uint32 start = millis(); - do - { - yield(); - } - while (millis() - start < ms); +extern "C" { + +void delay(unsigned long ms) +{ + uint32 start = micros(); + while (ms > 0) + { + yield(); + while ( (ms > 0) && ((micros() - start) >= 1000) ) + { + ms--; + start += 1000; + } + } } void delayMicroseconds(uint32 us) { delay_us(us); } + +} // extern "C" \ No newline at end of file diff --git a/STM32F1/cores/maple/wirish_time.h b/STM32F1/cores/maple/wirish_time.h index 1703957de..2ddaed0d9 100644 --- a/STM32F1/cores/maple/wirish_time.h +++ b/STM32F1/cores/maple/wirish_time.h @@ -37,6 +37,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** * Returns time (in milliseconds) since the beginning of program * execution. On overflow, restarts at 0. @@ -94,4 +98,8 @@ void delay(unsigned long ms); */ void delayMicroseconds(uint32 us); +#ifdef __cplusplus +} +#endif + #endif diff --git a/STM32F1/libraries/A_STM32_Examples/examples/Communication/USB-uart-w-signals/USB-uart-w-signals.ino b/STM32F1/libraries/A_STM32_Examples/examples/Communication/USB-uart-w-signals/USB-uart-w-signals.ino new file mode 100644 index 000000000..e9bddbc63 --- /dev/null +++ b/STM32F1/libraries/A_STM32_Examples/examples/Communication/USB-uart-w-signals/USB-uart-w-signals.ino @@ -0,0 +1,347 @@ +/* distribution: MIT lic, ag123*/ +#include "Arduino.h" +#include +#include +#include +#include + +void docmd(); +bool chkcmd(); +void setserial(); +void configserial(); +void bufsend(); + +// bluepill +//#define LED_BUILTIN PC13 + +uint8 ledPin = LED_BUILTIN; +uint8 dtrPin = PB12; +uint8 rtsPin = PB13; + +// this is the character used for the +++ escape sequence +// this would interfere with the escape sequence char of esp8266 +// change this to another character of your preference to prevent issues +#define ESCSEQCHAR '+' + +bool bcmd; +uint8 fsendlf; +uint8 dtr; +uint8 rts; + +#define INVERT(x) (~x)&1 + + +bool bsetlinecoding = false; + +//setup hook flags bsetlinecoding when SET_LINE_CODING is received +static void usbSetupHook(unsigned hook __attribute__((unused)), + void *requestvp) { + uint8 request = *(uint8*)requestvp; + + if (request == USB_CDCACM_SET_LINE_CODING) { + bsetlinecoding = true; + } + return; +} + + +// the setup() method runs once when the sketch starts +void setup() { + //initialize the digital pin as an output: + pinMode(ledPin, OUTPUT); + digitalWrite(ledPin, HIGH); + Serial.begin(); + + //disable DTR checks, note this disable DTR "LEAF" magic sequence + //replace the interface setup hook + usb_cdcacm_set_hooks(USB_CDCACM_HOOK_IFACE_SETUP, &usbSetupHook); + + //AN3155: usart boot loader requires even parity + // but literally those parity stuff is not (yet) implemented in the core + // and somehow it works! ;) + //Serial1.begin(115200,SERIAL_8E1); + Serial1.begin(115200,SERIAL_8N1); + //Serial1.begin(74880,SERIAL_8N1); + bcmd = false; + fsendlf = 1; + + dtr = usb_cdcacm_get_dtr(); + rts = usb_cdcacm_get_rts(); + + pinMode(dtrPin, OUTPUT); + //TTL levels are inverted ! + digitalWrite(dtrPin, INVERT(dtr)); + pinMode(rtsPin, OUTPUT); + digitalWrite(rtsPin, INVERT(rts)); + + +} + + +//the loop() method runs over and over again, +//as long as maple has power +void loop() { + + if(bsetlinecoding) { + //configure uart based on baud and line discipline from host + configserial(); + bsetlinecoding = false; + } + + if (usb_cdcacm_get_dtr() != dtr) { + dtr = INVERT(dtr); + digitalWrite(dtrPin, INVERT(dtr)); + } + + if (usb_cdcacm_get_rts() != rts) { + rts = INVERT(rts); + digitalWrite(rtsPin, INVERT(rts)); + } + + if(Serial1.available()) { + digitalWrite(ledPin, HIGH); // blink the led for traffic + while(Serial1.available()) { + char c = Serial1.read(); + Serial.write(c); + } + digitalWrite(ledPin, LOW); + } + + if(Serial.available()) { + digitalWrite(ledPin, HIGH); // blink the led for traffic + // command processor + chkcmd(); + while(Serial.available()) { + char c = Serial.read(); + Serial1.write(c); + if(c == 13 && fsendlf) Serial1.write(10); + } + } + digitalWrite(ledPin, LOW); + + //delay(1);//sleep for 1ms + asm("wfi"); +} + +static byte cmdline[20]; + +//commands here run after the "+++" +//any non matching commands exits the 'command mode' +//update the commands according to your needs +void docmd() { + uint8_t len = 0; + memset(&cmdline,0,20); + while(true) { + if(Serial.available()) { + char c = Serial.read(); + Serial.write(c); + if(c == '\n' || c == '\r' ) + break; + else if (c == 127 || c == 8) { + len--; + } else { + cmdline[len++] = c; + } + } + asm("wfi"); + } + if(len==0) return; + switch(cmdline[0]) { + case 'R': //reset + digitalWrite(rtsPin, 0); + delay(500); + digitalWrite(rtsPin, 1); + break; + case 'P': //program mode esp-01 gpio0 low + digitalWrite(dtrPin, 0); + break; + case 'p': //run mode esp01 gpio0 high + digitalWrite(dtrPin, 1); + break; + case 'D': //disconnect from AP + Serial1.print("AT+CWQAP\r\n"); + break; + case 'i': //print ip address + Serial1.print("AT+CIFSR\r\n"); + break; + case 'M': //configure MDNS + Serial1.print("AT+MDNS=1,\"esp8266\",\"http\",80\r\n"); + break; + case 'L': //logon to AP L"ssid","password" + Serial1.print("AT+CWJAP_CUR="); + Serial1.print((const char *)(cmdline + 1)); + Serial1.print("\r\n"); + break; + case 'W': //start the server mode + // softAP+station mode + //Serial1.print("AT+CWMODE=3\r\n"); + //enable multi connections + Serial1.print("AT+CIPMUX=1\r\n"); + delay(50); + //enable server + Serial1.print("AT+CIPSERVER=1,80\r\n"); + break; + case 's': //send some characters, s{channel}{message} + //e.g. s0type_your_message, note cmdline is 20-2 chars! + Serial1.print("AT+CIPSEND="); + Serial1.print((char) cmdline[1]); + Serial1.print(','); + Serial1.print(strlen((const char *)(cmdline + 2))); + Serial1.print("\r\n"); + delay(50); + Serial1.print((const char *)(cmdline + 2)); + break; + case 'S': //send S{channel},{length} e.g. S0,100 + Serial1.print("AT+CIPSEND="); + Serial1.print((const char *)(cmdline + 1)); + Serial1.print("\r\n"); + break; + case 'T'://send a bunch of characters, it computes length automatically + //T{channel} e.g. T0 + bufsend(); + break; + case 'c'://close channel c{channel} e.g. c0 + Serial1.print("AT+CIPCLOSE="); + Serial1.print((char) cmdline[1]); + Serial1.print("\r\n"); + break; + case 'k': + fsendlf = INVERT(fsendlf); + Serial.println(fsendlf); + break; + case 'b': + setserial(); + break; + default: + Serial.println("<+++"); + bcmd = false; + } +} + +//configures serial baud and flags from configuration received from host +void configserial() { + uint32 baud = usb_cdcacm_get_baud(); +// Serial.print("baud:"); +// Serial.print(baud); +// Serial.println(); +// Serial.print("bits:"); +// Serial.print(usb_cdcacm_get_n_data_bits()); +// Serial.println(); +// Serial.print("parity:"); +// Serial.print(usb_cdcacm_get_parity()); +// Serial.println(); +// Serial.print("stop:"); +// Serial.print(usb_cdcacm_get_stop_bits()); +// Serial.println(); + //currently the serial line discipline flags are not supported in the core + //hence it is hardcoded as default 8N1! + //only the baud rate is updated + Serial1.begin(baud, SERIAL_8N1); + + //line discipline handling + uint32_t u1cr1 = USART1_BASE->CR1; + uint32_t u1cr2 = USART1_BASE->CR2; + uint8 bits = usb_cdcacm_get_n_data_bits(); + if(bits == 9) + u1cr1 |= USART_CR1_M; + else //8 bits, and all others, zero out M bit + u1cr1 &= ~USART_CR1_M; + + uint8 stop = usb_cdcacm_get_stop_bits(); + //zero out the stop bits, this is 1 stop bits + //this is a 2 bits field + u1cr2 &= ~USART_CR2_STOP; + if(stop == 2) + u1cr2 |= USART_CR2_STOP_BITS_1; + else if (stop == 1) + u1cr2 |= USART_CR2_STOP_BITS_1_POINT_5; + //else 1 stop bits + + uint8 parity = usb_cdcacm_get_parity(); + if(parity == 1) { //odd + u1cr1 |= USART_CR1_PCE; //enable parity + u1cr1 |= USART_CR1_PS_ODD; + } else if (parity == 2) { //even + u1cr1 |= USART_CR1_PCE; //enable parity + u1cr1 &= ~USART_CR1_PS; //zero out PS - even parity + } else { + //zero out parity enable and parity selection + u1cr1 &= ~(USART_CR1_PCE|USART_CR1_PS); + } + USART1_BASE->CR1 = u1cr1; + USART1_BASE->CR2 = u1cr2; + +} + +void setserial() { + uint32 baud = atoi((const char *) (cmdline+1)); + Serial.println(baud); + Serial1.begin(baud, SERIAL_8N1); +} + +//send a bunch of characters, it computes length automatically +//T{channel} e.g. T0 +void bufsend() { + char buf[512]; + uint16_t timeout = 5000; + uint16_t len=0; + + memset(buf,0,512); + while(timeout > 0) { + if(Serial.available()){ + char c = Serial.read(); + buf[len++] = c; + //if(c == 13 && fsendlf) buf[len++] = 10; + Serial.print(c); + } + timeout--; + delay(1); + } + Serial1.print("AT+CIPSEND="); + Serial1.print((char) cmdline[1]); + Serial1.print(','); + Serial1.print(len); + Serial1.print("\r\n"); + delay(50); + for(uint16_t i=0;i`` key (i.e. either carriage return \r or line feed \n ) +an unrecognised command exits 'command mode' (response <+++) + +* R reset (esp8266) +this toggle rtsPIN low for 500ms and bring that back to high + +* P program mode +this toggles dtrPIN low + +* p run mode +this toggles dtrPIN high + +* D disconnect from AP + +* i print ip address + +* M configure MDNS + +* L"ssid","password" logon to AP +logon to AP with ssid and password. the double quotes are needed + +* W start server mode + +* s{channel}{message} send some characters (max 18 chars) +e.g. s0hello - sends hello on channel 0 + +* S{channel},{length} +e.g. S0,100 sends the next 100 characters on channel 0 + +* T{channel} send some characters, timeout 5s (see function bufsend()) +e.g. enter T0 ````, you have 5s to type your message, transmit on timeout, channel 0 + +* c{channel} close channel e.g. c0 + +* k sendlf +esp8266 AT commands specifially requires ```` as end of line markers. +Some terminals programs cannot make that translation on the host, most send just ````. toggling this +makes it send ```` when only ```` is received. this is a toggle (i.e. flip/flop), reverses with +each toggle + +* b{baud} set the baud rate e.g. b115200 +this is intended to change the baud rate after starting up. the initial baud rade is done in setup() hardcoded. + +this may be useful for instance esp8266 boots in 'program' mode with a non-standard baud of 74880, while in 'run' +mode it is 115200 8N1. while meddling around with a esp-01, i changed the baud to 74880 using 'b74880' command, +used the 'P' command to set dtrPIN low, then 'R' to toggle a reset on esp8266. esp8266 then boots into the +'program' mode, the prompts are legible instead of garbled due to a baud mismatch. i then switch out of +serial monitor on the host and run esptool to flash a rom on the esp8266. Again, this is literally beyond +the scope of this document, but this note here is just a tip on how i did it successfully in one of the attempts. + +The AT commands are based on a version of AT rom from expressif, they may be different between versions or have +changed. Refer to expressif documents for the AT commands reference +[ESP8266 Non-OS AT Instruction Set](https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf) + +[https://www.espressif.com/en/support/download/documents](https://www.espressif.com/en/support/download/documents) + +(note that links may change over time and become invalid) +and the codes - function docmd() for more details. + +## Programming/flashing another stm32 over uart + +This sketch can be used to program/flash another stm32(f103) over uart1. +But programming stm32 requires an 8E1 line discipline. This should be defined in setup. e.g. + +``` +void setup() { +//AN3155: usart boot loader requires even parity +Serial1.begin(115200,SERIAL_8E1); +``` + +In addition disable the command processor in the codes in loop() to prevent accidental activation. Though it +may probably work even if the command processor is left there. + +``` +void loop() { +... + if(Serial.available()) { + digitalWrite(ledPin, HIGH); // blink the led for traffic + // command processor + // chkcmd(); //<--- comment this deactivate the command processor + while(Serial.available()) { + char c = Serial.read(); + Serial1.write(c); + if(c == 13 && fsendlf) Serial1.write(10); + } + } +``` +Set BOOT0 on target device and swap the pins PA9 (TxD), PA10 (RxD) connecting between the bridge device - +target device. power up the target device, normally it is simply connect 3v3 and gnd + +relevant docs and utilities +- [USART protocol used in the STM32 bootloader](https://www.st.com/resource/en/application_note/cd00264342.pdf) +- [STM32 microcontroller system memory boot mode](https://www.st.com/resource/en/application_note/cd00167594.pdf) +- [https://github.com/jsnyder/stm32loader](https://github.com/jsnyder/stm32loader) +- [https://medium.com/@paramaggarwal/programming-an-stm32f103-board-using-usb-port-blue-pill-953cec0dbc86](https://medium.com/@paramaggarwal/programming-an-stm32f103-board-using-usb-port-blue-pill-953cec0dbc86) +(note that links may change over time and become invalid) +other than stm32loader there are other utilities including from ST that'd probably work. One'd just need to +do a web search for them or browse ST's webs. + +example sketch and this readme by ag123 - mit license - 2019 + + + + + + + + diff --git a/STM32F1/libraries/A_STM32_Examples/examples/Sensors/HardTimerAsEncoder/HardTimerAsEncoder.ino b/STM32F1/libraries/A_STM32_Examples/examples/Sensors/HardTimerAsEncoder/HardTimerAsEncoder.ino index 9febe1aee..679891627 100644 --- a/STM32F1/libraries/A_STM32_Examples/examples/Sensors/HardTimerAsEncoder/HardTimerAsEncoder.ino +++ b/STM32F1/libraries/A_STM32_Examples/examples/Sensors/HardTimerAsEncoder/HardTimerAsEncoder.ino @@ -66,13 +66,13 @@ void setup() { pinMode(D3, INPUT_PULLUP); //channel B //configure timer as encoder - timer.setMode(0, TIMER_ENCODER); //set mode, the channel is not used when in this mode. + timer.setMode(1, TIMER_ENCODER); //set mode, the channel is not used when in this mode (but it must be [1..4]). timer.pause(); //stop... timer.setPrescaleFactor(1); //normal for encoder to have the lowest or no prescaler. timer.setOverflow(PPR); //use this to match the number of pulse per revolution of the encoder. Most industrial use 1024 single channel steps. timer.setCount(0); //reset the counter. timer.setEdgeCounting(TIMER_SMCR_SMS_ENCODER3); //or TIMER_SMCR_SMS_ENCODER1 or TIMER_SMCR_SMS_ENCODER2. This uses both channels to count and ascertain direction. - timer.attachInterrupt(0, func); //channel doesn't mean much here either. + timer.attachInterrupt(0, func); //channel must be 0 here timer.resume(); //start the encoder... //Setup encoder simulator diff --git a/STM32F1/libraries/A_STM32_Examples/examples/Sensors/HardwareTimerOnePulseMode/HardwareTimerOnePulseMode.ino b/STM32F1/libraries/A_STM32_Examples/examples/Sensors/HardwareTimerOnePulseMode/HardwareTimerOnePulseMode.ino new file mode 100644 index 000000000..348e32145 --- /dev/null +++ b/STM32F1/libraries/A_STM32_Examples/examples/Sensors/HardwareTimerOnePulseMode/HardwareTimerOnePulseMode.ino @@ -0,0 +1,67 @@ +/* + * Example of the Timer Input Capture mode combined with one pulse mode + * + * This example uses: + * - Timer2 channel 1 as capture input + * - Timer2 channel 2 to generate the pulses, + * - Timer 3 to generate a PWM trigger signal for capture input + */ + +#include + +const uint16_t pulseDelay = 200; +const uint16_t pulseWidth = 200; +//----------------------------------------------------------------------------- +void toggle_led() +{ + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); +} +//----------------------------------------------------------------------------- +void setup() +{ + // setup PA1 (Timer2 channel 2) to PWM (one pulse mode) + pinMode(PA1, PWM); + // setup PA0 (Timer 2 channel 1) as input (capture input mode) + pinMode(PA0, INPUT); + + // stop the timers before configuring them + Timer2.pause(); + + Timer2.setPrescaleFactor(72); // 1 µs resolution + Timer2.setCompare(TIMER_CH2, pulseDelay); + Timer2.setOverflow(pulseWidth + pulseDelay-1); + + // counter setup in one pulse mode, as slave triggered by TI1 + TIMER2_BASE->CR1 = ( TIMER_CR1_OPM ); // one pulse mode + Timer2.setSlaveFlags( TIMER_SMCR_TS_TI1FP1 | TIMER_SMCR_SMS_TRIGGER ); + + // channel 1: capture input on rising edge + Timer2.setMode(TIMER_CH1, TIMER_INPUT_CAPTURE); + //Timer2.setPolarity(TIMER_CH1, 1); // trigger on falling edge + // channel 2: invert polarity (we want low for CNT=1000 ) + { + t = millis(); + toggle_led(); + } +} diff --git a/STM32F1/libraries/A_STM32_Examples/examples/Sensors/HardwareTimerPWMInput/HardwareTimerPWMInput.ino b/STM32F1/libraries/A_STM32_Examples/examples/Sensors/HardwareTimerPWMInput/HardwareTimerPWMInput.ino new file mode 100644 index 000000000..2cc962a09 --- /dev/null +++ b/STM32F1/libraries/A_STM32_Examples/examples/Sensors/HardwareTimerPWMInput/HardwareTimerPWMInput.ino @@ -0,0 +1,77 @@ +/* + * Example of the Timer Input Capture mode to measure PWM pulse width and period. + * + * This example uses: + * - Timer2 channel 1 as capture input + * - Timer3 to generate a PWM trigger signal for capture input + */ + +#include + +const uint8_t pwmPulse = 20; // ms +const uint8_t pwmPeriod = 50; // ms +//----------------------------------------------------------------------------- +void toggle_led() +{ + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); +} +//----------------------------------------------------------------------------- +void setup() +{ + pinMode(LED_BUILTIN, OUTPUT); + + // setup PA0 (Timer 2 channel 1) as input capture mode + pinMode(PA0, INPUT); + + while (!Serial); delay(1000); + + Serial << "Example of the Timer Input Capture mode to measure PWM pulse width and period\n\n"; + + // stop the timers before configuring them + Timer2.pause(); + Timer3.pause(); + + Timer2.setPrescaleFactor(72); // 1 microsecond resolution + + // setup timer 2 channel 1 capture on rising edge + Timer2.setInputCaptureMode(TIMER_CH1, TIMER_IC_INPUT_DEFAULT); // use default input TI1 + // setup timer 2 channel 2 capture on falling edge + Timer2.setInputCaptureMode(TIMER_CH2, TIMER_IC_INPUT_SWITCH); // use switched input TI1 + Timer2.setPolarity(TIMER_CH2, 1); // trigger on falling edge + + // counter setup as slave triggered by TI1 in reset mode + Timer2.setSlaveFlags( TIMER_SMCR_TS_TI1FP1 | TIMER_SMCR_SMS_RESET ); + + Timer2.refresh(); + Timer2.getCompare(TIMER_CH1); // clear capture flag + Timer2.getCompare(TIMER_CH2); // clear capture flag + Timer2.resume(); // let timer 2 run + + // setup PA6 (Timer3 channel 1) to generate 1 ms period PWM with 10% DC + pinMode(PA6, PWM); + Timer3.setPrescaleFactor(72); // 1 µs resolution + Timer3.setCompare(TIMER_CH1, pwmPulse*1000); + Timer3.setOverflow(pwmPeriod*1000); + Timer3.refresh(); + + Timer3.resume(); // let timer 3 run + + // discard first reading + // wait for first period end + while ( !Timer2.getInputCaptureFlag(TIMER_CH1) ); + Timer2.getCompare(TIMER_CH1); // clear capture flag +} +//----------------------------------------------------------------------------- +void loop() +{ + if ( Timer2.getInputCaptureFlag(TIMER_CH2) ) // high pulse end + { + Serial << "PWM pulse width: " << Timer2.getCompare(TIMER_CH2); + } + if ( Timer2.getInputCaptureFlag(TIMER_CH1) ) // period end + { + Serial << ", period: " << Timer2.getCompare(TIMER_CH1) << endl; + toggle_led(); + //delay(500); // read the values only 2 times per second + } +} diff --git a/STM32F1/libraries/A_STM32_Examples/keywords.txt b/STM32F1/libraries/A_STM32_Examples/keywords.txt index e40a09928..c553422d8 100644 --- a/STM32F1/libraries/A_STM32_Examples/keywords.txt +++ b/STM32F1/libraries/A_STM32_Examples/keywords.txt @@ -10,3 +10,7 @@ # Constants (LITERAL1) ####################################### +OUTPUT_OPEN_DRAIN LITERAL1 +INPUT_ANALOG LITERAL1 +INPUT_PULLDOWN LITERAL1 +PWM LITERAL1 \ No newline at end of file diff --git a/STM32F1/libraries/Adafruit_GFX_AS/Adafruit_GFX_AS.cpp b/STM32F1/libraries/Adafruit_GFX_AS/Adafruit_GFX_AS.cpp index 333b12204..16958bf9e 100644 --- a/STM32F1/libraries/Adafruit_GFX_AS/Adafruit_GFX_AS.cpp +++ b/STM32F1/libraries/Adafruit_GFX_AS/Adafruit_GFX_AS.cpp @@ -59,451 +59,17 @@ POSSIBILITY OF SUCH DAMAGE. #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #endif -Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h): - WIDTH(w), HEIGHT(h) -{ - _width = WIDTH; - _height = HEIGHT; - rotation = 0; - cursor_y = cursor_x = 0; - textsize = 1; - textcolor = textbgcolor = 0xFFFF; - wrap = true; -} - -// Draw a circle outline -void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, - uint16_t color) { - int16_t f = 1 - r; - int16_t ddF_x = 1; - int16_t ddF_y = -2 * r; - int16_t x = 0; - int16_t y = r; - - drawPixel(x0 , y0+r, color); - drawPixel(x0 , y0-r, color); - drawPixel(x0+r, y0 , color); - drawPixel(x0-r, y0 , color); - - while (x= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - drawPixel(x0 + x, y0 + y, color); - drawPixel(x0 - x, y0 + y, color); - drawPixel(x0 + x, y0 - y, color); - drawPixel(x0 - x, y0 - y, color); - drawPixel(x0 + y, y0 + x, color); - drawPixel(x0 - y, y0 + x, color); - drawPixel(x0 + y, y0 - x, color); - drawPixel(x0 - y, y0 - x, color); - } -} - -void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, - int16_t r, uint8_t cornername, uint16_t color) { - int16_t f = 1 - r; - int16_t ddF_x = 1; - int16_t ddF_y = -2 * r; - int16_t x = 0; - int16_t y = r; - - while (x= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - if (cornername & 0x4) { - drawPixel(x0 + x, y0 + y, color); - drawPixel(x0 + y, y0 + x, color); - } - if (cornername & 0x2) { - drawPixel(x0 + x, y0 - y, color); - drawPixel(x0 + y, y0 - x, color); - } - if (cornername & 0x8) { - drawPixel(x0 - y, y0 + x, color); - drawPixel(x0 - x, y0 + y, color); - } - if (cornername & 0x1) { - drawPixel(x0 - y, y0 - x, color); - drawPixel(x0 - x, y0 - y, color); - } - } -} - -void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, - uint16_t color) { - drawFastVLine(x0, y0-r, 2*r+1, color); - fillCircleHelper(x0, y0, r, 3, 0, color); -} - -// Used to do circles and roundrects -void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, - uint8_t cornername, int16_t delta, uint16_t color) { - - int16_t f = 1 - r; - int16_t ddF_x = 1; - int16_t ddF_y = -2 * r; - int16_t x = 0; - int16_t y = r; - - while (x= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - if (cornername & 0x1) { - drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); - drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); - } - if (cornername & 0x2) { - drawFastVLine(x0-x, y0-y, 2*y+1+delta, color); - drawFastVLine(x0-y, y0-x, 2*x+1+delta, color); - } - } -} - -// Bresenham's algorithm - thx wikpedia -void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, - int16_t x1, int16_t y1, - uint16_t color) { - int16_t steep = abs(y1 - y0) > abs(x1 - x0); - if (steep) { - swap(x0, y0); - swap(x1, y1); - } - - if (x0 > x1) { - swap(x0, x1); - swap(y0, y1); - } - - int16_t dx, dy; - dx = x1 - x0; - dy = abs(y1 - y0); - - int16_t err = dx / 2; - int16_t ystep; - - if (y0 < y1) { - ystep = 1; - } else { - ystep = -1; - } - - for (; x0<=x1; x0++) { - if (steep) { - drawPixel(y0, x0, color); - } else { - drawPixel(x0, y0, color); - } - err -= dy; - if (err < 0) { - y0 += ystep; - err += dx; - } - } -} - -// Draw a rectangle -void Adafruit_GFX::drawRect(int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t color) { - drawFastHLine(x, y, w, color); - drawFastHLine(x, y+h-1, w, color); - drawFastVLine(x, y, h, color); - drawFastVLine(x+w-1, y, h, color); -} - -void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, - int16_t h, uint16_t color) { - // Update in subclasses if desired! - drawLine(x, y, x, y+h-1, color); -} - -void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, - int16_t w, uint16_t color) { - // Update in subclasses if desired! - drawLine(x, y, x+w-1, y, color); -} - -void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color) { - // Update in subclasses if desired! - for (int16_t i=x; i= y1 >= y0) - if (y0 > y1) { - swap(y0, y1); swap(x0, x1); - } - if (y1 > y2) { - swap(y2, y1); swap(x2, x1); - } - if (y0 > y1) { - swap(y0, y1); swap(x0, x1); - } - - if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing - a = b = x0; - if(x1 < a) a = x1; - else if(x1 > b) b = x1; - if(x2 < a) a = x2; - else if(x2 > b) b = x2; - drawFastHLine(a, y0, b-a+1, color); - return; - } - - int16_t - dx01 = x1 - x0, - dy01 = y1 - y0, - dx02 = x2 - x0, - dy02 = y2 - y0, - dx12 = x2 - x1, - dy12 = y2 - y1, - sa = 0, - sb = 0; - - // For upper part of triangle, find scanline crossings for segments - // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 - // is included here (and second loop will be skipped, avoiding a /0 - // error there), otherwise scanline y1 is skipped here and handled - // in the second loop...which also avoids a /0 error here if y0=y1 - // (flat-topped triangle). - if(y1 == y2) last = y1; // Include y1 scanline - else last = y1-1; // Skip it - - for(y=y0; y<=last; y++) { - a = x0 + sa / dy01; - b = x0 + sb / dy02; - sa += dx01; - sb += dx02; - /* longhand: - a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); - b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); - */ - if(a > b) swap(a,b); - drawFastHLine(a, y, b-a+1, color); - } - - // For lower part of triangle, find scanline crossings for segments - // 0-2 and 1-2. This loop is skipped if y1=y2. - sa = dx12 * (y - y1); - sb = dx02 * (y - y0); - for(; y<=y2; y++) { - a = x1 + sa / dy12; - b = x0 + sb / dy02; - sa += dx12; - sb += dx02; - /* longhand: - a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); - b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); - */ - if(a > b) swap(a,b); - drawFastHLine(a, y, b-a+1, color); - } -} - -void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, - const uint8_t *bitmap, int16_t w, int16_t h, - uint16_t color) { - - int16_t i, j, byteWidth = (w + 7) / 8; - - for(j=0; j> (i & 7))) { - drawPixel(x+i, y+j, color); - } - } - } -} - -//#if ARDUINO >= 100 -size_t Adafruit_GFX::write(uint8_t c) { -//#else -//void Adafruit_GFX::write(uint8_t c) { -//#endif - if (c == '\n') { - cursor_y += textsize*8; - cursor_x = 0; - } else if (c == '\r') { - // skip em - } else { - drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); - cursor_x += textsize*6; - if (wrap && (cursor_x > (_width - textsize*6))) { - cursor_y += textsize*8; - cursor_x = 0; - } - } -//#if ARDUINO >= 100 - return 1; -//#endif -} - -// Draw a character -void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, - uint16_t color, uint16_t bg, uint8_t size) { -#ifdef LOAD_GLCD - if((x >= _width) || // Clip right - (y >= _height) || // Clip bottom - ((x + 6 * size - 1) < 0) || // Clip left - ((y + 8 * size - 1) < 0)) // Clip top - return; - - for (int8_t i=0; i<6; i++ ) { - uint8_t line; - if (i == 5) - line = 0x0; - else - line = pgm_read_byte(font+(c*5)+i); - for (int8_t j = 0; j<8; j++) { - if (line & 0x1) { - if (size == 1) // default size - drawPixel(x+i, y+j, color); - else { // big size - fillRect(x+(i*size), y+(j*size), size, size, color); - } - } else if (bg != color) { - if (size == 1) // default size - drawPixel(x+i, y+j, bg); - else { // big size - fillRect(x+i*size, y+j*size, size, size, bg); - } - } - line >>= 1; - } - } -#endif -} - -void Adafruit_GFX::setCursor(int16_t x, int16_t y) { - cursor_x = x; - cursor_y = y; -} - -void Adafruit_GFX::setTextSize(uint8_t s) { - textsize = (s > 0) ? s : 1; -} - -void Adafruit_GFX::setTextColor(uint16_t c) { - // For 'transparent' background, we'll set the bg - // to the same as fg instead of using a flag - textcolor = textbgcolor = c; -} - -void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) { - textcolor = c; - textbgcolor = b; -} - -void Adafruit_GFX::setTextWrap(boolean w) { - wrap = w; -} - -uint8_t Adafruit_GFX::getRotation(void) { - return rotation; -} - -void Adafruit_GFX::setRotation(uint8_t x) { - rotation = (x & 3); - switch(rotation) { - case 0: - case 2: - _width = WIDTH; - _height = HEIGHT; - break; - case 1: - case 3: - _width = HEIGHT; - _height = WIDTH; - break; - } -} - -// Return the size of the display (per current rotation) -int16_t Adafruit_GFX::width(void) { - return _width; -} - -int16_t Adafruit_GFX::height(void) { - return _height; -} - -void Adafruit_GFX::invertDisplay(boolean i) { - // Do nothing, must be subclassed if supported +Adafruit_GFX_AS::Adafruit_GFX_AS(int16_t w, int16_t h): Adafruit_GFX(w, h) +{ } /*************************************************************************************** ** Function name: drawUnicode ** Descriptions: draw a unicode ***************************************************************************************/ -int16_t Adafruit_GFX::drawUnicode(uint16_t uniCode, int16_t x, int16_t y, int16_t size) +int16_t Adafruit_GFX_AS::drawUnicode(uint16_t uniCode, int16_t x, int16_t y, int16_t size) { if (size) uniCode -= 32; @@ -615,7 +181,7 @@ return (width+gap)*textsize; // x + ** Function name: drawNumber unsigned with size ** Descriptions: drawNumber ***************************************************************************************/ -int16_t Adafruit_GFX::drawNumber(long long_num,int16_t poX, int16_t poY, int16_t size) +int16_t Adafruit_GFX_AS::drawNumber(long long_num,int16_t poX, int16_t poY, int16_t size) { char tmp[10]; if (long_num < 0) sprintf(tmp, "%li", long_num); @@ -627,7 +193,7 @@ int16_t Adafruit_GFX::drawNumber(long long_num,int16_t poX, int16_t poY, int16_t ** Function name: drawChar ** Descriptions: draw char ***************************************************************************************/ -int16_t Adafruit_GFX::drawChar(char c, int16_t x, int16_t y, int16_t size) +int16_t Adafruit_GFX_AS::drawChar(char c, int16_t x, int16_t y, int16_t size) { return drawUnicode(c, x, y, size); } @@ -636,7 +202,7 @@ int16_t Adafruit_GFX::drawChar(char c, int16_t x, int16_t y, int16_t size) ** Function name: drawString ** Descriptions: draw string ***************************************************************************************/ -int16_t Adafruit_GFX::drawString(char *string, int16_t poX, int16_t poY, int16_t size) +int16_t Adafruit_GFX_AS::drawString(char *string, int16_t poX, int16_t poY, int16_t size) { int16_t sumX = 0; @@ -654,7 +220,7 @@ int16_t Adafruit_GFX::drawString(char *string, int16_t poX, int16_t poY, int16_t ** Function name: drawCentreString ** Descriptions: draw string across centre ***************************************************************************************/ -int16_t Adafruit_GFX::drawCentreString(char *string, int16_t dX, int16_t poY, int16_t size) +int16_t Adafruit_GFX_AS::drawCentreString(char *string, int16_t dX, int16_t poY, int16_t size) { int16_t sumX = 0; int16_t len = 0; @@ -703,7 +269,7 @@ int16_t Adafruit_GFX::drawCentreString(char *string, int16_t dX, int16_t poY, in ** Function name: drawRightString ** Descriptions: draw string right justified ***************************************************************************************/ -int16_t Adafruit_GFX::drawRightString(char *string, int16_t dX, int16_t poY, int16_t size) +int16_t Adafruit_GFX_AS::drawRightString(char *string, int16_t dX, int16_t poY, int16_t size) { int16_t sumX = 0; int16_t len = 0; @@ -754,7 +320,7 @@ int16_t Adafruit_GFX::drawRightString(char *string, int16_t dX, int16_t poY, int ** Function name: drawFloat ** Descriptions: drawFloat ***************************************************************************************/ -int16_t Adafruit_GFX::drawFloat(float floatNumber, int16_t decimal, int16_t poX, int16_t poY, int16_t size) +int16_t Adafruit_GFX_AS::drawFloat(float floatNumber, int16_t decimal, int16_t poX, int16_t poY, int16_t size) { unsigned long temp=0; float decy=0.0; @@ -813,3 +379,5 @@ int16_t Adafruit_GFX::drawFloat(float floatNumber, int16_t decimal, int16_t poX, } return sumX; } + +#undef textsize diff --git a/STM32F1/libraries/Adafruit_GFX_AS/Adafruit_GFX_AS.h b/STM32F1/libraries/Adafruit_GFX_AS/Adafruit_GFX_AS.h index 974c47ca0..93055a599 100644 --- a/STM32F1/libraries/Adafruit_GFX_AS/Adafruit_GFX_AS.h +++ b/STM32F1/libraries/Adafruit_GFX_AS/Adafruit_GFX_AS.h @@ -1,64 +1,20 @@ -#ifndef _ADAFRUIT_GFX_H -#define _ADAFRUIT_GFX_H +#ifndef _ADAFRUIT_GFX_AS_H +#define _ADAFRUIT_GFX_AS_H #include "Load_fonts.h" -#if ARDUINO >= 100 - #include "Arduino.h" - #include "Print.h" -#else - #include "WProgram.h" -#endif +#include #define swap(a, b) { int16_t t = a; a = b; b = t; } -class Adafruit_GFX : public Print { - - public: - - Adafruit_GFX(int16_t w, int16_t h); // Constructor - - // This MUST be defined by the subclass: - virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0; - - // These MAY be overridden by the subclass to provide device-specific - // optimized code. Otherwise 'generic' versions are used. - virtual void - drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color), - drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color), - drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color), - drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), - fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), - fillScreen(uint16_t color), - invertDisplay(boolean i); - - // These exist only with Adafruit_GFX (no subclass overrides) - void - drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color), - drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, - uint16_t color), - fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color), - fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, - int16_t delta, uint16_t color), - drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, - int16_t x2, int16_t y2, uint16_t color), - fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, - int16_t x2, int16_t y2, uint16_t color), - drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, - int16_t radius, uint16_t color), - fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, - int16_t radius, uint16_t color), - drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, - int16_t w, int16_t h, uint16_t color), - drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, - uint16_t bg, uint8_t size), - setCursor(int16_t x, int16_t y), - setTextColor(uint16_t c), - setTextColor(uint16_t c, uint16_t bg), - setTextSize(uint8_t s), - setTextWrap(boolean w), - setRotation(uint8_t r); - +/** This class provides a few extensions to Adafruit_GFX, mostly for compatibility with + * existing code. Note that the fonts ("size" parameter) are not the same ones use as the + * ones provided by Adafruit_GFX. Using any of the functions defined in this class will + * therefore pull additional font tables into flash. If that is an issue, try to stick + * to the base class, or trim down the fonts loaded in Load_fonts.h . */ +class Adafruit_GFX_AS : public Adafruit_GFX { +public: + Adafruit_GFX_AS(int16_t w, int16_t h); // Constructor int16_t drawUnicode(uint16_t uniCode, int16_t x, int16_t y, int16_t size); int16_t drawNumber(long long_num,int16_t poX, int16_t poY, int16_t size); int16_t drawChar(char c, int16_t x, int16_t y, int16_t size); @@ -66,32 +22,6 @@ class Adafruit_GFX : public Print { int16_t drawCentreString(char *string, int16_t dX, int16_t poY, int16_t size); int16_t drawRightString(char *string, int16_t dX, int16_t poY, int16_t size); int16_t drawFloat(float floatNumber,int16_t decimal,int16_t poX, int16_t poY, int16_t size); - -#if ARDUINO >= 100 - virtual size_t write(uint8_t); -#else - virtual void write(uint8_t); -#endif - - int16_t - height(void), - width(void); - - uint8_t getRotation(void); - - protected: - const int16_t - WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes - int16_t - _width, _height, // Display w/h as modified by current rotation - cursor_x, cursor_y; - uint16_t - textcolor, textbgcolor; - uint8_t - textsize, - rotation; - boolean - wrap; // If set, 'wrap' text at right edge of display }; -#endif // _ADAFRUIT_GFX_H +#endif // _ADAFRUIT_GFX_AS_H diff --git a/STM32F1/libraries/Adafruit_GFX_AS/README.txt b/STM32F1/libraries/Adafruit_GFX_AS/README.txt index 43cf08afe..f5ccf000e 100644 --- a/STM32F1/libraries/Adafruit_GFX_AS/README.txt +++ b/STM32F1/libraries/Adafruit_GFX_AS/README.txt @@ -1,14 +1,22 @@ -This library has minor modifications to support STM32. -It also was modified to include additional fonts. +This library adds a few font-related functions on top of the Adafruit_GFX library (which you need to install, separately). -This is the core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.). It needs to be paired with a hardware-specific library for each display device we carry (to handle the lower-level functions). +Historically, Adafruit_GFX_AS started as a fork of Adafruit_GFX. Most importantly, it added support for using additional fonts, +before similar functionality became available in Adafruit_GFX. + +Today, the main point of this library is to continue supporting projects that have made use of the functions added in Adafruit_GFX_AS, +while also being fully compatible with Adafruit_GFX (which is used as the base class). It is not recommended to use the functions +provided by the Adafruit_GFX_AS class in newly developed code. + +To use this library with a driver that is not based on Adafruit_GFX_AS, all you will have to do is to replace "Adafrui_GFX" with "Adafruit_GFX_AS" +in your driver code. This will usually be three places: The #include-directive, the base-class declaration, and the call to the base-contstructor. Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! -Written by Limor Fried/Ladyada for Adafruit Industries. +Adafruit_GFX Written by Limor Fried/Ladyada for Adafruit Industries. +Adafruit_GFX_AS funtions added by "Bodmer"(?) BSD license, check license.txt for more information. All text above must be included in any redistribution. -To download, click the DOWNLOAD ZIP button, uncompress and rename the uncompressed folder Adafruit_GFX. Confirm that the Adafruit_GFX folder contains Adafruit_GFX.cpp and Adafruit_GFX.h +To download, click the DOWNLOAD ZIP button, uncompress and rename the uncompressed folder Adafruit_GFX_AS. Confirm that the Adafruit_GFX_AS folder contains Adafruit_GFX_AS.cpp and Adafruit_GFX_AS.h -Place the Adafruit_GFX library folder your /Libraries/ folder. You may need to create the Libraries subfolder if its your first library. Restart the IDE. +Place the Adafruit_GFX_AS library folder your /Libraries/ folder. You may need to create the Libraries subfolder if its your first library. Restart the IDE. diff --git a/STM32F1/libraries/Adafruit_ILI9341_STM/Adafruit_ILI9341_STM.cpp b/STM32F1/libraries/Adafruit_ILI9341_STM/Adafruit_ILI9341_STM.cpp index 914e4d153..d3b7a1fd8 100644 --- a/STM32F1/libraries/Adafruit_ILI9341_STM/Adafruit_ILI9341_STM.cpp +++ b/STM32F1/libraries/Adafruit_ILI9341_STM/Adafruit_ILI9341_STM.cpp @@ -8,7 +8,7 @@ Includes DMA transfers on DMA1 CH2 and CH3. // Constructor when using hardware SPI. Faster, but must use SPI pins // specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.) -Adafruit_ILI9341_STM::Adafruit_ILI9341_STM(int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) +Adafruit_ILI9341_STM::Adafruit_ILI9341_STM(int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX_AS(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) { _cs = cs; _dc = dc; @@ -276,7 +276,7 @@ void Adafruit_ILI9341_STM::drawFastVLine(int16_t x, int16_t y, int16_t h, setAddrWindow(x, y, x, y + h - 1); - if (h>DMA_ON_LIMIT) { + if (h>ILI9341_STM_DMA_ON_LIMIT) { lineBuffer[0] = color; mSPI.dmaSend(lineBuffer, h, 0); } else { @@ -299,7 +299,7 @@ void Adafruit_ILI9341_STM::drawFastHLine(int16_t x, int16_t y, int16_t w, setAddrWindow(x, y, x + w - 1, y); - if (w>DMA_ON_LIMIT) { + if (w>ILI9341_STM_DMA_ON_LIMIT) { lineBuffer[0] = color; mSPI.dmaSend(lineBuffer, w, 0); } else { @@ -337,7 +337,7 @@ void Adafruit_ILI9341_STM::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, setAddrWindow(x, y, x + w - 1, y + h - 1); uint32_t nr_bytes = w * h; - if ( nr_bytes>DMA_ON_LIMIT ) { + if ( nr_bytes>ILI9341_STM_DMA_ON_LIMIT ) { while ( nr_bytes>65535 ) { nr_bytes -= 65535; mSPI.dmaSend(lineBuffer, (65535), 0); diff --git a/STM32F1/libraries/Adafruit_ILI9341_STM/Adafruit_ILI9341_STM.h b/STM32F1/libraries/Adafruit_ILI9341_STM/Adafruit_ILI9341_STM.h index b77b3562f..877fdf97b 100644 --- a/STM32F1/libraries/Adafruit_ILI9341_STM/Adafruit_ILI9341_STM.h +++ b/STM32F1/libraries/Adafruit_ILI9341_STM/Adafruit_ILI9341_STM.h @@ -95,7 +95,7 @@ This library has been modified for the Maple Mini #define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ #define ILI9341_PINK 0xF81F -class Adafruit_ILI9341_STM : public Adafruit_GFX { +class Adafruit_ILI9341_STM : public Adafruit_GFX_AS { public: @@ -128,7 +128,10 @@ class Adafruit_ILI9341_STM : public Adafruit_GFX { uint32_t readcommand32(uint8_t); */ -#define DMA_ON_LIMIT 250 // do DMA only for more data than this +#ifndef ILI9341_STM_DMA_ON_LIMIT +#define ILI9341_STM_DMA_ON_LIMIT 250 // do DMA only for more data than this +#endif + #define SAFE_FREQ 24000000ul // 24MHz for reading #define writePixel drawPixel diff --git a/STM32F1/libraries/EEPROM/EEPROM.cpp b/STM32F1/libraries/EEPROM/EEPROM.cpp index 289a93ad8..32cd7365d 100644 --- a/STM32F1/libraries/EEPROM/EEPROM.cpp +++ b/STM32F1/libraries/EEPROM/EEPROM.cpp @@ -10,13 +10,13 @@ */ uint16 EEPROMClass::EE_CheckPage(uint32 pageBase, uint16 status) { - uint32 pageEnd = pageBase + (uint32)PageSize; + uint32 pageEnd = pageBase + (uint32)PageSize * Pages; // Page Status not EEPROM_ERASED and not a "state" - if ((*(__io uint16*)pageBase) != EEPROM_ERASED && (*(__io uint16*)pageBase) != status) + if ((*(__IO uint16*)pageBase) != EEPROM_ERASED && (*(__IO uint16*)pageBase) != status) return EEPROM_BAD_FLASH; for(pageBase += 4; pageBase < pageEnd; pageBase += 4) - if ((*(__io uint32*)pageBase) != 0xFFFFFFFF) // Verify if slot is empty + if ((*(__IO uint32*)pageBase) != 0xFFFFFFFF) // Verify if slot is empty return EEPROM_BAD_FLASH; return EEPROM_OK; } @@ -31,15 +31,19 @@ uint16 EEPROMClass::EE_CheckPage(uint32 pageBase, uint16 status) FLASH_Status EEPROMClass::EE_ErasePage(uint32 pageBase) { FLASH_Status FlashStatus; - uint16 data = (*(__io uint16*)(pageBase)); + uint16 data = (*(__IO uint16*)(pageBase)); if ((data == EEPROM_ERASED) || (data == EEPROM_VALID_PAGE) || (data == EEPROM_RECEIVE_DATA)) - data = (*(__io uint16*)(pageBase + 2)) + 1; + data = (*(__IO uint16*)(pageBase + 2)) + 1; else data = 0; FlashStatus = FLASH_ErasePage(pageBase); if (FlashStatus == FLASH_COMPLETE) FlashStatus = FLASH_ProgramHalfWord(pageBase + 2, data); + for (size_t i = 1; i < Pages; i++) + { + FLASH_ErasePage(pageBase + PageSize * i); + } return FlashStatus; } @@ -73,8 +77,8 @@ uint16 EEPROMClass::EE_CheckErasePage(uint32 pageBase, uint16 status) */ uint32 EEPROMClass::EE_FindValidPage(void) { - uint16 status0 = (*(__io uint16*)PageBase0); // Get Page0 actual status - uint16 status1 = (*(__io uint16*)PageBase1); // Get Page1 actual status + uint16 status0 = (*(__IO uint16*)PageBase0); // Get Page0 actual status + uint16 status1 = (*(__IO uint16*)PageBase1); // Get Page1 actual status if (status0 == EEPROM_VALID_PAGE && status1 == EEPROM_ERASED) return PageBase0; @@ -95,19 +99,19 @@ uint16 EEPROMClass::EE_GetVariablesCount(uint32 pageBase, uint16 skipAddress) { uint16 varAddress, nextAddress; uint32 idx; - uint32 pageEnd = pageBase + (uint32)PageSize; + uint32 pageEnd = pageBase + (uint32)PageSize * Pages; uint16 count = 0; for (pageBase += 6; pageBase < pageEnd; pageBase += 4) { - varAddress = (*(__io uint16*)pageBase); + varAddress = (*(__IO uint16*)pageBase); if (varAddress == 0xFFFF || varAddress == skipAddress) continue; count++; for(idx = pageBase + 4; idx < pageEnd; idx += 4) { - nextAddress = (*(__io uint16*)idx); + nextAddress = (*(__IO uint16*)idx); if (nextAddress == varAddress) { count--; @@ -136,27 +140,27 @@ uint16 EEPROMClass::EE_PageTransfer(uint32 newPage, uint32 oldPage, uint16 SkipA FLASH_Status FlashStatus; // Transfer process: transfer variables from old to the new active page - newEnd = newPage + ((uint32)PageSize); + newEnd = newPage + ((uint32)PageSize * Pages); // Find first free element in new page for (newIdx = newPage + 4; newIdx < newEnd; newIdx += 4) - if ((*(__io uint32*)newIdx) == 0xFFFFFFFF) // Verify if element + if ((*(__IO uint32*)newIdx) == 0xFFFFFFFF) // Verify if element break; // contents are 0xFFFFFFFF if (newIdx >= newEnd) return EEPROM_OUT_SIZE; oldEnd = oldPage + 4; - oldIdx = oldPage + (uint32)(PageSize - 2); + oldIdx = oldPage + (uint32)(PageSize * Pages - 2); for (; oldIdx > oldEnd; oldIdx -= 4) { - address = *(__io uint16*)oldIdx; + address = *(__IO uint16*)oldIdx; if (address == 0xFFFF || address == SkipAddress) continue; // it's means that power off after write data found = 0; for (idx = newPage + 6; idx < newIdx; idx += 4) - if ((*(__io uint16*)(idx)) == address) + if ((*(__IO uint16*)(idx)) == address) { found = 1; break; @@ -167,7 +171,7 @@ uint16 EEPROMClass::EE_PageTransfer(uint32 newPage, uint32 oldPage, uint16 SkipA if (newIdx < newEnd) { - data = (*(__io uint16*)(oldIdx - 2)); + data = (*(__IO uint16*)(oldIdx - 2)); FlashStatus = FLASH_ProgramHalfWord(newIdx, data); if (FlashStatus != FLASH_COMPLETE) @@ -219,13 +223,13 @@ uint16 EEPROMClass::EE_VerifyPageFullWriteVariable(uint16 Address, uint16 Data) return EEPROM_NO_VALID_PAGE; // Get the valid Page end Address - pageEnd = pageBase + PageSize; // Set end of page + pageEnd = pageBase + PageSize * Pages; // Set end of page for (idx = pageEnd - 2; idx > pageBase; idx -= 4) { - if ((*(__io uint16*)idx) == Address) // Find last value for address + if ((*(__IO uint16*)idx) == Address) // Find last value for address { - count = (*(__io uint16*)(idx - 2)); // Read last data + count = (*(__IO uint16*)(idx - 2)); // Read last data if (count == Data) return EEPROM_OK; if (count == 0xFFFF) @@ -240,7 +244,7 @@ uint16 EEPROMClass::EE_VerifyPageFullWriteVariable(uint16 Address, uint16 Data) // Check each active page address starting from begining for (idx = pageBase + 4; idx < pageEnd; idx += 4) - if ((*(__io uint32*)idx) == 0xFFFFFFFF) // Verify if element + if ((*(__IO uint32*)idx) == 0xFFFFFFFF) // Verify if element { // contents are 0xFFFFFFFF FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data if (FlashStatus != FLASH_COMPLETE) @@ -254,7 +258,7 @@ uint16 EEPROMClass::EE_VerifyPageFullWriteVariable(uint16 Address, uint16 Data) // Empty slot not found, need page transfer // Calculate unique variables in page count = EE_GetVariablesCount(pageBase, Address) + 1; - if (count >= (PageSize / 4 - 1)) + if (count >= (PageSize * Pages / 4 - 1)) return EEPROM_OUT_SIZE; if (pageBase == PageBase1) @@ -284,6 +288,7 @@ EEPROMClass::EEPROMClass(void) PageBase0 = EEPROM_PAGE0_BASE; PageBase1 = EEPROM_PAGE1_BASE; PageSize = EEPROM_PAGE_SIZE; + Pages = 1; Status = EEPROM_NOT_INIT; } @@ -292,6 +297,16 @@ uint16 EEPROMClass::init(uint32 pageBase0, uint32 pageBase1, uint32 pageSize) PageBase0 = pageBase0; PageBase1 = pageBase1; PageSize = pageSize; + Pages = 1; + return init(); +} + +uint16 EEPROMClass::init(uint32 pageBase0, uint32 pageBase1, uint32 pageSize, uint16 pages) +{ + PageBase0 = pageBase0; + PageBase1 = pageBase1; + PageSize = pageSize; + Pages = pages; return init(); } @@ -303,8 +318,8 @@ uint16 EEPROMClass::init(void) FLASH_Unlock(); Status = EEPROM_NO_VALID_PAGE; - status0 = (*(__io uint16 *)PageBase0); - status1 = (*(__io uint16 *)PageBase1); + status0 = (*(__IO uint16 *)PageBase0); + status1 = (*(__IO uint16 *)PageBase1); switch (status0) { @@ -407,7 +422,7 @@ uint16 EEPROMClass::format(void) status = EE_CheckErasePage(PageBase0, EEPROM_VALID_PAGE); if (status != EEPROM_OK) return status; - if ((*(__io uint16*)PageBase0) == EEPROM_ERASED) + if ((*(__IO uint16*)PageBase0) == EEPROM_ERASED) { // Set Page0 as valid page: Write VALID_PAGE at Page0 base address FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE); @@ -437,7 +452,7 @@ uint16 EEPROMClass::erases(uint16 *Erases) if (pageBase == 0) return EEPROM_NO_VALID_PAGE; - *Erases = (*(__io uint16*)pageBase+2); + *Erases = (*(__IO uint16*)pageBase+2); return EEPROM_OK; } @@ -481,13 +496,13 @@ uint16 EEPROMClass::read(uint16 Address, uint16 *Data) return EEPROM_NO_VALID_PAGE; // Get the valid Page end Address - pageEnd = pageBase + ((uint32)(PageSize - 2)); + pageEnd = pageBase + ((uint32)(PageSize * Pages - 2)); // Check each active page address starting from end for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4) - if ((*(__io uint16*)pageEnd) == Address) // Compare the read address with the virtual address + if ((*(__IO uint16*)pageEnd) == Address) // Compare the read address with the virtual address { - *Data = (*(__io uint16*)(pageEnd - 2)); // Get content of Address-2 which is variable value + *Data = (*(__IO uint16*)(pageEnd - 2)); // Get content of Address-2 which is variable value return EEPROM_OK; } @@ -564,7 +579,7 @@ uint16 EEPROMClass::count(uint16 *Count) uint16 EEPROMClass::maxcount(void) { - return ((PageSize / 4)-1); + return ((PageSize * Pages / 4)-1); } EEPROMClass EEPROM; diff --git a/STM32F1/libraries/EEPROM/EEPROM.h b/STM32F1/libraries/EEPROM/EEPROM.h index 29574767d..bf5436278 100644 --- a/STM32F1/libraries/EEPROM/EEPROM.h +++ b/STM32F1/libraries/EEPROM/EEPROM.h @@ -61,6 +61,7 @@ class EEPROMClass uint16 init(void); uint16 init(uint32, uint32, uint32); + uint16 init(uint32, uint32, uint32, uint16); uint16 format(void); @@ -75,6 +76,7 @@ class EEPROMClass uint32 PageBase0; uint32 PageBase1; uint32 PageSize; + uint16 Pages; uint16 Status; private: FLASH_Status EE_ErasePage(uint32); diff --git a/STM32F1/libraries/EEPROM/examples/EEPROM_example/EEPROM_example.ino b/STM32F1/libraries/EEPROM/examples/EEPROM_example/EEPROM_example.ino index e3c8982a3..84ba0bbee 100644 --- a/STM32F1/libraries/EEPROM/examples/EEPROM_example/EEPROM_example.ino +++ b/STM32F1/libraries/EEPROM/examples/EEPROM_example/EEPROM_example.ino @@ -3,8 +3,8 @@ int ledPin = 13; // LED connected to digital pin 13 const char HELP_MSG[] = "Press :\r\n" \ " 0 display configuration\r\n" \ - " 1 set configuration to 0x801F000 / 0x801F800 / 0x400 (RB MCU)\r\n" \ - " 2 set configuration to 0x801F000 / 0x801F800 / 0x800 (ZE/RE MCU)\r\n" \ + " 1 set configuration to 0x801F000 / 0x801F800 / 0x400 / 2 (RB MCU)\r\n" \ + " 2 set configuration to 0x801F000 / 0x801F800 / 0x800 / 1 (ZE/RE MCU)\r\n" \ " 3 write/read variable\r\n" \ " 4 increment address\r\n" \ " 5 display pages top/bottom\r\n" \ @@ -40,6 +40,7 @@ void loop() EEPROM.PageBase0 = 0x801F000; EEPROM.PageBase1 = 0x801F800; EEPROM.PageSize = 0x400; + EEPROM.Pages = 2; DisplayConfig(); } else if (cmd == '2') @@ -47,6 +48,7 @@ void loop() EEPROM.PageBase0 = 0x801F000; EEPROM.PageBase1 = 0x801F800; EEPROM.PageSize = 0x800; + EEPROM.Pages = 1; DisplayConfig(); } else if (cmd == '3') @@ -111,6 +113,8 @@ void DisplayConfig(void) Serial.print (" ("); Serial.print (EEPROM.PageSize, DEC); Serial.println(")"); + Serial.print ("EEPROM.Pages : "); + Serial.println(EEPROM.Pages, DEC); } void DisplayHex(uint16 value) @@ -149,7 +153,7 @@ void DisplayPagesEnd(uint32 endIndex) { Serial.println("Page 0 Bottom Page 1"); - for (uint32 idx = EEPROM.PageSize - endIndex; idx < EEPROM.PageSize; idx += 4) + for (uint32 idx = EEPROM.PageSize * EEPROM.Pages - endIndex; idx < EEPROM.PageSize * EEPROM.Pages; idx += 4) { Serial.print (EEPROM.PageBase0 + idx, HEX); Serial.print (" : "); diff --git a/STM32F1/libraries/EEPROM/flash_stm32.c b/STM32F1/libraries/EEPROM/flash_stm32.c index 364e64e7a..5c7a3feb6 100644 --- a/STM32F1/libraries/EEPROM/flash_stm32.c +++ b/STM32F1/libraries/EEPROM/flash_stm32.c @@ -17,7 +17,7 @@ */ static void delay(void) { - __io uint32 i = 0; + __IO uint32 i = 0; for(i = 0xFF; i != 0; i--) { } } @@ -122,7 +122,7 @@ FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data) { /* if the previous operation is completed, proceed to program the new data */ FLASH_BASE->CR |= FLASH_CR_PG; - *(__io uint16*)Address = Data; + *(__IO uint16*)Address = Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status != FLASH_TIMEOUT) diff --git a/STM32F1/libraries/Ethernet_STM/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino b/STM32F1/libraries/Ethernet_STM/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino index 5ffab7d3c..8390e10dc 100644 --- a/STM32F1/libraries/Ethernet_STM/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino +++ b/STM32F1/libraries/Ethernet_STM/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino @@ -30,7 +30,7 @@ */ #include -#include +#include // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield diff --git a/STM32F1/libraries/FreeRTOS/MapleFreeRTOS.cpp b/STM32F1/libraries/FreeRTOS701/MapleFreeRTOS.cpp similarity index 100% rename from STM32F1/libraries/FreeRTOS/MapleFreeRTOS.cpp rename to STM32F1/libraries/FreeRTOS701/MapleFreeRTOS.cpp diff --git a/STM32F1/libraries/FreeRTOS/MapleFreeRTOS.h b/STM32F1/libraries/FreeRTOS701/MapleFreeRTOS.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/MapleFreeRTOS.h rename to STM32F1/libraries/FreeRTOS701/MapleFreeRTOS.h diff --git a/STM32F1/libraries/FreeRTOS/keywords.txt b/STM32F1/libraries/FreeRTOS701/keywords.txt similarity index 100% rename from STM32F1/libraries/FreeRTOS/keywords.txt rename to STM32F1/libraries/FreeRTOS701/keywords.txt diff --git a/STM32F1/libraries/FreeRTOS/rules.mk b/STM32F1/libraries/FreeRTOS701/rules.mk similarity index 100% rename from STM32F1/libraries/FreeRTOS/rules.mk rename to STM32F1/libraries/FreeRTOS701/rules.mk diff --git a/STM32F1/libraries/FreeRTOS/utility/FreeRTOS.h b/STM32F1/libraries/FreeRTOS701/utility/FreeRTOS.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/FreeRTOS.h rename to STM32F1/libraries/FreeRTOS701/utility/FreeRTOS.h diff --git a/STM32F1/libraries/FreeRTOS/utility/FreeRTOSConfig.h b/STM32F1/libraries/FreeRTOS701/utility/FreeRTOSConfig.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/FreeRTOSConfig.h rename to STM32F1/libraries/FreeRTOS701/utility/FreeRTOSConfig.h diff --git a/STM32F1/libraries/FreeRTOS/utility/StackMacros.h b/STM32F1/libraries/FreeRTOS701/utility/StackMacros.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/StackMacros.h rename to STM32F1/libraries/FreeRTOS701/utility/StackMacros.h diff --git a/STM32F1/libraries/FreeRTOS/utility/croutine.c b/STM32F1/libraries/FreeRTOS701/utility/croutine.c similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/croutine.c rename to STM32F1/libraries/FreeRTOS701/utility/croutine.c diff --git a/STM32F1/libraries/FreeRTOS/utility/croutine.h b/STM32F1/libraries/FreeRTOS701/utility/croutine.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/croutine.h rename to STM32F1/libraries/FreeRTOS701/utility/croutine.h diff --git a/STM32F1/libraries/FreeRTOS/utility/heap_2.c b/STM32F1/libraries/FreeRTOS701/utility/heap_2.c similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/heap_2.c rename to STM32F1/libraries/FreeRTOS701/utility/heap_2.c diff --git a/STM32F1/libraries/FreeRTOS/utility/list.c b/STM32F1/libraries/FreeRTOS701/utility/list.c similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/list.c rename to STM32F1/libraries/FreeRTOS701/utility/list.c diff --git a/STM32F1/libraries/FreeRTOS/utility/list.h b/STM32F1/libraries/FreeRTOS701/utility/list.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/list.h rename to STM32F1/libraries/FreeRTOS701/utility/list.h diff --git a/STM32F1/libraries/FreeRTOS/utility/mpu_wrappers.h b/STM32F1/libraries/FreeRTOS701/utility/mpu_wrappers.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/mpu_wrappers.h rename to STM32F1/libraries/FreeRTOS701/utility/mpu_wrappers.h diff --git a/STM32F1/libraries/FreeRTOS/utility/port.c b/STM32F1/libraries/FreeRTOS701/utility/port.c similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/port.c rename to STM32F1/libraries/FreeRTOS701/utility/port.c diff --git a/STM32F1/libraries/FreeRTOS/utility/portable.h b/STM32F1/libraries/FreeRTOS701/utility/portable.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/portable.h rename to STM32F1/libraries/FreeRTOS701/utility/portable.h diff --git a/STM32F1/libraries/FreeRTOS/utility/portmacro.h b/STM32F1/libraries/FreeRTOS701/utility/portmacro.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/portmacro.h rename to STM32F1/libraries/FreeRTOS701/utility/portmacro.h diff --git a/STM32F1/libraries/FreeRTOS/utility/projdefs.h b/STM32F1/libraries/FreeRTOS701/utility/projdefs.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/projdefs.h rename to STM32F1/libraries/FreeRTOS701/utility/projdefs.h diff --git a/STM32F1/libraries/FreeRTOS/utility/queue.c b/STM32F1/libraries/FreeRTOS701/utility/queue.c similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/queue.c rename to STM32F1/libraries/FreeRTOS701/utility/queue.c diff --git a/STM32F1/libraries/FreeRTOS/utility/queue.h b/STM32F1/libraries/FreeRTOS701/utility/queue.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/queue.h rename to STM32F1/libraries/FreeRTOS701/utility/queue.h diff --git a/STM32F1/libraries/FreeRTOS/utility/semphr.h b/STM32F1/libraries/FreeRTOS701/utility/semphr.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/semphr.h rename to STM32F1/libraries/FreeRTOS701/utility/semphr.h diff --git a/STM32F1/libraries/FreeRTOS/utility/task.h b/STM32F1/libraries/FreeRTOS701/utility/task.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/task.h rename to STM32F1/libraries/FreeRTOS701/utility/task.h diff --git a/STM32F1/libraries/FreeRTOS/utility/tasks.c b/STM32F1/libraries/FreeRTOS701/utility/tasks.c similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/tasks.c rename to STM32F1/libraries/FreeRTOS701/utility/tasks.c diff --git a/STM32F1/libraries/FreeRTOS/utility/timers.c b/STM32F1/libraries/FreeRTOS701/utility/timers.c similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/timers.c rename to STM32F1/libraries/FreeRTOS701/utility/timers.c diff --git a/STM32F1/libraries/FreeRTOS/utility/timers.h b/STM32F1/libraries/FreeRTOS701/utility/timers.h similarity index 100% rename from STM32F1/libraries/FreeRTOS/utility/timers.h rename to STM32F1/libraries/FreeRTOS701/utility/timers.h diff --git a/STM32F1/libraries/HardwareCAN/examples/HardwareCANexample/Changes.h b/STM32F1/libraries/HardwareCAN/examples/HardwareCANexample/Changes.h new file mode 100644 index 000000000..1ccd2fe88 --- /dev/null +++ b/STM32F1/libraries/HardwareCAN/examples/HardwareCANexample/Changes.h @@ -0,0 +1,53 @@ +#ifdef CHANGES_INCLUDE + +****** DETAILS OF THE CHANGES TO BE DONE TO THE CORE TO BE ABLE TO USE THE LIBRARY HardwareCAN ****** + +1) History +The Hardware CAN library was originally published in the Maple Leaflabs forum by X893. +I tested it, and found bugs, which I fixed in the code. My fixes are commented with the initials JMD. +The most important things that missed was to connect the interrupt service routine to the CAN interrupt vector. +The problem is that in the F1 family, this vector is shared with the USB vector, as is some of the memory. Thus, +when one wants to use the CAN, the USB becomes unavailable. This is a severe drawback of this chip, but one has to cope with this. + +2) Changes performed + +2.1) In file C:\ArduinoForSTM32\arduino-1.6.9\hardware\Arduino_STM32-master\STM32F1\cores\maple\libmaple\rcc_f1.c +inserted 1 line, position 96: + [RCC_CAN] = { .clk_domain = APB1, .line_num = 25 }, //! JMD after X893 + +2.2) In file C:\ArduinoForSTM32\arduino-1.6.9\hardware\Arduino_STM32-master\STM32F1\system\libmaple\stm32f1\include\series\rcc.h +inserted 1 line, position 442: + RCC_CAN, //! JMD after X893 + +2.3) In file C:\ArduinoForSTM32\arduino-1.6.9\hardware\Arduino_STM32-master\STM32F1\cores\maple\libmaple\usb\stm32f1\usb.c +2.3.1) inserted 12 lines, position 186 +// JMD : default ISRs of CAN, to be overridden if HardwareCAN library is used in sketch +void __attribute__((weak)) USB_HP_CAN_TX_IRQHandler(void) +{ ; } // Dummy ISR + +void __irq_usb_hp_can_tx(void) +{ + USB_HP_CAN_TX_IRQHandler () ; +} + +uint8 __attribute__((weak)) CAN_RX0_IRQ_Handler(void) +{ return 1 ; } // Dummy ISR + +2.3.2) and altered function void __irq_usb_lp_can_rx0(void) + Was + +void __irq_usb_lp_can_rx0(void) { + uint16 istr = USB_BASE->ISTR; + + /* Use USB_ISR_MSK to only include code for bits we care about. */ + +Becomes + +void __irq_usb_lp_can_rx0(void) { + uint16 istr = USB_BASE->ISTR; + + if (CAN_RX0_IRQ_Handler()) //! JMD : Call to CAN ISR, returns 1 CAN is active + return; //! JMD + + /* Use USB_ISR_MSK to only include code for bits we care about. */ + #endif diff --git a/STM32F1/libraries/HardwareCAN/examples/HardwareCANexample/HardwareCANexample.ino b/STM32F1/libraries/HardwareCAN/examples/HardwareCANexample/HardwareCANexample.ino new file mode 100644 index 000000000..a902543cf --- /dev/null +++ b/STM32F1/libraries/HardwareCAN/examples/HardwareCANexample/HardwareCANexample.ino @@ -0,0 +1,181 @@ +#include +//#include "changes.h" +/* + * Example of use of the HardwareCAN library + * This application receives two frames containing various data. It also produces data that are sent periodically using another two frames. + * Please read the file changes.h to see the changes to be performed to the core in order to use this + */ +// Define the values of the identifiers +#define GYRO_ID 0x27 +#define JOYSTICK_VALUES_ID 0x5A +#define TANK_LEVEL_ID 0x78 +#define MOTOR_CONTROL_ID 0x92 + +// Limit time to flag a CAN error +#define CAN_TIMEOUT 100 +#define CAN_DELAY 10 // ms between two processings of incoming messages +#define CAN_SEND_RATE 200 // ms between two successive sendings + +// Message structures. Each message has its own identifier. As many such variables should be defined +// as the number of different CAN frames the application has to send. Here, they are two. +CanMsg msgGyroscope ; +CanMsg msgMotorControl ; + +// Traffic handling data +int CANquietTime ; // Quiet time counter to detect no activity on CAN bus +bool CANError ; // Indicates that incoming CAN traffic is missing +int CANsendDivider ; // Used to send frames once every so many times loop() is called + +// Applicaton variables +int Contents[4] ; // Contents of the four tanks +int JoystickX ; // Setting of the joystick, X axis +int JoystickY ; // ... Y axis +int AngularRate ; // Output of local gyroscope +int Throttle ; // Motor control value, produced by some local processing +bool ErreurGyroscope = false ; + +// Instanciation of CAN interface +HardwareCAN canBus(CAN1_BASE); + + +// Note : for the predefined identifiers, please have a look in file can.h + +void CANSetup(void) +{ + CAN_STATUS Stat ; + + // Initialize the message structures + // A CAN structure includes the following fields: + msgGyroscope.IDE = CAN_ID_STD; // Indicates a standard identifier ; CAN_ID_EXT would mean this frame uses an extended identifier + msgGyroscope.RTR = CAN_RTR_DATA; // Indicated this is a data frame, as opposed to a remote frame (would then be CAN_RTR_REMOTE) + msgGyroscope.ID = GYRO_ID ; // Identifier of the frame : 0-2047 (0-0x3ff) for standard idenfiers; 0-0x1fffffff for extended identifiers + msgGyroscope.DLC = 3; // Number of data bytes to follow + msgGyroscope.Data[0] = 0x0; // Data bytes, there can be 0 to 8 bytes. + msgGyroscope.Data[1] = 0x0; + msgGyroscope.Data[2] = 0x0; + + msgMotorControl.IDE = CAN_ID_STD; + msgMotorControl.RTR = CAN_RTR_DATA; + msgMotorControl.ID = MOTOR_CONTROL_ID ; + msgMotorControl.DLC = 2; + msgMotorControl.Data[0] = 0x0; + msgMotorControl.Data[1] = 0x0; + + // Initialize CAN module + canBus.map(CAN_GPIO_PB8_PB9); // This setting is already wired in the Olimexino-STM32 board + Stat = canBus.begin(CAN_SPEED_125, CAN_MODE_NORMAL); // Other speeds go from 125 kbps to 1000 kbps. CAN allows even more choices. + + canBus.filter(0, 0, 0); + canBus.set_irq_mode(); // Use irq mode (recommended), so the handling of incoming messages + // will be performed at ease in a task or in the loop. The software fifo is 16 cells long, + // allowing at least 15 ms before processing the fifo is needed at 125 kbps + Stat = canBus.status(); + if (Stat != CAN_OK) + /* Your own error processing here */ ; // Initialization failed +} + +// Send one frame. Parameter is a pointer to a frame structure (above), that has previously been updated with data. +// If no mailbox is available, wait until one becomes empty. There are 3 mailboxes. +CAN_TX_MBX CANsend(CanMsg *pmsg) +{ + CAN_TX_MBX mbx; + + do + { + mbx = canBus.send(pmsg) ; +#ifdef USE_MULTITASK + vTaskDelay( 1 ) ; // Infinite loops are not multitasking-friendly +#endif + } + while(mbx == CAN_TX_NO_MBX) ; // Waiting outbound frames will eventually be sent, unless there is a CAN bus failure. + return mbx ; +} + +// Process incoming messages +// Note : frames are not fully checked for correctness: DLC value is not checked, neither are the IDE and RTR fields. However, the data is guaranteed to be corrrect. +void ProcessMessages(void) +{ + int Pr = 0 ; + int i ; + + CanMsg *r_msg; + + // Loop for every message in the fifo + while ((r_msg = canBus.recv()) != NULL) + { + CANquietTime = 0 ; // Reset at each received frame + CANError = false ; // Clear CAN silence error + switch ( r_msg->ID ) + { + case TANK_LEVEL_ID : // This frame contains four 16-bit words, little endian coded + for ( i = 0 ; i < 4 ; i++ ) + Contents[i] = (int)r_msg->Data[2*i] | ((int)r_msg->Data[(2*i)+1]) << 8 ; + break ; + + case JOYSTICK_VALUES_ID : // This frame contains two 16-bit words, little endian coded + Pr = (int)r_msg->Data[0] ; + Pr |= (int)r_msg->Data[1] << 8 ; + JoystickX = Pr ; + + Pr = (int)r_msg->Data[2] ; + Pr |= (int)r_msg->Data[3] << 8 ; + JoystickY = Pr ; + break ; + + default : // Any frame with a different identifier is ignored + break ; + } + + canBus.free(); // Remove processed message from buffer, whatever the identifier +#ifdef USE_MULTITASK + vTaskDelay( 1 ) ; // Infinite loops are not multitasking-friendly +#endif + } +} + +// Send messages +// Prepare and send 2 frames containing the value of process variables +// Sending all frames at once is a choice; they could be sent separately, at different times and rates. +void SendCANmessages(void) +{ + // Prepare Gyroscope frame : send angular rate + msgGyroscope.Data[0] = AngularRate & 0xff ; + msgGyroscope.Data[1] = ( AngularRate >> 8 ) & 0xff ; + msgGyroscope.Data[2] = ErreurGyroscope ? 1 : 0 ; + CANsend(&msgGyroscope) ; // Send this frame + + msgMotorControl.Data[0] = Throttle & 0xff ; + msgMotorControl.Data[1] = ( Throttle >> 8 ) & 0xff ; + CANsend(&msgMotorControl) ; +} + +// The application program starts here +void setup() { + // put your setup code here, to run once: + CANSetup() ; // Initialize the CAN module and prepare the message structures. +} + +void loop() { + // Process incoming messages periodically (should be often enough to avoid overflowing the fifo) + ProcessMessages() ; // Process all incoming messages, update local variables accordingly + + // This is an example of timeout management. Here it is global to all received frames; + // it could be on a frame by frame basis, with as many control variables as the number of frames. + CANquietTime++ ; + if ( CANquietTime > CAN_TIMEOUT ) + { + CANquietTime = CAN_TIMEOUT + 1 ; // To prevent overflowing this variable if silence prolongs... + CANError = true ; // Flag CAN silence error. Will be cleared at first frame received + } + + // Send messages containing variables to publish. Sent less frequently than the processing of incoming frames (here, every 200 ms) + CANsendDivider-- ; + if ( CANsendDivider < 0 ) + { + CANsendDivider = CAN_SEND_RATE / CAN_DELAY ; + SendCANmessages() ; + } + delay(CAN_DELAY) ; // The delay must not be greater than the time to overflow the incoming fifo (here about 15 ms) +} + + diff --git a/STM32F1/libraries/HardwareCAN/keywords.txt b/STM32F1/libraries/HardwareCAN/keywords.txt new file mode 100644 index 000000000..6d901e314 --- /dev/null +++ b/STM32F1/libraries/HardwareCAN/keywords.txt @@ -0,0 +1,40 @@ +####################################### +# Syntax Coloring Map For HardwareCAN +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +HardwareCAN KEYWORD1 +CanMsg KEYWORD1 +CAN_TX_MBX KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +release KEYWORD2 CAN_Release +send KEYWORD2 CAN_Send +read KEYWORD2 CAN_Read +recv KEYWORD2 CAN_Recieve +set_pool_mode KEYWORD2 CAN_Set_Pool_Mode +set_irq_mode KEYWORD2 CAN_Set_IRQ_Mode +fifo_ready KEYWORD2 CAN_Fifo_Ready +filter KEYWORD2 CAN_Filter +free KEYWORD2 CAN_Free +available KEYWORD2 CAN_Available + +####################################### +# Constants (LITERAL1) +####################################### +CAN_GPIO_PD0_PD1 LITERAL1 +CAN_GPIO_PB8_PB9 LITERAL1 +CAN_FIFO0 LITERAL1 +CAN_FIFO1 LITERAL1 +CAN_SPEED_125 LITERAL1 +CAN_SPEED_250 LITERAL1 +CAN_SPEED_500 LITERAL1 +CAN_SPEED_1000 LITERAL1 +CAN1_BASE LITERAL1 +CAN2_BASE LITERAL1 +CAN_ID_STD LITERAL1 +CAN_RTR_DATA LITERAL1 diff --git a/STM32F1/libraries/HardwareCAN/library.properties b/STM32F1/libraries/HardwareCAN/library.properties new file mode 100644 index 000000000..9186eb6cc --- /dev/null +++ b/STM32F1/libraries/HardwareCAN/library.properties @@ -0,0 +1,9 @@ +name=HardwareCAN +version=1.0.0 +author=Maple Leaflabs fixed by JMD +maintainer=JMD +sentence=Enables managing CAN communication using the built-in CAN port of the OLIMEX STM32 board. +paragraph=With this library you can use the built-in CAN port of the OLIMEX STM32. The library handles both standard and extended frames. +category=Communication +url= +architectures=* \ No newline at end of file diff --git a/STM32F1/libraries/HardwareCAN/src/HardwareCAN.cpp b/STM32F1/libraries/HardwareCAN/src/HardwareCAN.cpp new file mode 100644 index 000000000..f113c4d85 --- /dev/null +++ b/STM32F1/libraries/HardwareCAN/src/HardwareCAN.cpp @@ -0,0 +1,120 @@ +/** + * @brief HardwareCAN "wiring-like" api for CAN + */ + +#include "wirish.h" +#include "utility/can.h" +#include "HardwareCAN.h" + +/** + * @brief Initialize a CAN peripheral + * @param freq frequency to run at, must one of the following values: + * - CAN_SPEED_1000 + * - CAN_SPEED_500 + * - CAN_SPEED_250 + * - CAN_SPEED_125 + */ +CAN_STATUS HardwareCAN::begin(CAN_SPEED speed, uint32 mode) +{ +/* Begin Fix JMD + if (can_init(Port, CAN_MCR_NART, CAN_SPEED_250) == CAN_OK) + // NART empêche la réémission en cas de perte d'arbitrage d'où trames perdues + */ + Serial.end(); // disable USB interface -- JMD + if (can_init(Port, 0, speed) == CAN_OK) + // End Fix JMD + return can_set_mode(Port, mode); + return can_status(); +} + +void HardwareCAN::set_pool_mode(void) +{ + return can_set_pool_mode(Port); +} + +void HardwareCAN::set_irq_mode(void) +{ + return can_set_irq_mode(Port); +} + +CAN_STATUS HardwareCAN::filter(uint8 idx, uint32 id, uint32 mask) +{ + return can_filter(Port, idx, CAN_FIFO0, CAN_FILTER_32BIT, CAN_FILTER_MASK, id, mask); +} + +CAN_STATUS HardwareCAN::status(void) +{ + return can_status(); +} + +CAN_TX_MBX HardwareCAN::send(CanMsg* message) +{ + return can_transmit(Port, message); +} + +uint8 HardwareCAN::available(void) +{ + return can_rx_available(); +} + +CanMsg* HardwareCAN::recv(void) +{ + return can_rx_queue_get(); +} + +void HardwareCAN::clear(void) +{ + can_rx_queue_clear(); +} + +void HardwareCAN::free(void) +{ + can_rx_queue_free(); +} + +void HardwareCAN::cancel(CAN_TX_MBX mbx) +{ + can_cancel(Port, mbx); +} + +/** + * @brief Initialize a CAN peripheral + */ +CAN_STATUS HardwareCAN::begin(void) +{ + return begin(CAN_SPEED_250, CAN_MODE_NORMAL); +} + +void HardwareCAN::end(void) +{ + can_deinit(Port); +} + +CanMsg* HardwareCAN::read(CAN_FIFO fifo, CanMsg* msg) +{ + return can_read(Port, fifo, msg); +} + +void HardwareCAN::release(CAN_FIFO fifo) +{ + can_rx_release(Port, fifo); +} + +/** + * @brief Initialize a CAN peripheral + */ +CAN_STATUS HardwareCAN::map(CAN_GPIO_MAP remap) +{ + return can_gpio_map(Port, remap); +} + +uint8 HardwareCAN::fifo_ready(CAN_FIFO fifo) +{ + return can_fifo_ready(Port, fifo); +} + +HardwareCAN::HardwareCAN(CAN_Port* CANx) +{ + Port = CANx; +} + diff --git a/STM32F1/libraries/HardwareCAN/src/HardwareCAN.h b/STM32F1/libraries/HardwareCAN/src/HardwareCAN.h new file mode 100644 index 000000000..ccc318f5b --- /dev/null +++ b/STM32F1/libraries/HardwareCAN/src/HardwareCAN.h @@ -0,0 +1,68 @@ +/** + * @brief HardwareCAN definitions + */ + +#ifndef _HARDWARECAN_H_ +#define _HARDWARECAN_H_ + +#include "utility/can.h" +#include "usb_serial.h" + +#define PID_REQUEST 0x7DF +#define PID_REPLY 0x7E8 + +#define ENGINE_COOLANT_TEMP 0x05 +#define ENGINE_RPM 0x0C +#define VEHICLE_SPEED 0x0D +#define MAF_SENSOR 0x10 +#define O2_VOLTAGE 0x14 +#define THROTTLE 0x11 + +/** + * Defines the possible SPI communication speeds. + */ + +class HardwareCAN +{ +private: +public: + CAN_Port* Port; + HardwareCAN(CAN_Port *CANx_BASE); + CAN_STATUS begin(void); + + uint32 MSR(void) + { + return Port->MSR; + } + + uint32 RF0R(void) + { + return Port->RF0R; + } + + void set_pool_mode(void); + void set_irq_mode(void); + + CAN_STATUS begin(CAN_SPEED speed, uint32 mode); + void end(void); + + CAN_STATUS filter(uint8 idx, uint32 id, uint32 mask); + CAN_STATUS map(CAN_GPIO_MAP remap); + CAN_STATUS status(void); + + CAN_TX_MBX send(CanMsg* message); + void cancel(CAN_TX_MBX mbx); + + uint8 available(void); + + CanMsg* recv(void); + + void free(void); + void clear(void); + + uint8 fifo_ready(CAN_FIFO fifo); + CanMsg* read(CAN_FIFO fifo, CanMsg* msg); + void release(CAN_FIFO fifo); +}; + +#endif diff --git a/STM32F1/libraries/HardwareCAN/src/utility/can.c b/STM32F1/libraries/HardwareCAN/src/utility/can.c new file mode 100644 index 000000000..0120e0eed --- /dev/null +++ b/STM32F1/libraries/HardwareCAN/src/utility/can.c @@ -0,0 +1,543 @@ +//#include "libmaple.h" +#include "can.h" +//#include "rcc.h" +//#include "gpio.h" +//#include "nvic.h" +//#include "usb.h" + +/** + * CAN_interrupts + */ + +#define CAN_IT_RQCP0 ((uint32)0x00000005) /* Request completed mailbox 0 */ +#define CAN_IT_RQCP1 ((uint32)0x00000006) /* Request completed mailbox 1 */ +#define CAN_IT_RQCP2 ((uint32)0x00000007) /* Request completed mailbox 2 */ +#define CAN_IT_TME ((uint32)0x00000001) /* Transmit mailbox empty */ +#define CAN_IT_FMP0 ((uint32)0x00000002) /* FIFO 0 message pending */ +#define CAN_IT_FF0 ((uint32)0x00000004) /* FIFO 0 full */ +#define CAN_IT_FOV0 ((uint32)0x00000008) /* FIFO 0 overrun */ +#define CAN_IT_FMP1 ((uint32)0x00000010) /* FIFO 1 message pending */ +#define CAN_IT_FF1 ((uint32)0x00000020) /* FIFO 1 full */ +#define CAN_IT_FOV1 ((uint32)0x00000040) /* FIFO 1 overrun */ +#define CAN_IT_EWG ((uint32)0x00000100) /* Error warning */ +#define CAN_IT_EPV ((uint32)0x00000200) /* Error passive */ +#define CAN_IT_BOF ((uint32)0x00000400) /* Bus-off */ +#define CAN_IT_LEC ((uint32)0x00000800) /* Last error code */ +#define CAN_IT_ERR ((uint32)0x00008000) /* Error */ +#define CAN_IT_WKU ((uint32)0x00010000) /* Wake-up */ +#define CAN_IT_SLK ((uint32)0x00020000) /* Sleep */ + +/* Time out for INAK bit */ +#define CAN_INAK_TimeOut ((uint32)0x0000FFFF) + +/* Time out for SLAK bit */ +#define CAN_SLAK_TimeOut ((uint32)0x0000FFFF) + +#define CAN_CONTROL_MASK (CAN_MCR_TTCM | CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_NART | CAN_MCR_RFLM | CAN_MCR_TXFP) +#define CAN_TIMING_MASK (CAN_BTR_SJW | CAN_BTR_TS2 | CAN_BTR_TS1 | CAN_BTR_BRP) +#define CAN_MODE_MASK (CAN_BTR_LBKM | CAN_BTR_SILM) + +struct can_speed_info { + const uint32 btr; +}; + +#define CAN_CLOCK (36000000UL / 18UL) + +static const struct can_speed_info can_speed_table[] = { + [CAN_SPEED_125] = { .btr = ( + (( 4-1) << CAN_BTR_SJW_POS) | + ((12-1) << CAN_BTR_TS1_POS) | + (( 5-1) << CAN_BTR_TS2_POS) | + (CAN_CLOCK / 125000UL - 1) + )}, + [CAN_SPEED_250] = { .btr = ( + (( 4-1) << CAN_BTR_SJW_POS) | + ((12-1) << CAN_BTR_TS1_POS) | + (( 5-1) << CAN_BTR_TS2_POS) | + (CAN_CLOCK / 250000UL - 1) + )}, + [CAN_SPEED_500] = { .btr = ( + (( 4-1) << CAN_BTR_SJW_POS) | + ((12-1) << CAN_BTR_TS1_POS) | + (( 5-1) << CAN_BTR_TS2_POS) | + (CAN_CLOCK / 500000UL - 1) + )}, + [CAN_SPEED_1000] = { .btr = ( + (( 4-1) << CAN_BTR_SJW_POS) | + ((12-1) << CAN_BTR_TS1_POS) | + (( 5-1) << CAN_BTR_TS2_POS) | + (CAN_CLOCK / 1000000UL - 1) + )} +}; + +CAN_STATUS status; +CanMsg can_rx_queue[CAN_RX_QUEUE_SIZE]; + +uint8 can_rx_head; +uint8 can_rx_tail; +uint8 can_rx_count; +uint8 can_rx_lost; +uint8 can_active = 0; + +/** + * @brief Return last operation status + */ +CAN_STATUS can_status(void) +{ + return status; +} + +/** + * @brief Enter initialization mode + */ +CAN_STATUS can_init_enter(CAN_Port* CANx) +{ + volatile uint32 wait_ack = 0 ; + + status = CAN_OK; + if ((CANx->MSR & CAN_MSR_INAK) == 0) // Check for initialization mode already set + { + CANx->MCR |= CAN_MCR_INRQ; // Request initialisation + + wait_ack = 0; // Wait the acknowledge + while ((wait_ack != CAN_INAK_TimeOut) && ((CANx->MSR & CAN_MSR_INAK) == 0)) + wait_ack++; + if ((CANx->MSR & CAN_MSR_INAK) == 0) + status = CAN_INIT_E_FAILED; // Timeout + } + return status; +} + +/** + * @brief Leave initialization mode + */ +CAN_STATUS can_init_leave(CAN_Port* CANx) +{ + volatile uint32 wait_ack = 0 ; + + status = CAN_OK; + if ((CANx->MSR & CAN_MSR_INAK) != 0) // Check for initialization mode already reset + { + CANx->MCR &= ~CAN_MCR_INRQ; // Clear Request initialization + + wait_ack = 0; // Wait the acknowledge + while ((wait_ack != CAN_INAK_TimeOut) && ((CANx->MSR & CAN_MSR_INAK) != 0)) + wait_ack++; + if ((CANx->MSR & CAN_MSR_INAK) != 0) + status = CAN_INIT_L_FAILED; + } + return status; +} + +/** + * @brief Deinitializes the CAN peripheral registers to their default reset values. + */ +CAN_STATUS can_deinit(CAN_Port* CANx) +{ + if (CANx == CAN1_BASE) + { + nvic_irq_disable(NVIC_USB_LP_CAN_RX0); // Disable interrupts + nvic_irq_disable(NVIC_USB_HP_CAN_TX); + rcc_reset_dev(RCC_CAN); + rcc_clk_disable(RCC_CAN); + can_active = 0; + } + return (status = CAN_OK); +} + +/** + * @brief Initialize CAN registers + */ +/* + * Bits in control parameter: + * CAN_MCR_TTCM time triggered communication mode + * CAN_MCR_ABOM automatic bus-off management + * CAN_MCR_AWUM automatic wake-up mode + * CAN_MCR_NART no automatic retransmission + * CAN_MCR_RFLM receive FIFO locked mode + * CAN_MCR_TXFP transmit FIFO priority + */ +CAN_STATUS can_init(CAN_Port* CANx, uint32 control, uint8 speed) +{ + status = CAN_INIT_FAILED; // default result status + // initialize receive message queue + can_rx_head = can_rx_tail = can_rx_count = can_rx_lost = 0; + + rcc_reset_dev(RCC_USB); //! X893 + rcc_clk_disable(RCC_USB); //! X893 +// line_dtr_rts = 0; //! X893 + rcc_clk_enable(RCC_AFIO); // enable clocks for AFIO + rcc_clk_enable(RCC_CAN); // and CAN + rcc_reset_dev(RCC_CAN); // reset CAN interface + + can_active = 1; // set CAN active flag (for interrupt handler + + CANx->MCR &= ~CAN_MCR_SLEEP; // reset CAN sleep mode (default after reset) + + if (can_init_enter(CANx) != CAN_OK) // enter CAN initialization mode + return status; // error, so return + + CANx->MCR &= ~CAN_CONTROL_MASK; // set mode bits + CANx->MCR |= (control & CAN_CONTROL_MASK); + + CANx->BTR &= ~CAN_TIMING_MASK; // Set the bit timing register + CANx->BTR |= (can_speed_table[speed].btr & CAN_TIMING_MASK); + + nvic_irq_enable(NVIC_USB_LP_CAN_RX0); // Enable interrupts + + nvic_irq_enable(NVIC_USB_HP_CAN_TX); + + CANx->IER = (CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_TMEIE); + + if (can_init_leave(CANx) == CAN_OK) + { + while (!(CANx->TSR & CAN_TSR_TME0)); // Transmit mailbox 0 is empty + while (!(CANx->TSR & CAN_TSR_TME1)); // Transmit mailbox 0 is empty + while (!(CANx->TSR & CAN_TSR_TME2)); // Transmit mailbox 0 is empty + } + return status; +} + +/** + * @brief Set timing calues (CAN_BTR) + */ +CAN_STATUS can_set_timing(CAN_Port* CANx, uint32 timing) +{ + if (can_init_enter(CANx) == CAN_OK) + { + CANx->BTR = ((CANx->BTR & ~CAN_TIMING_MASK) | (timing & CAN_TIMING_MASK)); + can_init_leave(CANx); + } + return status; +} + +/** + * @brief Set CAN mode + * @param CANx pointer to CAN port + * @param mode CAN mode + */ +CAN_STATUS can_set_mode(CAN_Port* CANx, uint32 mode) +{ + if (can_init_enter(CANx) == CAN_OK) + { + CANx->BTR &= ~CAN_MODE_MASK; + CANx->BTR |= (mode & CAN_MODE_MASK); + can_init_leave(CANx); + } + return status; +} + +/** + * @brief Set CAN to GPIO mapping + */ +CAN_STATUS can_gpio_map(CAN_Port* CANx, CAN_GPIO_MAP map_mode) +{ + rcc_clk_enable(RCC_AFIO); + + status = CAN_INIT_FAILED; + if( CANx == CAN1_BASE) + { + switch(map_mode) + { + case CAN_GPIO_PB8_PB9: + rcc_clk_enable(RCC_GPIOB); + afio_remap(AFIO_MAPR_CAN_REMAP_PB8_PB9); + gpio_set_mode(GPIOB, 8, GPIO_INPUT_FLOATING); + gpio_set_mode(GPIOB, 9, GPIO_AF_OUTPUT_PP); + break; +#if NR_GPIO_PORTS >= 4 + case CAN_GPIO_PD0_PD1: + rcc_clk_enable(RCC_GPIOD); + afio_remap(AFIO_MAPR_CAN_REMAP_PD0_PD1); + gpio_set_mode(GPIOD, 0, GPIO_INPUT_FLOATING); + gpio_set_mode(GPIOD, 1, GPIO_AF_OUTPUT_PP); + break; +#endif + default: + return status; + } + status = CAN_OK; + } + return status; +} + +CAN_STATUS can_filter(CAN_Port* CANx, uint8 filter_idx, CAN_FIFO fifo, CAN_FILTER_SCALE scale, CAN_FILTER_MODE mode, uint32 fr1, uint32 fr2) +{ + uint32 mask = ((uint32)0x00000001) << filter_idx; + + CANx->FMR |= CAN_FMR_FINIT; // Initialization mode for the filter + CANx->FA1R &= ~mask; // Deactivation filter + + + if (scale == CAN_FILTER_32BIT) + CANx->FS1R |= mask; + else + CANx->FS1R &= ~mask; + + CANx->sFilterRegister[filter_idx].FR1 = fr1; + CANx->sFilterRegister[filter_idx].FR2 = fr2; + + if (mode == CAN_FILTER_MASK) + CANx->FM1R &= ~mask; + else + CANx->FM1R |= mask; + + if (fifo == CAN_FIFO0) + CANx->FFA1R &= ~mask; + else + CANx->FFA1R |= mask; + + CANx->FA1R |= mask; + CANx->FMR &= ~CAN_FMR_FINIT; + return CAN_OK; +} + +/** + * @brief Initiates the transmission of a message. + * @param CANx: where x can be 1 to select the CAN peripheral. + * @param msg: pointer to a structure which contains CAN Id, CAN DLC and CAN datas. + * @retval : The number of the mailbox that is used for transmission or CAN_NO_MB if there is no empty mailbox. + */ +CAN_TX_MBX can_transmit(CAN_Port* CANx, CanMsg* msg) +{ + CAN_TX_MBX mbx; + uint32 data; + + /* Select one empty transmit mailbox */ + if (CANx->TSR & CAN_TSR_TME0) + mbx = CAN_TX_MBX0; + else if (CANx->TSR & CAN_TSR_TME1) + mbx = CAN_TX_MBX1; + else if (CANx->TSR & CAN_TSR_TME2) + mbx = CAN_TX_MBX2; + else + { + status = CAN_NO_MB; + return CAN_TX_NO_MBX; + } + + /* Set up the Id */ + if (msg->IDE == CAN_ID_STD) + data = (msg->ID << 21); + else + data = (msg->ID << 3) | CAN_ID_EXT; + + data |= ((uint32)msg->RTR); + + /* Set up the DLC */ + CANx->sTxMailBox[mbx].TDTR = (uint32)(msg->DLC & 0x0F); + + /* Set up the data field */ + CANx->sTxMailBox[mbx].TDLR = ( + ((uint32)msg->Data[3] << 24) | + ((uint32)msg->Data[2] << 16) | + ((uint32)msg->Data[1] << 8) | + ((uint32)msg->Data[0]) + ); + CANx->sTxMailBox[mbx].TDHR = ( + ((uint32)msg->Data[7] << 24) | + ((uint32)msg->Data[6] << 16) | + ((uint32)msg->Data[5] << 8) | + ((uint32)msg->Data[4]) + ); + /* Request transmission */ + CANx->sTxMailBox[mbx].TIR = (data | CAN_TMIDxR_TXRQ); + status = CAN_OK; + + return mbx; +} + +/** + * Checks the transmission of a message. + * @param CANx: where x can be 1 to select the CAN peripheral. + * @param mbx: the number of the mailbox that is used for transmission. + * @retval : CAN_TX_OK if the CAN driver transmits the message, CAN_TX_FAILED in an other case. + */ +CAN_STATUS can_tx_status(CAN_Port* CANx, CAN_TX_MBX mbx) +{ + /* RQCP, TXOK and TME bits */ + uint8 state = 0; + + switch (mbx) + { + case CAN_TX_MBX0: + state |= (uint8)((CANx->TSR & CAN_TSR_RQCP0) << 2); + state |= (uint8)((CANx->TSR & CAN_TSR_TXOK0) >> 0); + state |= (uint8)((CANx->TSR & CAN_TSR_TME0) >> 26); + break; + case CAN_TX_MBX1: + state |= (uint8)((CANx->TSR & CAN_TSR_RQCP1) >> 6); + state |= (uint8)((CANx->TSR & CAN_TSR_TXOK1) >> 8); + state |= (uint8)((CANx->TSR & CAN_TSR_TME1) >> 27); + break; + case CAN_TX_MBX2: + state |= (uint8)((CANx->TSR & CAN_TSR_RQCP2) >> 14); + state |= (uint8)((CANx->TSR & CAN_TSR_TXOK2) >> 16); + state |= (uint8)((CANx->TSR & CAN_TSR_TME2) >> 28); + break; + default: + status = CAN_TX_FAILED; + return status; + } + + // state = RQCP TXOK TME + switch (state) + { + /* transmit pending */ + case 0x0: + status = CAN_TX_PENDING; + break; + /* transmit failed */ + case 0x5: + status = CAN_TX_FAILED; + break; + /* transmit succedeed */ + case 0x7: + status = CAN_OK; + break; + default: + status = CAN_TX_FAILED; + break; + } + return status; +} + +/** + * @brief Cancels a transmit request. + * @param CANx: where x can be 1 to select the CAN peripheral. + * @param mbx: Mailbox number. + * @retval : None. + */ +void can_cancel(CAN_Port* CANx, uint8 mbx) +{ + /* abort transmission */ + switch (mbx) + { + case 0: + CANx->TSR |= CAN_TSR_ABRQ0; + break; + case 1: + CANx->TSR |= CAN_TSR_ABRQ1; + break; + case 2: + CANx->TSR |= CAN_TSR_ABRQ2; + break; + default: + break; + } +} + +void can_rx_queue_clear(void) +{ + nvic_irq_disable(NVIC_USB_LP_CAN_RX0); + can_rx_head = can_rx_tail = can_rx_count = can_rx_lost = 0; + nvic_irq_enable(NVIC_USB_LP_CAN_RX0); +} + +uint8 can_rx_available(void) +{ + return can_rx_count; +} + +CanMsg* can_rx_queue_get(void) +{ + if (can_rx_count == 0) + return NULL; + return &(can_rx_queue[can_rx_tail]); +} + +void can_rx_queue_free(void) +{ + if (can_rx_count > 0) + { + nvic_irq_disable(NVIC_USB_LP_CAN_RX0); // JMD problème d'atomicité + can_rx_tail = (can_rx_tail == (CAN_RX_QUEUE_SIZE - 1)) ? 0 : (can_rx_tail + 1); + --can_rx_count; + nvic_irq_enable(NVIC_USB_LP_CAN_RX0); // fin JMD problème d'atomicité + } +} + +CanMsg* can_read(CAN_Port* CANx, CAN_FIFO fifo, CanMsg* msg) +{ + uint32 data = CANx->sFIFOMailBox[fifo].RIR; + + /* Get the Id */ + if (data & CAN_ID_EXT) + { + msg->ID = 0x1FFFFFFF & (data >> 3); + msg->IDE = (uint8)CAN_ID_EXT; + } + else + { + msg->ID = 0x000007FF & (data >> 21); + msg->IDE = (uint8)CAN_ID_STD; + } + + msg->RTR = (uint8)(CAN_RTR_REMOTE & data); + msg->DLC = (uint8)(0x0F & CANx->sFIFOMailBox[fifo].RDTR); + msg->FMI = (uint8)(0xFF & (CANx->sFIFOMailBox[fifo].RDTR >> 8)); + + /* Get the data field */ + data = CANx->sFIFOMailBox[fifo].RDLR; + uint8* p = msg->Data; + *p++ = (uint8)0xFF & data; + *p++ = (uint8)0xFF & (data >> 8); + *p++ = (uint8)0xFF & (data >> 16); + *p++ = (uint8)0xFF & (data >> 24); + + data = CANx->sFIFOMailBox[fifo].RDHR; + *p++ = (uint8)0xFF & data; + *p++ = (uint8)0xFF & (data >> 8); + *p++ = (uint8)0xFF & (data >> 16); + *p++ = (uint8)0xFF & (data >> 24); + + return msg; +} + +void can_rx_release(CAN_Port* CANx, CAN_FIFO fifo) +{ + if (fifo == CAN_FIFO0) + CANx->RF0R |= (CAN_RF0R_RFOM0); // Release FIFO0 + else + CANx->RF1R |= (CAN_RF1R_RFOM1); // Release FIFO1 +} + +void can_rx_read(CAN_Port* CANx, CAN_FIFO fifo) +{ + if (can_rx_count < CAN_RX_QUEUE_SIZE) // read the message + { + CanMsg* msg = &can_rx_queue[can_rx_head]; + can_read(CANx, fifo, msg); + can_rx_head = (can_rx_head == (CAN_RX_QUEUE_SIZE - 1)) ? 0 : (can_rx_head + 1); + can_rx_count++; + } + else + can_rx_lost = 1; // no place in queue, ignore package + + can_rx_release(CANx, fifo); +} + +uint8 CAN_RX0_IRQ_Handler(void) +{ + if (can_active) + { + while ((CAN1_BASE->RF0R & CAN_RF0R_FMP0) != 0) + can_rx_read(CAN1_BASE, CAN_FIFO0); // message pending FIFO0 + while ((CAN1_BASE->RF1R & CAN_RF1R_FMP1) != 0) + can_rx_read(CAN1_BASE, CAN_FIFO1); // message pending FIFO1 + } + return can_active; // return CAN active flag to USB handler +} + +void USB_HP_CAN_TX_IRQHandler (void) +{ + if (can_active) + { + if (CAN1_BASE->TSR & CAN_TSR_RQCP0) + CAN1_BASE->TSR |= CAN_TSR_RQCP0; // reset request complete mbx 0 + if (CAN1_BASE->TSR & CAN_TSR_RQCP1) + CAN1_BASE->TSR |= CAN_TSR_RQCP1; // reset request complete mbx 1 + if (CAN1_BASE->TSR & CAN_TSR_RQCP2) + CAN1_BASE->TSR |= CAN_TSR_RQCP2; // reset request complete mbx 2 + } +} diff --git a/STM32F1/libraries/HardwareCAN/src/utility/can.h b/STM32F1/libraries/HardwareCAN/src/utility/can.h new file mode 100644 index 000000000..576ac36fe --- /dev/null +++ b/STM32F1/libraries/HardwareCAN/src/utility/can.h @@ -0,0 +1,322 @@ +#ifndef _CAN_H_ +#define _CAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//#include "libmaple_types.h" +#include +#include +#include "libmaple/nvic.h" +#include +//#include "types.h" +#include "libmaple/usb.h" + +#ifndef CAN_RX_QUEUE_SIZE + #define CAN_RX_QUEUE_SIZE 16 +#endif + +/* peripheral addresses */ +#define CAN1_BASE ((CAN_Port*)0x40006400) +#define CAN2_BASE ((CAN_Port*)0x40006800) + + +/* CAN Master Control Register bits */ +#define CAN_MCR_INRQ ((uint32)0x00000001) /* Initialization request */ +#define CAN_MCR_SLEEP ((uint32)0x00000002) /* Sleep mode request */ +#define CAN_MCR_TXFP ((uint32)0x00000004) /* Transmit FIFO priority */ +#define CAN_MCR_RFLM ((uint32)0x00000008) /* Receive FIFO locked mode */ +#define CAN_MCR_NART ((uint32)0x00000010) /* No automatic retransmission */ +#define CAN_MCR_AWUM ((uint32)0x00000020) /* Automatic wake up mode */ +#define CAN_MCR_ABOM ((uint32)0x00000040) /* Automatic bus-off management */ +#define CAN_MCR_TTCM ((uint32)0x00000080) /* Time triggered communication mode */ +#define CAN_MCR_RESET ((uint32)0x00008000) /* bxCAN software master reset */ +#define CAN_MCR_DBF ((uint32)0x00010000) /* Debug freeze */ + +/* CAN Master Status Register bits */ +#define CAN_MSR_INAK ((uint32)0x00000001) /* Initialization acknowledge */ +#define CAN_MSR_SLAK ((uint32)0x00000002) /* Sleep acknowledge */ +#define CAN_MSR_ERRI ((uint32)0x00000004) /* Error interrupt */ +#define CAN_MSR_WKUI ((uint32)0x00000008) /* Wake-up interrupt */ +#define CAN_MSR_SLAKI ((uint32)0x00000010) /* Sleep acknowledge interrupt */ +#define CAN_MSR_TXM ((uint32)0x00000100) /* Transmit mode */ +#define CAN_MSR_RXM ((uint32)0x00000200) /* Receive mode */ +#define CAN_MSR_SAMP ((uint32)0x00000400) /* Last sample point */ +#define CAN_MSR_RX ((uint32)0x00000800) /* CAN Rx signal */ + +/* CAN Transmit Status Register bits */ +#define CAN_TSR_RQCP0 ((uint32)0x00000001) /* Request completed mailbox0 */ +#define CAN_TSR_TXOK0 ((uint32)0x00000002) /* Transmission OK of mailbox0 */ +#define CAN_TSR_ALST0 ((uint32)0x00000004) /* Arbitration Lost for Mailbox0 */ +#define CAN_TSR_TERR0 ((uint32)0x00000008) /* Transmission Error of Mailbox0 */ +#define CAN_TSR_ABRQ0 ((uint32)0x00000080) /* Abort request for mailbox0 */ +#define CAN_TSR_RQCP1 ((uint32)0x00000100) /* Request completed mailbox1 */ +#define CAN_TSR_TXOK1 ((uint32)0x00000200) /* Transmission OK of mailbox1 */ +#define CAN_TSR_ALST1 ((uint32)0x00000400) /* Arbitration Lost for Mailbox1 */ +#define CAN_TSR_TERR1 ((uint32)0x00000800) /* Transmission Error of Mailbox1 */ +#define CAN_TSR_ABRQ1 ((uint32)0x00008000) /* Abort request for mailbox1 */ +#define CAN_TSR_RQCP2 ((uint32)0x00010000) /* Request completed mailbox2 */ +#define CAN_TSR_TXOK2 ((uint32)0x00020000) /* Transmission OK of mailbox2 */ +#define CAN_TSR_ALST2 ((uint32)0x00040000) /* Arbitration Lost for mailbox 2 */ +#define CAN_TSR_TERR2 ((uint32)0x00080000) /* Transmission Error of Mailbox 2 */ +#define CAN_TSR_ABRQ2 ((uint32)0x00800000) /* Abort request for mailbox2 */ +#define CAN_TSR_CODE ((uint32)0x03000000) /* Mailbox Code */ +#define CAN_TSR_TME ((uint32)0x1C000000) /* TME[2:0] bits */ +#define CAN_TSR_TME0 ((uint32)0x04000000) /* Transmit mailbox 0 empty */ +#define CAN_TSR_TME1 ((uint32)0x08000000) /* Transmit mailbox 1 empty */ +#define CAN_TSR_TME2 ((uint32)0x10000000) /* Transmit mailbox 2 empty */ +#define CAN_TSR_LOW ((uint32)0xE0000000) /* LOW[2:0] bits */ +#define CAN_TSR_LOW0 ((uint32)0x20000000) /* Lowest Priority Flag for Mailbox 0 */ +#define CAN_TSR_LOW1 ((uint32)0x40000000) /* Lowest Priority Flag for Mailbox 1 */ +#define CAN_TSR_LOW2 ((uint32)0x80000000) /* Lowest Priority Flag for Mailbox 2 */ + +/* CAN Receive FIFO 0 Register bits */ +#define CAN_RF0R_FMP0 ((uint32)0x00000003) /* FIFO 0 message pending */ +#define CAN_RF0R_FULL0 ((uint32)0x00000008) /* FIFO 0 full */ +#define CAN_RF0R_FOVR0 ((uint32)0x00000010) /* FIFO 0 overrun */ +#define CAN_RF0R_RFOM0 ((uint32)0x00000020) /* Release FIFO 0 output mailbox */ + +/* CAN Receive FIFO 1 Register bits */ +#define CAN_RF1R_FMP1 ((uint32)0x00000003) /* FIFO 1 message pending */ +#define CAN_RF1R_FULL1 ((uint32)0x00000008) /* FIFO 1 full */ +#define CAN_RF1R_FOVR1 ((uint32)0x00000010) /* FIFO 1 overrun */ +#define CAN_RF1R_RFOM1 ((uint32)0x00000020) /* Release FIFO 1 output mailbox */ + +/* CAN Error Status Register bits */ +#define CAN_ESR_EWGF ((uint32)0x00000001) /* Error warning flag */ +#define CAN_ESR_EPVF ((uint32)0x00000002) /* Error passive flag */ +#define CAN_ESR_BOFF ((uint32)0x00000004) /* Bus-off flag */ + +/* CAN interrupt enable register (CAN_IER) */ +#define CAN_IER_TMEIE ((uint32)0x00000001) /* Transmit Mailbox Empty Interrupt Enable */ +#define CAN_IER_FMPIE0 ((uint32)0x00000002) /* FIFO Message Pending Interrupt Enable */ +#define CAN_IER_FFIE0 ((uint32)0x00000004) /* FIFO Full Interrupt Enable */ +#define CAN_IER_FOVIE0 ((uint32)0x00000008) /* FIFO Overrun Interrupt Enable */ +#define CAN_IER_FMPIE1 ((uint32)0x00000010) /* FIFO Message Pending Interrupt Enable */ +#define CAN_IER_FFIE1 ((uint32)0x00000020) /* FIFO Full Interrupt Enable */ +#define CAN_IER_FOVIE1 ((uint32)0x00000040) /* FIFO Overrun Interrupt Enable */ +#define CAN_IER_EWGIE ((uint32)0x00000100) /* Error Warning Interrupt Enable */ +#define CAN_IER_EPVIE ((uint32)0x00000200) /* Error Passive Interrupt Enable */ +#define CAN_IER_BOFIE ((uint32)0x00000400) /* Bus-Off Interrupt Enable */ +#define CAN_IER_LECIE ((uint32)0x00000800) /* Last Error Code Interrupt Enable */ +#define CAN_IER_ERRIE ((uint32)0x00008000) /* Error Interrupt Enable */ +#define CAN_IER_WKUIE ((uint32)0x00010000) /* Wakeup Interrupt Enable */ +#define CAN_IER_SLKIE ((uint32)0x00020000) /* Sleep Interrupt Enable */ + +/* CAN error status register (CAN_ESR) */ +#define CAN_ESR_EWGF ((uint32)0x00000001) /* Error Warning Flag */ +#define CAN_ESR_EPVF ((uint32)0x00000002) /* Error Passive Flag */ +#define CAN_ESR_BOFF ((uint32)0x00000004) /* Bus-Off Flag */ + +#define CAN_ESR_LEC ((uint32)0x00000070) /* LEC[2:0] bits (Last Error Code) */ +#define CAN_ESR_LEC_0 ((uint32)0x00000010) /* Bit 0 */ +#define CAN_ESR_LEC_1 ((uint32)0x00000020) /* Bit 1 */ +#define CAN_ESR_LEC_2 ((uint32)0x00000040) /* Bit 2 */ + +#define CAN_ESR_TEC ((uint32)0x00FF0000) /* Least significant byte of the 9-bit Transmit Error Counter */ +#define CAN_ESR_REC ((uint32)0xFF000000) /* Receive Error Counter */ + +/* CAN bit timing register (CAN_BTR) */ +#define CAN_BTR_SJW_POS 24 +#define CAN_BTR_TS2_POS 20 +#define CAN_BTR_TS1_POS 16 + +#define CAN_BTR_BRP ((uint32)0x000003FF) /* Baud Rate Prescaler */ +#define CAN_BTR_TS1 ((uint32)0x000F0000) /* Time Segment 1 */ +#define CAN_BTR_TS2 ((uint32)0x00700000) /* Time Segment 2 */ +#define CAN_BTR_SJW ((uint32)0x03000000) /* Resynchronization Jump Width */ +#define CAN_BTR_LBKM ((uint32)0x40000000) /* Loop Back Mode (Debug) */ +#define CAN_BTR_SILM ((uint32)0x80000000) /* Silent Mode */ + + +/* CAN Mailbox Transmit Request */ +#define CAN_TMIDxR_TXRQ ((uint32)0x00000001) /* Transmit mailbox request */ + +/* CAN Filter Master Register bits */ +#define CAN_FMR_FINIT ((uint32)0x00000001) /* Filter init mode */ + + +typedef enum CAN_GPIO_MAP { + CAN_GPIO_PB8_PB9, /* RX to PB8, TX to PB9 */ + CAN_GPIO_PD0_PD1 /* RX to PD0, TX to PD1 */ +} CAN_GPIO_MAP; + +typedef enum CAN_STATUS +{ + CAN_OK = 0, + CAN_INIT_FAILED, + CAN_INIT_E_FAILED, + CAN_INIT_L_FAILED, + CAN_TX_FAILED, + CAN_TX_PENDING, + CAN_NO_MB, + CAN_FILTER_FULL +} CAN_STATUS; + +typedef enum CAN_TX_MBX +{ + CAN_TX_MBX0 = 0, + CAN_TX_MBX1 = 1, + CAN_TX_MBX2 = 2, + CAN_TX_NO_MBX = CAN_NO_MB +} CAN_TX_MBX; + +#define CAN_MODE_NORMAL ((uint32)0x0) /* normal mode */ +#define CAN_MODE_LOOPBACK (CAN_BTR_LBKM) /* loopback mode */ +#define CAN_MODE_SILENT (CAN_BTR_SILM) /* silent mode */ +#define CAN_MODE_SILENT_LOOPBACK (CAN_BTR_LBKM | CAN_BTR_SILM) /* loopback combined with silent mode */ + +enum CAN_SPEED { + CAN_SPEED_125, + CAN_SPEED_250, + CAN_SPEED_500, + CAN_SPEED_1000, +}; + +/** + * CAN_identifier_type + */ +#define CAN_ID_STD ((uint32)0x00) /* Standard Id */ +#define CAN_ID_EXT ((uint32)0x04) /* Extended Id */ + +/** + * CAN_remote_transmission_request + */ +#define CAN_RTR_DATA ((uint32)0x00) /* Data frame */ +#define CAN_RTR_REMOTE ((uint32)0x02) /* Remote frame */ + +/** + * CAN_receive_FIFO_number_constants + */ +typedef enum { + CAN_FIFO0 = 0, + CAN_FIFO1 = 1 +} CAN_FIFO; + +typedef enum { + CAN_FILTER_32BIT = 0, + CAN_FILTER_16BIT = 1 +} CAN_FILTER_SCALE; + +typedef enum { + CAN_FILTER_MASK = 0, + CAN_FILTER_LIST = 1 +} CAN_FILTER_MODE; +/** + * @brief Controller Area Network TxMailBox + */ +typedef struct +{ + volatile uint32 TIR; + volatile uint32 TDTR; + volatile uint32 TDLR; + volatile uint32 TDHR; +} CAN_TxMailBox_Port; + +/** + * @brief Controller Area Network FIFOMailBox + */ +typedef struct +{ + volatile uint32 RIR; + volatile uint32 RDTR; + volatile uint32 RDLR; + volatile uint32 RDHR; +} CAN_FIFOMailBox_Port; + +/** + * @brief Controller Area Network FilterRegister + */ +typedef struct +{ + volatile uint32 FR1; + volatile uint32 FR2; +} CAN_FilterRegister_Port; + +typedef struct { + volatile uint32 MCR; // CAN master control register (CAN_MCR) + volatile uint32 MSR; // CAN master status register (CAN_MSR) + volatile uint32 TSR; // CAN transmit status register (CAN_TSR) + volatile uint32 RF0R; // CAN receive FIFO 0 register (CAN_RF0R) + volatile uint32 RF1R; // CAN receive FIFO 1 register (CAN_RF1R) + volatile uint32 IER; + volatile uint32 ESR; + volatile uint32 BTR; + uint32 RESERVED0[88]; + CAN_TxMailBox_Port sTxMailBox[3]; + CAN_FIFOMailBox_Port sFIFOMailBox[2]; + uint32 RESERVED1[12]; + volatile uint32 FMR; + volatile uint32 FM1R; + uint32 RESERVED2; + volatile uint32 FS1R; + uint32 RESERVED3; + volatile uint32 FFA1R; + uint32 RESERVED4; + volatile uint32 FA1R; + uint32 RESERVED5[8]; + CAN_FilterRegister_Port sFilterRegister[14]; +} CAN_Port; + +/** + * @brief CAN Tx message structure definition + */ +typedef struct +{ + uint32 ID; // CAN ID + uint8 IDE; // CAN_ID_STD for standard and CAN_ID_EXT for extended + uint8 RTR; + uint8 DLC; + uint8 Data[8]; + uint8 FMI; +} CanMsg; + +/* Functions */ +CAN_STATUS can_init_enter(CAN_Port* CANx); +CAN_STATUS can_init_leave(CAN_Port* CANx); +CAN_STATUS can_init(CAN_Port *CANx, uint32 mode, uint8 speed); +CAN_STATUS can_deinit(CAN_Port* CANx); +CAN_STATUS can_filter(CAN_Port* CANx, uint8 filter_idx, CAN_FIFO fifo_number, CAN_FILTER_SCALE scale, CAN_FILTER_MODE mode, uint32 fr1, uint32 fr2); +CAN_STATUS can_set_timing(CAN_Port* CANx, uint32 timing); +CAN_STATUS can_set_mode(CAN_Port* CANx, uint32 mode); +CAN_STATUS can_gpio_map(CAN_Port* CANx, CAN_GPIO_MAP map_mode); +CAN_STATUS can_status(void); +void can_cancel(CAN_Port* CANx, uint8 mbx); +void can_rx_queue_clear(void); +uint8 can_rx_available(void); +CanMsg* can_rx_queue_get(void); +CanMsg* can_read(CAN_Port* CANx, CAN_FIFO fifo, CanMsg* msg); +void can_rx_release(CAN_Port* CANx, CAN_FIFO fifo); +void can_rx_queue_free(void); +CAN_TX_MBX can_transmit(CAN_Port* CANx, CanMsg* msg); +CAN_STATUS can_tx_status(CAN_Port* CANx, CAN_TX_MBX mbx); + +/** + * @brief Set pooling mode + */ +static inline void can_set_pool_mode(CAN_Port* CANx) +{ + CANx->IER &= ~(CAN_IER_FMPIE0 | CAN_IER_FMPIE1); +} + +/** + * @brief Set interrupt mode + */ +static inline void can_set_irq_mode(CAN_Port* CANx) +{ + CANx->IER |= (CAN_IER_FMPIE0 | CAN_IER_FMPIE1); +} + +static inline uint8 can_fifo_ready(CAN_Port* CANx, CAN_FIFO fifo) +{ + if (fifo == CAN_FIFO0) + return (uint8)(CANx->RF0R & CAN_RF0R_FMP0); + return (uint8)(CANx->RF1R & CAN_RF1R_FMP1); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/STM32F1/libraries/OLED_I2C/OLED_I2C.cpp b/STM32F1/libraries/OLED_I2C/OLED_I2C.cpp index 8b59f9d8c..fbdefb651 100644 --- a/STM32F1/libraries/OLED_I2C/OLED_I2C.cpp +++ b/STM32F1/libraries/OLED_I2C/OLED_I2C.cpp @@ -283,7 +283,7 @@ void OLED::printNumF(double num, byte dec, int x, int y, char divider, int lengt if (divider != '.') { - for (int i=0; iTWI_THR = scrbuf[b]; while ((twi->TWI_SR & TWI_SR_TXRDY) != TWI_SR_TXRDY) {}; */ - static byte aa=scrbuf[b]; + byte aa=scrbuf[b]; WIRE_WRITE(aa); } diff --git a/STM32F1/libraries/RTClock/examples/BluePill-RTClock-test/BluePill-RTClock-test.ino b/STM32F1/libraries/RTClock/examples/BluePill-RTClock-test/BluePill-RTClock-test.ino index d49025a1d..cc78ec59d 100644 --- a/STM32F1/libraries/RTClock/examples/BluePill-RTClock-test/BluePill-RTClock-test.ino +++ b/STM32F1/libraries/RTClock/examples/BluePill-RTClock-test/BluePill-RTClock-test.ino @@ -4,16 +4,16 @@ based on https://github.com/rogerclarkmelbourne/Arduino_STM32 1. Blink on PC13 per 4s or 7s by attachAlarmInterrupt for 10 times - 2. Second counter by attachSecondsInterrpt + 2. Second counter by attachSecondsInterrupt 3. Serial output on(41s) or off(21s) by creatAlarm - 4. change to your timezone in the sketch; . + 4. change to your timezone in the sketch; 3. get Unix epoch time from https://www.epochconverter.com/ ; - 4. last step input the 10 bits number( example: 1503945555) to Serialport ; + 4. last step input the 10 digit number( example: 1503945555) to Serialport ; 5. the clock will be reset to you wanted. - ## Why the 10 bits Unix epoch time be used? + ## Why the 10 digit Unix epoch time be used? ****Because I wanna connect to NTP server by ESP-8266. -****in the library. getNtpTime() will return this 10 bits Unix epoch time. +****in the library. getNtpTime() will return this 10 digit Unix epoch time. * * 嗨!朋友们, 这是一个STM32F10x系列的RTC应用的例子,希望对你的编码有所帮助 * 这个程序基于https://github.com/rogerclarkmelbourne/Arduino_STM32 , 感谢所有贡献者的付出。 @@ -28,70 +28,110 @@ RTClock rtclock (RTCSEL_LSE); // initialise int timezone = 8; // change to your timezone -time_t tt; -time_t tt1; -tm_t mtt = { 47, 9, 13, 3, 11, 22, 30, 30 }; // init time 47+1970 = 2017 Unix epoch Time counted from 00:00:00 1 Jan 1970 -char weekday1[][7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; // 0,1,2,3,4,5,6 +time_t tt, tt1; +tm_t mtt; uint8_t dateread[11]; int globAlmCount = 0; int lastGlobAlmCount; int SPECAlmCount = 0; int lastSPECAlmCount; -int i = 0; int alarmcount = 3; uint8_t AlarmExchange = 0; bool dispflag = true; -#define LED_PIN PC13 - -// This function is called in the attachSecondsInterrpt +//----------------------------------------------------------------------------- +const char * weekdays[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; +const char * months[] = {"Dummy", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +//----------------------------------------------------------------------------- +uint8_t str2month(const char * d) +{ + uint8_t i = 13; + while ( (--i) && strcmp(months[i], d)!=0 ); + return i; +} +//----------------------------------------------------------------------------- +const char * delim = " :"; +char s[128]; // for sprintf +//----------------------------------------------------------------------------- +void ParseBuildTimestamp(tm_t & mt) +{ + // Timestamp format: "Dec 8 2017, 22:57:54" + sprintf(s, "Timestamp: %s, %s\n", __DATE__, __TIME__); + //Serial.print(s); + char * token = strtok(s, delim); // get first token + // walk through tokens + while( token != NULL ) { + uint8_t m = str2month((const char*)token); + if ( m>0 ) { + mt.month = m; + //Serial.print(" month: "); Serial.println(mt.month); + token = strtok(NULL, delim); // get next token + mt.day = atoi(token); + //Serial.print(" day: "); Serial.println(mt.day); + token = strtok(NULL, delim); // get next token + mt.year = atoi(token) - 1970; + //Serial.print(" year: "); Serial.println(mt.year); + token = strtok(NULL, delim); // get next token + mt.hour = atoi(token); + //Serial.print(" hour: "); Serial.println(mt.hour); + token = strtok(NULL, delim); // get next token + mt.minute = atoi(token); + //Serial.print(" minute: "); Serial.println(mt.minute); + token = strtok(NULL, delim); // get next token + mt.second = atoi(token); + //Serial.print(" second: "); Serial.println(mt.second); + } + token = strtok(NULL, delim); + } +} +//----------------------------------------------------------------------------- +// This function is called in the attachSecondsInterrupt +//----------------------------------------------------------------------------- void SecondCount () { tt++; } -// This function is called in the attachAlarmInterrpt +//----------------------------------------------------------------------------- +// This function is called in the attachAlarmInterrupt +//----------------------------------------------------------------------------- void blink () { - digitalWrite(LED_PIN, !digitalRead(LED_PIN)); + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); globAlmCount++; - //tt++; } - +//----------------------------------------------------------------------------- void OnOffSerial () { dispflag = !dispflag; SPECAlmCount++; } - +//----------------------------------------------------------------------------- void setup() { lastGlobAlmCount = ~globAlmCount; lastSPECAlmCount = ~SPECAlmCount; Serial.begin(115200); - pinMode(LED_PIN, OUTPUT); - tt = rtclock.makeTime(mtt); - rtclock.setTime(tt); + pinMode(LED_BUILTIN, OUTPUT); + //while (!Serial); delay(1000); + ParseBuildTimestamp(mtt); // get the Unix epoch Time counted from 00:00:00 1 Jan 1970 + tt = rtclock.makeTime(mtt) + 25; // additional seconds to compensate build and upload delay + rtclock.setTime(tt); tt1 = tt; rtclock.attachAlarmInterrupt(blink);// Call blink rtclock.attachSecondsInterrupt(SecondCount);// Call SecondCount } - +//----------------------------------------------------------------------------- void loop() { - while (Serial.available()) - { dateread[i] = Serial.read(); - if (i < 11) { - i++; - } - else { - i = 0; - tt = (dateread[0] - '0') * 1000000000 + (dateread[1] - '0') * 100000000 + (dateread[2] - '0') * 10000000 + (dateread[3] - '0') * 1000000 + (dateread[4] - '0') * 100000; - tt += (dateread[5] - '0') * 10000 + (dateread[6] - '0') * 1000 + (dateread[7] - '0') * 100 + (dateread[8] - '0') * 10 + (dateread[9] - '0'); - rtclock.TimeZone(tt, timezone); //adjust to your local date - rtclock.setTime(rtclock.TimeZone(tt, timezone)); + if ( Serial.available()>10 ) { + for (uint8_t i = 0; i<11; i++) { + dateread[i] = Serial.read(); } + Serial.flush(); + tt = atol((char*)dateread); + rtclock.setTime(rtclock.TimeZone(tt, timezone)); //adjust to your local date } - if (lastGlobAlmCount != globAlmCount | lastSPECAlmCount != SPECAlmCount ) { + if (lastGlobAlmCount != globAlmCount || lastSPECAlmCount != SPECAlmCount ) { if (globAlmCount == 10) { // to detachAlarmInterrupt and start creatAlarm after 10 times about 110s rtclock.detachAlarmInterrupt(); globAlmCount = 0; @@ -117,23 +157,13 @@ void loop() } } } - if (tt1 != tt & dispflag == true ) + if (tt1 != tt && dispflag == true ) { tt1 = tt; - //rtclock.breakTime(tt, mtt); - Serial.print("Date: "); - Serial.print(rtclock.day()); - Serial.print("- "); - Serial.print(rtclock.month()); - Serial.print(" "); - Serial.print(rtclock.year() + 1970); - Serial.print(" "); - Serial.print(weekday1[rtclock.weekday()]); - Serial.print(" Time: "); - Serial.print(rtclock.hour()); - Serial.print(" : "); - Serial.print(rtclock.minute()); - Serial.print(" : "); - Serial.println(rtclock.second()); + // get and print actual RTC timestamp + rtclock.breakTime(rtclock.now(), mtt); + sprintf(s, "RTC timestamp: %s %u %u, %s, %02u:%02u:%02u\n", + months[mtt.month], mtt.day, mtt.year+1970, weekdays[mtt.weekday], mtt.hour, mtt.minute, mtt.second); + Serial.print(s); } } diff --git a/STM32F1/libraries/RTClock/examples/RTCAdjust/RTCAdjust.ino b/STM32F1/libraries/RTClock/examples/RTCAdjust/RTCAdjust.ino new file mode 100644 index 000000000..954cbe100 --- /dev/null +++ b/STM32F1/libraries/RTClock/examples/RTCAdjust/RTCAdjust.ino @@ -0,0 +1,256 @@ +/* + * RTCAdjust.cpp + * + * Created on: Dec 10, 2018 + * + * @license MIT use at your own risk + * + * Copyright 2018 andrew goh + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +#include +#include "rtadjust.h" + +/* note that the adjustment functions needs this RTClock + * if you rename variable rt, update rtadjust.h so that the + * extern refers to this RTClock*/ +RTClock rt(RTCSEL_LSE); // initialise + +#define BUFLEN 100 +uint8_t ind = 0; +char cmd = 0; +char buf[BUFLEN]; +tm_t tm; + +enum LineState { + KEY, + LINE +} state; + +void processkey(); +void showtime(); +void synctime(char *buf, int len); +void settime(char *buf, int len); +void calibrate(char *buf, int len); +void setdriftdur(char *buf, int len); +void help(); +void clearbuf(); + +void setup() { + state = LineState::KEY; + + Serial.begin(115200); + + /* initialise access to backup registers, + * this is necessary due to the use of backup registers */ + bkp_init(); + + /* adjust rtc */ + adjtime(); + + //turn on the led basic check + //pinMode(LED_BUILTIN, OUTPUT); + //digitalWrite(LED_BUILTIN, HIGH); +} + +void loop() { + if(Serial.available()) + processkey(); + else + delay(1); +} + +void processkey() { + char c = Serial.read(); + //echo the char; + Serial.print(c); + if( state == LineState::LINE ) { + if (ind < BUFLEN && c != '\r') { + if(c == 8 || c == 127 ) // backspace + ind--; + else + buf[ind++] = c; // copy the chars into buf + } else { + Serial.println(); + switch(cmd) { + case 's': + synctime(buf,ind); + break; + case 'T': + settime(buf,ind); + break; + case 'c': + calibrate(buf,ind); + break; + case 'x': + setdriftdur(buf,ind); + break; + default: + break; + } + state = LineState::KEY; + cmd = 0; + clearbuf(); + } + } else { + switch(c) { + case 't': + showtime(); + break; + case 's': + state = LineState::LINE; + clearbuf(); + cmd = 's'; + break; + case 'T': + state = LineState::LINE; + clearbuf(); + cmd = 'T'; + break; + case 'c': + state = LineState::LINE; + clearbuf(); + cmd = 'c'; + break; + case 'x': + state = LineState::LINE; + clearbuf(); + cmd = 'x'; + break; + case 'h': + case 'H': + case '?': + help(); + break; + default: + break; + } + } +} + + +void showtime() { + // get and print actual RTC timestamp + rt.breakTime(rt.now(), tm); + memset(buf,0,BUFLEN); + sprintf(buf, "RTC timestamp: %u-%u-%u, %02u:%02u:%02u", + tm.year+1970, tm.month, tm.day, tm.hour, tm.minute, tm.second); + Serial.println(buf); + clearbuf(); + + Serial.print("last adj:"); + rt.breakTime(getbkptime(), tm); + memset(buf,0,BUFLEN); + sprintf(buf, "RTC timestamp: %u-%u-%u, %02u:%02u:%02u", + tm.year+1970, tm.month, tm.day, tm.hour, tm.minute, tm.second); + Serial.println(buf); + clearbuf(); + +#ifdef INCR_CALIBRATE + Serial.print("init adj:"); + rt.breakTime(getinitadjtime(), tm); + memset(buf,0,BUFLEN); + sprintf(buf, "RTC timestamp: %u-%u-%u, %02u:%02u:%02u", + tm.year+1970, tm.month, tm.day, tm.hour, tm.minute, tm.second); + Serial.println(buf); + clearbuf(); +#endif + + Serial.print(F("drift duration, number of seconds for the stm32 rtc to drift 1 secs (faster):")); + Serial.println(getdrift()); + + Serial.print(F("BKP_RTCCR:")); + Serial.println(getrtccr()); +} + +void synctime(char *buf, int len) { + if (len == BUFLEN) buf[BUFLEN-1] = 0; //terminate the string for safety + if(parsetimestamp(buf, tm) <0) { + Serial.println(F("invalid date/time")); + return; + } + + time_t time = rt.makeTime(tm); + /* this call the actual function to set the RTC and update + * the last adjusted time simultaneously + */ + synctime(time); +} + + + +void calibrate(char *buf, int len) { + if (len == BUFLEN) buf[BUFLEN-1] = 0; //terminate the string for safety + if(parsetimestamp(buf, tm) <0) { + Serial.println(F("invalid date/time")); + return; + } + + time_t time = rt.makeTime(tm); + + /* this call the calibratertc() function to calculate + * the drift duration + */ + calibratertc(time); +} + +/* + * this function sets the rtc directly by-passing all the adjustments + * + * note that this function is used during tests to simulate drifts etc + * hence it is not featured in help(); + * + * in a normal context use synctime() to set the RTC time so that + * the last adjustment date/time is updated as well + */ +void settime(char *buf, int len) { + if (len == BUFLEN) buf[BUFLEN-1] = 0; //terminate the string for safety + if(parsetimestamp(buf, tm) <0) { + Serial.println(F("invalid date/time")); + return; + } + + rt.setTime(tm); +} + +void setdriftdur(char *buf, int len) { + if (len == BUFLEN) buf[BUFLEN-1] = 0; //terminate the string for safety + int16_t drift_dur = atoi(buf); + /* this funciton updates the drift duration directly */ + setbkpdrift(drift_dur); +} + +void help() { + Serial.println(F("h, H, ? - display help, this message")); + Serial.println(F("t - current time")); + Serial.println(F("sYYYY-MM-DD HH:MM:SS - sync/set time")); + Serial.println(F("cYYYY-MM-DD HH:MM:SS - calibrate rtc")); + Serial.println(F("where YYYY-MM-DD HH:MM_SS - is the current accurate time")); + Serial.println(F("xnnnn - set the drift duration where nnnn is the drift duration")); + Serial.println(F(" number of seconds for the stm32 rtc to drift 1 secs (faster)")); + Serial.println(F("the s, c, x commands needs to end with a carriage return at the end of line")); + Serial.println(); +} + +void clearbuf() { + ind = 0; + memset(buf,0,BUFLEN); +} + diff --git a/STM32F1/libraries/RTClock/examples/RTCAdjust/readme.md b/STM32F1/libraries/RTClock/examples/RTCAdjust/readme.md new file mode 100644 index 000000000..5a7956c6f --- /dev/null +++ b/STM32F1/libraries/RTClock/examples/RTCAdjust/readme.md @@ -0,0 +1,181 @@ +# stm32duino RTC drift adjustment + +This Arduino sketch is built based on Stm32duino libmaple core. +It provides an example of how one could adjust for RTC (real time clock) drifts if one is using a 32k crystal that drift significantly. + +For drifts that is less than (304 secs ~ 5 minutes) per month. STM has published an appnote for a different means of slowing down the RTC clock +[AN2604 STM32F101xx and STM32F103xx RTC calibration](https://www.st.com/content/ccc/resource/technical/document/application_note/ff/c1/4f/86/4e/29/42/d1/CD00167326.pdf/files/CD00167326.pdf/jcr:content/translations/en.CD00167326.pdf). +This is possibly simpler and more accurate. *this feature has been added in this implementation* + +Due to the use of backup registers, you need to power the board/stm32 on VBAT (e.g. using a coin cell) so that the backup memory is maintained. And as the last adjusted date/time (saved in backup register 8 and 9) and drift duration (saved in backup register 7), if power is removed and the backup memory is lost, you would need to re-do the calibration again. + +## Building and running the sketch + +Build and run the sketch based on STM32duino libmaple core using the Arduino IDE. +The files relevant to the sketch are: + +* RTCAdjust.ino - this is the sketch itself +* rtadjust.h - utility functions for the adjustments +* rtadjust.cpp - utility functions for the adjustments + +The sketch is a demo that runs on the serial console, the commands on the serial console are + +* h, H, ? - display help this message +* t - display current time +* sYYYY-MM-DD HH:MM:SS - sync/set time +* cYYYY-MM-DD HH:MM:SS - calibrate rtc + where YYYY-MM-DD HH:MM_SS - is the current accurate time +* xnnnn - set the drift duration where nnnn is the drift duration + number of seconds for the stm32 rtc to drift 1 secs (faster) + +t command displays the time and some additional info related to the adjustments e.g. +``` +RTC timestamp: 2018-12-10, 00:00:01 +last adj:RTC timestamp: 2018-12-10, 00:00:00 +drift duration, number of seconds for the stm32 rtc to drift 1 secs (faster): 3350 +``` +## How do the adjustments work + +In your wiring/arduino setup() function, make it call the function *adjtime();*, e.g. +``` +void setup() { + /* initialise access to backup registers, + * this is necessary due to the use of backup registers */ + bkp_init(); + + /* adjust rtc */ + adjtime(); +} +``` +This function would make RTC adjustments based a calibrated drift duration or offset which i named as the drift duration. The drift duration is number of seconds for the stm32 rtc to drift 1 seconds (faster) + + +## How to do the calibrations using the demo sketch / app + +This app/sketch itself has the commands to do the calibration. To do the calibration: + +1. run sYYYY-MM-DD HH:MM:SS - sync/set time + where YYYY-MM-DD HH:MM_SS - is the current accurate date/time + This would set the RTC and the last adjustment date/time to the date / time you supplied. + The last adjustment date/time is saved in 2 backup registers 8 and 9. + +2. after a day or more, a longer period cumulates more drift and increase accuracy + run cYYYY-MM-DD HH:MM:SS - calibrate rtc + where YYYY-MM-DD HH:MM_SS - is the current accurate date/time at the time you do the calibration. + + This would compute the drift duration and save it in backup register 7. + +3. reset the device and check the time after the calibration. if setup() calls adjtime(), the RTC would show the drift adjusted/compensated date/time. + +## Incremental calibration mode + +incremental calibration is enabled by the define INCR_CALIBRATE in rtcadjust.h + +``` + #define INCR_CALIBRATE +``` + +Incremental calibration allows you to call calibratertc() repeatedly. It works by saving the +initial time when you call synctime() - step 1 above, and computing the total time elapsed between +synctime() to calibratertc() step 2 above. + +note that this use 2 additional backup registers making it a total of 5 backup registers used, +without this 3 registers are used. +However, without incremental calibration, you can only call calibratertc() once after the initial +synctime() call + +you need to call bkp_init() and adjtime() in setup() prior to doing incremental calibration +with calibratertc(). calibratertc() computes the drift adjustments by adding up the +cumulative adjustment each time you call calibratertc(). By doing this, it accounts for the smaller +differential errors detected from the initial synctime() call, and hopefully more accurate adjustments + over a longer time period. + +``` +void setup() { + /* initialise access to backup registers, + * this is necessary due to the use of backup registers */ + bkp_init(); + + /* adjust rtc */ + adjtime(); +} +``` + +## How to do the adjustments and calibrations work in actual code? + +1. in setup() run adjtime() + +``` +void setup() { + /* initialise access to backup registers, + * this is necessary due to the use of backup registers */ + bkp_init(); + + /* adjust rtc */ + adjtime(); +} +``` +This would make the adjustments every time the sketch is started. +Note that adjtime() does the adjustment no more than once in 24 hours. This design is to prevent frequent adjustments which could result in cumulative errors as the granuality of adjustments is 1 sec. if you prefer for the adjustments to be more frequent you could comment the statement in the function. + +2. The function to set the RTC and last adjusted date time is: + +``` +/* synctime() set the RTC clock and saves the time in backup register 8 and 9 + * as the time of the last adjustment + * + * call this function with the current accurate clock time to set the rtc + * + * @param time the time_t value of the current accurate clock time + */ +void synctime(time_t time_now); +``` + +3. The function to perform the RTC calibration to compute the drift duration is + +``` +/* this function calibrate the rtc by computing the drift_duration + * + * call this function with the current accurate clock time to calibrate the rtc + * + * it is recommended to set the RTC time with the time you provide to calibratertc() + * after calling this function to calibrate the RTC, that ensures a time sync after + * calibratertc(). + * + * however, call rt.setTime(time_now) and not synctime() as synctime would change the + * initial time sync timestamp needed by this calibratertc() function + * + * if the cumulative delay between current time and the last time when synctime() + * is called is lower than 100, a warning would be displayed that the drift + * granulity is low and may result in inaccuracy of the rtc adjustments + * + * note that if you want to call calibratertc() repeatedly after an initial synctime + * you need to define INCR_CALIBRATE. that would allow you to call calibratertc() + * multiple times after an initial synctime() call. + * + * without INCR_CALIBRATE this function can only be run once to compute + * the drift_duration this is because the time of last adjustment would have + * been updated by adjtime() after calibration and is no longer relevant for purpose of + * computing drift duration + * + * to run it again + * 1) first zero out drift duration using setbkpdrift(0) + * or disconnect VBAT and power to clear backup memory + * next repeat the calibration cycle + * 2) run synctime(time_now) with the accurate clock time + * 3) after a day or more (longer period cumulates more drift and increase accuracy) + * run calibrate(time_now) with the accurate clock time + * + * @param time the time_t value of the current accurate clock time + */ + void calibratertc(time_t time_now); +``` + +4. Dependencies, in the main sketch: + +``` +/* note that the adjustment functions needs this RTClock + * if you rename variable rt, update rtadjust.h so that the + * extern refers to this RTClock*/ +RTClock rt(RTCSEL_LSE); // initialise +``` \ No newline at end of file diff --git a/STM32F1/libraries/RTClock/examples/RTCAdjust/rtadjust.cpp b/STM32F1/libraries/RTClock/examples/RTCAdjust/rtadjust.cpp new file mode 100644 index 000000000..721c71b71 --- /dev/null +++ b/STM32F1/libraries/RTClock/examples/RTCAdjust/rtadjust.cpp @@ -0,0 +1,319 @@ +/* + * RTCAdjust.cpp + * + * Created on: Dec 10, 2018 + * + * @license MIT use at your own risk + * + * Copyright 2018 andrew goh + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "rtadjust.h" + + +#define INIT_ADJ_REG_LOW 5 +#define INIT_ADJ_REG_HIGH 6 +#define DRIFT_REG 7 +#define LAST_ADJ_REG_LOW 8 +#define LAST_ADJ_REG_HIGH 9 + + +/* adjust RTC time + * call this from setup() so that the sketch updates the rtc when starting up + */ +void adjtime() { + int adj; + time_t now = rt.getTime(); + int last = getbkptime(); + int dur = now - last; + + /* adjust time no more than once in 24 hours + * multiple adjustments could result in cumulative errors + * comment this if you prefer to adjust every time + */ + if(now - last < 24 * 60 * 60) return; + + int driftdur = getdrift(); + if(driftdur != 0) { + adj = dur / driftdur ; // number of sec to subtract + now -= adj; // subtracting as the clock runs fast, change this if you are 'speeding up' the rtc + rt.setTime(now); + setbkptime(now); + } +} + +/* synctime() set the RTC clock and saves the time in backup register 8 and 9 + * as the time of the last adjustment + * + * call this function with the current accurate clock time to set the rtc + * + * @param time the time_t value of the current accurate clock time + */ +void synctime(time_t time_now) { + rt.setTime(time_now); + +#ifdef INCR_CALIBRATE + setinitadjtime(time_now); + setbkptime(time_now); +#else + setbkptime(time_now); +#endif +} + + +/* this function calibrate the rtc by computing the drift_duration + * + * call this function with the current accurate clock time to calibrate the rtc + * + * it is recommended to set the RTC time with the time you provide to calibratertc() + * after calling this function to calibrate the RTC, that ensures a time sync after + * calibratertc(). + * + * however, call rt.setTime(time_now) and not synctime() as synctime would change the + * initial time sync timestamp needed by this calibratertc() function + * + * if the cumulative delay between current time and the last time when synctime() + * is called is lower than 100, a warning would be displayed that the drift + * granulity is low and may result in inaccuracy of the rtc adjustments + * + * note that if you want to call calibratertc() repeatedly after an initial synctime + * you need to define INCR_CALIBRATE. that would allow you to call calibratertc() + * multiple times after an initial synctime() call. + * + * without INCR_CALIBRATE this function can only be run once to compute + * the drift_duration this is because the time of last adjustment would have + * been updated by adjtime() after calibration and is no longer relevant for purpose of + * computing drift duration + * + * to run it again + * 1) first zero out drift duration using setbkpdrift(0) + * or disconnect VBAT and power to clear backup memory + * next repeat the calibration cycle + * 2) run synctime(time_now) with the accurate clock time + * 3) after a day or more (longer period cumulates more drift and increase accuracy) + * run calibrate(time_now) with the accurate clock time + * + * @param time the time_t value of the current accurate clock time + */ +void calibratertc(time_t time_now) { + + int cur_drift = getdrift(); + int last = 0; +#ifdef INCR_CALIBRATE + last = getinitadjtime(); +#else + if(cur_drift != 0) { + Serial.print(F("err: rtc has been calibrated prior, ")); + Serial.println(F("zero out drift duration before calibrating again")); + return; + } + last = getbkptime(); +#endif + int now = rt.getTime(); + int elapsed = time_now - last; + Serial.print(F("elapsed (s):")); + Serial.println(elapsed); + int drift = now - time_now ; + Serial.print(F("drift (s):")); + Serial.println(drift); + Serial.print("previous drift:"); + Serial.println(cur_drift); + if (drift < 100) { + Serial.print(F("warn: drift granuity is low, 1 sec difference results in ")); + float d = 100.0 / (drift + 1.0); + Serial.print(d); + Serial.println(F(" % error")); + } + int drift_dur = elapsed / drift; +#ifdef INCR_CALIBRATE + if(cur_drift != 0) + drift_dur = cur_drift * drift_dur / (cur_drift + drift_dur); +#endif + + Serial.print(F("drift duration, number of seconds for the stm32 rtc to drift 1 secs (faster):")); + Serial.println(drift_dur); + + int rtccr_max = 1048576 / 127; + if (drift_dur > rtccr_max) { //about less than 314 secs ~ 5 mins drift per month + + /*if the drift is better than 1048576 / 127 ~ 1:8256 the rtc hardware can do the + * adjustment, in this case just setup BKP_RTCCR register calibration value and let the + * RTC hardware take care of the drift adjustment. this only works if the RTC + * runs faster than accurate time + * + * see AN2604 STM32F101xx and STM32F103xx RTC calibration + * https://www.st.com/content/ccc/resource/technical/document/application_note/ff/c1/4f/86/4e/29/42/d1/CD00167326.pdf/files/CD00167326.pdf/jcr:content/translations/en.CD00167326.pdf + */ + + uint8_t cal = drift_dur * 127 / 1048576; + setrtccr(cal); + //set the drift duration as zero - no software adjustments needed + setbkpdrift(0); + } else if (drift_dur > -32768 && drift_dur <= rtccr_max) { + setbkpdrift(drift_dur & 0xffff); //bkp register is only 16 bits + } else + //drift duration < -32767 ! (about slower by less than 10 secs per month) + //no adjustment can't store in 16 bit bkp register + setbkpdrift(0); + +} + +/* set the time of init adjustment in backup register 8 and 9 + * @param time this is the time_t value to be saved + */ +void setinitadjtime(time_t time) { + bkp_enable_writes(); + bkp_write(INIT_ADJ_REG_LOW, time & 0xffff); + bkp_write(INIT_ADJ_REG_HIGH, time >> 16); + bkp_disable_writes(); +} + +/* get the time of init adjustment from backup register 8 and 9 + * @return the time_t value of the time saved + */ +time_t getinitadjtime() { + time_t time; + time = bkp_read(INIT_ADJ_REG_LOW); + time |= bkp_read(INIT_ADJ_REG_HIGH) << 16; + return time; +} + + +/* set the time of last adjustment in backup register 8 and 9 + * @param time this is the time_t value to be saved + */ +void setbkptime(time_t time) { + bkp_enable_writes(); + bkp_write(LAST_ADJ_REG_LOW, time & 0xffff); + bkp_write(LAST_ADJ_REG_HIGH, time >> 16); + bkp_disable_writes(); +} + +/* get the time of last adjustment from backup register 8 and 9 + * @return the time_t value of the time saved + */ +time_t getbkptime() { + time_t time; + time = bkp_read(LAST_ADJ_REG_LOW); + time |= bkp_read(LAST_ADJ_REG_HIGH) << 16; + return time; +} + +/* save the drift duration in backup register 7 + * number of seconds for the stm32 rtc to drift 1 secs (faster) + * from an accurate time source + * + * @param adj number of seconds for the stm32 rtc to drift 1 secs (faster) + * from an accurate time source + * + */ +void setbkpdrift(int16_t drift_dur) { + bkp_enable_writes(); + bkp_write(DRIFT_REG, drift_dur); + bkp_disable_writes(); +} + +/* get the drift duration from backup register 7 + * @return number of seconds for the stm32 rtc to drift 1 secs (faster) + * from an accurate time source + * + */ +int16_t getdrift() { + return bkp_read(DRIFT_REG); +} + + +/* update BKP_RTCCR register calibration value + * see AN2604 STM32F101xx and STM32F103xx RTC calibration + * https://www.st.com/content/ccc/resource/technical/document/application_note/ff/c1/4f/86/4e/29/42/d1/CD00167326.pdf/files/CD00167326.pdf/jcr:content/translations/en.CD00167326.pdf + * as well as RM0008 reference manual for stm32f1x section 6 Backup registers (BKP) page 80 + * section 6.4.2 RTC clock calibration register (BKP_RTCCR) page 82 + * + * there are reports that this freezes, reason is not clear + * + * @param cal the calibration value according to AN2604 STM32F101xx and STM32F103xx RTC calibration + * + */ +void setrtccr(uint8_t cal) { + bkp_enable_writes(); + uint16_t val = 0; + //calibration value is the 1st 7 bits of RTCCR + //we zero out the other bits as it is not needed + BKP->regs->RTCCR = cal & 0x7f; + bkp_disable_writes(); +} + +/* retrieve the rtccr calibration value + * + * @return rtccr calibration value + */ +uint8_t getrtccr() { + return (BKP->regs->RTCCR) & 0x7f; +} + +//const char * delim = " -:"; +/* utility function to parse entered timestamp + * format yyyy-mm-dd hh:mm:ss + * */ +int8_t parsetimestamp(char *buf, tm_t &tm) { + int8_t i = 0; + char *token = strtok(buf, " -:"); // get first token + // walk through tokens + while( token != NULL ) { + i++; + int num = atoi(token); + //Serial.print(i); + //Serial.print(' '); + //Serial.println(num); + switch(i) { + case 1: + tm.year = num - 1970; + break; + case 2: + tm.month = num; + break; + case 3: + tm.day = num; + break; + case 4: + tm.hour = num; + break; + case 5: + tm.minute = num; + break; + case 6: + tm.second = num; + break; + default: + break; + } + token = strtok(NULL, " -:"); // get next token + } + if (i==6) //if we have 6 tokens assume it is correct ;p + return 0; + else + return -1; +} + + + + diff --git a/STM32F1/libraries/RTClock/examples/RTCAdjust/rtadjust.h b/STM32F1/libraries/RTClock/examples/RTCAdjust/rtadjust.h new file mode 100644 index 000000000..591777f5e --- /dev/null +++ b/STM32F1/libraries/RTClock/examples/RTCAdjust/rtadjust.h @@ -0,0 +1,158 @@ +/* + * rtadjust.h + * + * Created on: Dec 10, 2018 + * + * @license MIT use at your own risk + * + * Copyright 2018 andrew goh + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef RTADJUST_H_ +#define RTADJUST_H_ +#include + +/* allows incremental calibration by calling calibratertc() repeatedly + * note that this use 2 additional backup registers making it a total of 5 backup registers used + * without this 3 registers are used + * however, without incremental adjustment, you can only call calibratertc() + * once after calling synctime() + */ +#define INCR_CALIBRATE + +/* adjust RTC time + * call this from setup() so that the sketch updates the rtc when starting up + */ +void adjtime(); + +/* synctime() set the RTC clock and saves the time in backup register 8 and 9 + * as the time of the last adjustment + * + * call this function with the current accurate clock time to set the rtc + * + * @param time the time_t value of the current accurate clock time + */ +void synctime(time_t time_now); + +/* this function calibrate the rtc by computing the drift_duration + * + * call this function with the current accurate clock time to calibrate the rtc + * + * it is recommended to set the RTC time with the time you provide to calibratertc() + * after calling this function to calibrate the RTC, that ensures a time sync after + * calibratertc(). + * + * however, call rt.setTime(time_now) and not synctime() as synctime would change the + * initial time sync timestamp needed by this calibratertc() function + * + * if the cumulative delay between current time and the last time when synctime() + * is called is lower than 100, a warning would be displayed that the drift + * granulity is low and may result in inaccuracy of the rtc adjustments + * + * note that if you want to call calibratertc() repeatedly after an initial synctime + * you need to define INCR_CALIBRATE. that would allow you to call calibratertc() + * multiple times after an initial synctime() call. + * + * without INCR_CALIBRATE this function can only be run once to compute + * the drift_duration this is because the time of last adjustment would have + * been updated by adjtime() after calibration and is no longer relevant for purpose of + * computing drift duration + * + * to run it again + * 1) first zero out drift duration using setbkpdrift(0) + * or disconnect VBAT and power to clear backup memory + * next repeat the calibration cycle + * 2) run synctime(time_now) with the accurate clock time + * 3) after a day or more (longer period cumulates more drift and increase accuracy) + * run calibrate(time_now) with the accurate clock time + * + * @param time the time_t value of the current accurate clock time + */ +void calibratertc(time_t time_now); + + + +/* set the time of init adjustment in backup register 8 and 9 + * @param time this is the time_t value to be saved + */ +void setinitadjtime(time_t time); + +/* get the time of init adjustment from backup register 8 and 9 + * @return the time_t value of the time saved + */ +time_t getinitadjtime(); + +/* set the time of last adjustment in backup register 8 and 9 + * @param time this is the time_t value to be saved + */ +void setbkptime(time_t time); + + +/* get the time of last adjustment from backup register 8 and 9 + * @return the time_t value of the time saved + */ +time_t getbkptime(); + + +/* save the drift duration in backup register 7 + * number of seconds for the stm32 rtc to drift 1 secs (faster) + * from an accurate time source + * + * @param adj number of seconds for the stm32 rtc to drift 1 secs (faster) + * from an accurate time source + * + */ +void setbkpdrift(int16_t drift_dur); + +/* get the drift duration from backup register 7 + * @return number of seconds for the stm32 rtc to drift 1 secs (faster) + * from an accurate time source + * + */ +int16_t getdrift(); + + +/* update BKP_RTCCR register calibration value + * see AN2604 STM32F101xx and STM32F103xx RTC calibration + * https://www.st.com/content/ccc/resource/technical/document/application_note/ff/c1/4f/86/4e/29/42/d1/CD00167326.pdf/files/CD00167326.pdf/jcr:content/translations/en.CD00167326.pdf + * as well as RM0008 reference manual for stm32f1x section 6 Backup registers (BKP) page 80 + * section 6.4.2 RTC clock calibration register (BKP_RTCCR) page 82 + * + * @param cal the calibration value according to AN2604 STM32F101xx and STM32F103xx RTC calibration + * + */ +void setrtccr(uint8_t cal); + +/* retrieve the rtccr calibration value + * + * @return rtccr calibration value + */ +uint8_t getrtccr(); + +/* utility function to parse entered timestamp + * format yyyy-mm-dd hh:mm:ss + * */ +int8_t parsetimestamp(char *buf, tm_t &tm); + +/* note that the adjustment functions needs this RTClock + * if you rename variable rt, update this so that the + * extern refers to valid RTClock*/ +extern RTClock rt; + +#endif /* RTADJUST_H_ */ diff --git a/STM32F1/libraries/RTClock/src/RTClock.cpp b/STM32F1/libraries/RTClock/src/RTClock.cpp index e95bead86..8d65c1c18 100755 --- a/STM32F1/libraries/RTClock/src/RTClock.cpp +++ b/STM32F1/libraries/RTClock/src/RTClock.cpp @@ -39,7 +39,7 @@ }//end RTC - RTClock::RTClock(rtc_clk_src src, uint16 prescaler ) { + RTClock::RTClock(rtc_clk_src src, uint32 prescaler ) { switch (src) { case RTCSEL_LSE : { @@ -111,7 +111,7 @@ void RTClock::breakTime(time_t timeInput, tm_t & tmm) time /= 60; // now it is hours tmm.hour = time % 24; time /= 24; // now it is days - tmm.weekday = ((time + 4) % 7); // Monday is day 1 // + 1; // Sunday is day 1 + tmm.weekday = ((time + 3) % 7); // Monday is day 1 year = 0; days = 0; diff --git a/STM32F1/libraries/RTClock/src/RTClock.h b/STM32F1/libraries/RTClock/src/RTClock.h index 71015a586..7e758dbc7 100755 --- a/STM32F1/libraries/RTClock/src/RTClock.h +++ b/STM32F1/libraries/RTClock/src/RTClock.h @@ -27,7 +27,7 @@ typedef struct tm_t { uint8_t year; // years since 1970 uint8_t month; // month of a year - [ 1 to 12 ] uint8_t day; // day of a month - [ 1 to 31 ] - uint8_t weekday; // day of a week (first day is Sunday) - [ 0 to 6 ] + uint8_t weekday; // day of a week (first day is Monday) - [ 0 to 6 ] uint8_t pm; // AM: 0, PM: 1 uint8_t hour; // hour of a day - [ 0 to 23 ] uint8_t minute; // minute of an hour - [ 0 to 59 ] @@ -41,7 +41,7 @@ class RTClock { public: RTClock(); RTClock(rtc_clk_src src ); - RTClock(rtc_clk_src src, uint16 prescaler ); + RTClock(rtc_clk_src src, uint32 prescaler ); //~RTClock(); //to implement void breakTime(time_t epoch_time, tm_t & tmm); @@ -52,7 +52,9 @@ class RTClock { time_t getTime(); void getTime(tm_t & tmm ); - #define now getTime + + time_t now() { return getTime(); } + void now(tm_t & tmm ) { getTime(tmm); } // non-standard use of now() function, added for compatibility with previous versions of the library uint8_t year(void) { getTime(tmm); return tmm.year; } uint8_t month(void) { getTime(tmm); return tmm.month; } @@ -100,4 +102,4 @@ class RTClock { #endif // _RTCLOCK_H_ - \ No newline at end of file + diff --git a/STM32F1/libraries/RTClock/src/utility/rtc_util.c b/STM32F1/libraries/RTClock/src/utility/rtc_util.c index 3c8b7d518..3d7a2620a 100644 --- a/STM32F1/libraries/RTClock/src/utility/rtc_util.c +++ b/STM32F1/libraries/RTClock/src/utility/rtc_util.c @@ -168,8 +168,10 @@ uint32 rtc_get_count() { rtc_clear_sync(); rtc_wait_sync(); rtc_wait_finished(); - h = RTC->regs->CNTH & 0xffff; - l = RTC->regs->CNTL & 0xffff; + do { + h = RTC->regs->CNTH & 0xffff; + l = RTC->regs->CNTL & 0xffff; + } while (h != (RTC->regs->CNTH & 0xffff)); return (h << 16) | l; } @@ -211,8 +213,10 @@ uint32 rtc_get_divider() { rtc_clear_sync(); rtc_wait_sync(); rtc_wait_finished(); - h = RTC->regs->DIVH & 0x000f; - l = RTC->regs->DIVL & 0xffff; + do { + h = RTC->regs->DIVH & 0x000f; + l = RTC->regs->DIVL & 0xffff; + } while (h != (RTC->regs->DIVH & 0x000f)); return (h << 16) | l; } @@ -229,4 +233,4 @@ void rtc_set_alarm(uint32 value) { RTC->regs->ALRL = value & 0xffff; rtc_exit_config_mode(); rtc_wait_finished(); -} \ No newline at end of file +} diff --git a/STM32F1/libraries/RTClock/src/utility/rtc_util.h b/STM32F1/libraries/RTClock/src/utility/rtc_util.h index 7084b0d55..5432de3a5 100644 --- a/STM32F1/libraries/RTClock/src/utility/rtc_util.h +++ b/STM32F1/libraries/RTClock/src/utility/rtc_util.h @@ -52,16 +52,16 @@ extern "C" { #endif typedef struct rtc_reg_map { - __io uint32 CRH; /**< Control register high */ - __io uint32 CRL; /**< Control register high */ - __io uint32 PRLH; /**< Prescaler load register high */ - __io uint32 PRLL; /**< Prescaler load register low */ - __io uint32 DIVH; /**< Prescaler divider register high */ - __io uint32 DIVL; /**< Prescaler divider register low */ - __io uint32 CNTH; /**< Counter register high */ - __io uint32 CNTL; /**< Counter register low */ - __io uint32 ALRH; /**< Alarm register high */ - __io uint32 ALRL; /**< Alarm register low */ + __IO uint32 CRH; /**< Control register high */ + __IO uint32 CRL; /**< Control register high */ + __IO uint32 PRLH; /**< Prescaler load register high */ + __IO uint32 PRLL; /**< Prescaler load register low */ + __IO uint32 DIVH; /**< Prescaler divider register high */ + __IO uint32 DIVL; /**< Prescaler divider register low */ + __IO uint32 CNTH; /**< Counter register high */ + __IO uint32 CNTL; /**< Counter register low */ + __IO uint32 ALRH; /**< Alarm register high */ + __IO uint32 ALRL; /**< Alarm register low */ } rtc_reg_map; /** RTC register map base pointer */ diff --git a/STM32F1/libraries/SDIO/SdioF1.cpp b/STM32F1/libraries/SDIO/SdioF1.cpp index 8957b37d3..e8a15f9a1 100644 --- a/STM32F1/libraries/SDIO/SdioF1.cpp +++ b/STM32F1/libraries/SDIO/SdioF1.cpp @@ -30,7 +30,7 @@ //============================================================================== //#define SDHC_PROCTL_DTW_4BIT 0x01 #define CMD8_RETRIES 10 -#define BUSY_TIMEOUT_MILLIS 1500 +#define BUSY_TIMEOUT_MILLIS 1000 //============================================================================== #define CMD_RESP_NONE SDIO_CMD_WAIT_NO_RESP #define CMD_RESP_R1 SDIO_CMD_WAIT_SHORT_RESP // normal response @@ -61,6 +61,12 @@ #define CMD38_XFERTYP (uint16_t)( CMD38 | CMD_RESP_R1b ) #define ACMD41_XFERTYP (uint16_t)( ACMD41 | CMD_RESP_R3 ) +/* + * ACMD42 to enable disable CD/D3 pull up. Needed for 4bit mode. + */ +const uint8_t ACMD42 = 0X2A; +#define ACMD42_XFERTYP (uint16_t)( ACMD41 | CMD_RESP_R1 ) + #define CMD55_XFERTYP (uint16_t)( CMD55 | CMD_RESP_R1 ) //============================================================================= @@ -69,20 +75,33 @@ static void initSDHC(void); static bool isBusyCMD13(void); static bool isBusyTransferComplete(void); +static bool isBusyTransferCRC(void); //static bool isBusyCommandComplete(); //static bool isBusyCommandInhibit(); static bool readReg16(uint32_t xfertyp, void* data); //static void setSdclk(uint32_t kHzMax); static bool yieldTimeout(bool (*fcn)(void)); +static bool yieldDmaStatus(void); static bool waitDmaStatus(void); static bool waitTimeout(bool (*fcn)(void)); //----------------------------------------------------------------------------- +static const uint32_t IDLE_STATE = 0; +static const uint32_t READ_STATE = 1; +static const uint32_t WRITE_STATE = 2; +volatile uint32_t m_curLba; +volatile uint32_t m_limitLba; +volatile uint8_t m_curState; +volatile uint64_t m_totalReadLbas = 0; +volatile uint64_t m_readErrors = 0; +volatile uint64_t m_writeErrors = 0; +volatile uint64_t m_totalWriteLbas = 0; + #define TRX_RD 0 #define TRX_WR 1 static uint8_t m_dir = TRX_RD; static bool (*m_busyFcn)() = 0; static bool m_initDone = false; -static uint32_t m_lba; // for raw non-DMA read(write)Start, read(write)Data, read(write)Stop +//static uint32_t m_lba; // for raw non-DMA read(write)Start, read(write)Data, read(write)Stop static uint32_t m_cnt; // for raw non-DMA read(write)Start, read(write)Data, read(write)Stop static bool m_version2; static bool m_highCapacity; @@ -96,28 +115,29 @@ static uint32_t m_ocr; static cid_t m_cid; static csd_t m_csd; static uint32_t t = 0; + +uint32_t aligned[128]; // temporary buffer for misaligned buffers //============================================================================= -/* - * Todo Remove this or change it, but rather remove since this can be checked with debugger. - */ + #if USE_DEBUG_MODE #define DBG_PRINT() { \ Serial.write('_'); Serial.print(__FUNCTION__); Serial.write('_'); Serial.print(__LINE__); Serial.print(": "); \ - Serial.print("DMA->LISR: "); Serial.print(SDIO_DMA_DEV->regs->LISR, HEX); \ + Serial.print("DMA->ISR: 0x"); Serial.print(SDIO_DMA_DEV->regs->ISR, HEX); \ /*Serial.print("DMA->HISR: "); Serial.println(SDIO_DMA_DEV->regs->HISR, HEX);*/ \ - Serial.print(", DMA->CR: "); Serial.print(SDIO_DMA_DEV->regs->STREAM[SDIO_DMA_CHANNEL].CR, HEX); \ - Serial.print(", DMA->NDTR: "); Serial.print(SDIO_DMA_DEV->regs->STREAM[SDIO_DMA_CHANNEL].NDTR, HEX); \ - /**/Serial.print(", DMA->PAR: "); Serial.print(SDIO_DMA_DEV->regs->STREAM[SDIO_DMA_CHANNEL].PAR, HEX); \ - /**/Serial.print(", DMA->M0AR: "); Serial.print(SDIO_DMA_DEV->regs->STREAM[SDIO_DMA_CHANNEL].M0AR, HEX); \ - Serial.print(", DMA->FCR: "); Serial.print(SDIO_DMA_DEV->regs->STREAM[SDIO_DMA_CHANNEL].FCR, HEX); \ + Serial.print(", DMA->CCR: 0x"); Serial.print(SDIO_DMA_DEV->regs->CCR4, HEX); \ + Serial.print(", DMA->CNDTR: "); Serial.print(SDIO_DMA_DEV->regs->CNDTR4,DEC); \ + /**/Serial.print(", DMA->CPAR: 0x"); Serial.print(SDIO_DMA_DEV->regs->CPAR4, HEX); \ + /**/Serial.print(", DMA->CMAR: 0x"); Serial.print(SDIO_DMA_DEV->regs->CMAR4, HEX); \ + Serial.print(", DMA->IFCR: 0x"); Serial.print(SDIO_DMA_DEV->regs->IFCR, HEX); \ \ /*Serial.print(" SDIO->POWER: "); Serial.println(SDIO->POWER, HEX);*/ \ - Serial.print(", SDIO->CLKCR: "); Serial.print(SDIO->CLKCR, HEX); \ - Serial.print(", SDIO->DTIMER: "); Serial.print(SDIO->DTIMER, HEX); \ - Serial.print(", SDIO->DCTRL: "); Serial.print(SDIO->DCTRL, HEX); \ + Serial.print(", SDIO->CLKCR: 0x"); Serial.print(SDIO->CLKCR, HEX); \ + Serial.print(", SDIO->DTIMER: 0x"); Serial.print(SDIO->DTIMER, HEX); \ + Serial.print(", SDIO->DCTRL: 0x"); Serial.print(SDIO->DCTRL, HEX); \ /**/Serial.print(", SDIO->DLEN: "); Serial.print(SDIO->DLEN); \ Serial.print(", SDIO->DCOUNT: "); Serial.print(SDIO->DCOUNT); \ - Serial.print(", SDIO->STA: "); Serial.println(SDIO->STA, HEX); \ + Serial.print(", SDIO->STA: 0x"); Serial.println(SDIO->STA, HEX); \ + Serial.print(", SDIO->FIFOCNT: "); Serial.println(SDIO->FIFOCNT); \ /*delay(1);*/ \ } #define DBG_PIN PD0 @@ -131,7 +151,7 @@ static void _panic(const char *message, uint32_t code) { Serial.print(message); Serial.println(code, HEX); //Block the execution with blinky leds - while (1); + while (1) {delay (1);}; /* pinMode(BOARD_LED_PIN, OUTPUT); //pinMode(BOARD_LED2_PIN, OUTPUT); @@ -171,13 +191,14 @@ void yield(void) } val = dma_get_isr_bits(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - if ( val & DMA_ISR_FEIF ) { +/* if ( val & DMA_ISR_FEIF ) { val ^= DMA_ISR_FEIF; dma_clear_isr_bits(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); } +*/ if ( val ) { if (val & DMA_ISR_TEIF) Serial.print(" TEIF"); - if (val & DMA_ISR_DMEIF) Serial.print(" DMEIF"); + //if (val & DMA_ISR_DMEIF) Serial.print(" DMEIF"); //if (val & DMA_ISR_FEIF) Serial.print(" FEIF"); _panic(" - DMA: Data Transmission Error ", val); } @@ -208,7 +229,7 @@ static bool cardCommand(uint16_t xfertyp, uint32_t arg) #if USE_DEBUG_MODE==2 Serial.print("cardCommand: "); Serial.print(xfertyp&SDIO_CMD_CMDINDEX); Serial.print(", arg: "); Serial.print(arg, HEX); #endif - uint8_t resp = sdio_cmd_send(xfertyp, arg); // returns non-zero if fails, zero if OK + uint8_t resp = sdio_cmd_send(xfertyp, arg); // returns non-zero if OK, zero if it fails #if USE_DEBUG_MODE==2 Serial.print(", resp: "); Serial.print(resp, HEX); Serial.print(", SDIO->STA: "); Serial.print(SDIO->STA, HEX); Serial.print(", cmd_resp: "); Serial.print(SDIO->RESP[0], HEX); @@ -264,19 +285,38 @@ static bool isBusyCMD13(void) { } return !(SDIO->RESP[0] & CARD_STATUS_READY_FOR_DATA); } -/*---------------------------------------------------------------------------*/ + +/* + * Returns False if DMA transfer disabled. + * True otherwise + */ +static bool inline isEnabledDMA(void) +{ + return dma_is_enabled(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); +} + +/* + * Returns False if DMA transfer is completed or in error. + * True otherwise + */ static bool isBusyDMA(void) { + if (!isEnabledDMA()) return false; uint8_t isr = dma_get_isr_bits(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - isr &= DMA_ISR_TCIF | DMA_ISR_TEIF; + isr &= DMA_ISR_TCIF | DMA_ISR_TEIF; //if (isr&DMA_ISR_TCIF) dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); return !(isr); // ignore transfer error flag } + /*---------------------------------------------------------------------------*/ +/* + * Returns true while the transfer has not completed + * False when it has completed. + */ static bool isBusyTransferComplete(void) { uint32_t mask = SDIO->STA &(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS); -#if USE_DEBUG_MODE +//#if USE_DEBUG_MODE if ( mask & SDIO_STA_TRX_ERROR_FLAGS ) { Serial.print("XFER ERROR: SDIO->STA: "); Serial.print(SDIO->STA, HEX); if (mask & SDIO_STA_STBITERR) Serial.print(" STBITERR"); @@ -286,13 +326,43 @@ static bool isBusyTransferComplete(void) if (mask & SDIO_STA_DCRCFAIL) Serial.print(" DCRCFAIL"); Serial.println(); } -#endif +//#endif if (mask) { dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); return false; } return true; } + + +/* + * New function, to follow Reference Manual sequence. + * Returns true if still not confirmed DBCKEND: Data block sent/received (CRC check passed) + * False when it has completed the transfer with CRC check. + */ +static bool isBusyTransferCRC(void) +{ + uint32_t mask = SDIO->STA &(SDIO_STA_DBCKEND | SDIO_STA_TRX_ERROR_FLAGS); +#if USE_DEBUG_MODE + if ( mask & SDIO_STA_TRX_ERROR_FLAGS ) { + Serial.print("XFER ERROR: SDIO->STA: "); Serial.print(SDIO->STA, HEX); + if (mask & SDIO_STA_STBITERR) Serial.print(" STBITERR"); + if (mask & SDIO_STA_RXOVERR) Serial.print(" RXOVERR"); + if (mask & SDIO_STA_TXUNDERR) Serial.print(" TXUNDERR"); + if (mask & SDIO_STA_DTIMEOUT) Serial.print(" DTIMEOUT"); + if (mask & SDIO_STA_DCRCFAIL) Serial.print(" DCRCFAIL"); + Serial.println(); + } +#endif + if (mask) { + //dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); + //Serial.print("SDIO->STA SDIO_STA_DBCKEND"); Serial.println(SDIO->STA && SDIO_STA_DBCKEND, HEX); + return false; + } + return true; +} + + /*---------------------------------------------------------------------------*/ static void trxStart(uint8_t* buf, uint32_t n, uint8_t dir) { @@ -305,62 +375,86 @@ static void trxStart(uint8_t* buf, uint32_t n, uint8_t dir) /*---------------------------------------------------------------------------*/ static bool trxStop() { - if (!cardCommand(CMD12_XFERTYP, 0)) { - return sdError(SD_CARD_ERROR_CMD12); - } - if ( t ) { - Serial.print(", in "); Serial.println(millis()-t); - t = 0; - } - return true; + if (!cardCommand(CMD12_XFERTYP, 0)) { + return sdError(SD_CARD_ERROR_CMD12); + } + /* + * Added this to wait to complete on sync. + */ + if (yieldTimeout(isBusyCMD13)) { + return sdError(SD_CARD_ERROR_CMD13); + } + if ( t ) { + Serial.print(", in "); Serial.println(millis()-t); + t = 0; + } + return true; } /*---------------------------------------------------------------------------*/ -static bool dmaTrxStart(uint8_t* buf, uint32_t n, uint8_t dir) +static bool dmaTrxStart(uint32_t n, uint8_t dir) { - m_dir = dir; - if ((3 & (uint32_t)buf) || n == 0) { // check alignment - _panic("- transferStart: unaligned buffer address ", (uint32_t)buf); - return sdError(SD_CARD_ERROR_DMA); - } - if (dir==TRX_RD && yieldTimeout(isBusyCMD13)) { - return sdError(SD_CARD_ERROR_CMD13); - } - uint32_t flags = (SDIO_BLOCKSIZE_512 | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN); + uint32_t flags = (SDIO_BLOCKSIZE_512 | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN); if (dir==TRX_RD) flags |= SDIO_DIR_RX; // setup SDIO to transfer n blocks of 512 bytes sdio_setup_transfer(0x00FFFFFF, n, flags); - // setup SDIO_DMA_DEV stream 3 channel 4 - /* - * Moved to begin. - */ - //dma_init(SDIO_DMA_DEV); - /* - * Todo. Check this, channel must be disabled to change DMA priority, and seems like channel is not completing transfers - */ - //dma_set_priority(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, DMA_PRIORITY_VERY_HIGH); - flags = (DMA_MINC_MODE); - // not extra flag if read - if (dir!=TRX_RD) flags |= DMA_FROM_MEM;// write - dma_setup_transfer(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, &SDIO->FIFO, DMA_SIZE_32BITS, buf, DMA_SIZE_32BITS, flags); - dma_set_num_transfers(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, n>>2); // F1 DMA controller counts each word as 1 data item. - //dma_set_fifo_flags(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, (DMA_FCR_DMDIS | DMA_FCR_FTH_FULL)); // disable direct mode | threshold FULL - dma_clear_isr_bits(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - dma_enable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); + return true; } + +/* + * This one replaces dmaTrxStart, and will just prepare the DMA part, then a new + * one will enable the DMA reception as per the RM. + */ +static bool dmaTrxPrepare(uint8_t* buf, uint32_t n, uint8_t dir) +{ + uint32_t flags; + m_dir = dir; + if ((3 & (uint32_t)buf) || n == 0) { // check alignment + _panic("- transferStart: unaligned buffer address ", (uint32_t)buf); + return sdError(SD_CARD_ERROR_DMA); + } + /* + * No point to wait here again if we always wait before calling this. + if (dir==TRX_RD && yieldTimeout(isBusyCMD13)) { + return sdError(SD_CARD_ERROR_CMD13); + } + */ + + /* + * Following RM 22.3.2. Setup DMA first, SDIO peripheral next + * + */ + flags = (DMA_MINC_MODE); + // not extra flag if read + if (dir!=TRX_RD) flags |= DMA_FROM_MEM;// write + dma_setup_transfer(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, &SDIO->FIFO, DMA_SIZE_32BITS, buf, DMA_SIZE_32BITS, flags); + dma_set_num_transfers(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, n>>2); // F1 DMA controller counts each word as 1 data item. + //dma_set_fifo_flags(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, (DMA_FCR_DMDIS | DMA_FCR_FTH_FULL)); // disable direct mode | threshold FULL + dma_clear_isr_bits(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); + dma_enable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); + + return true; +} + + /*---------------------------------------------------------------------------*/ static bool dmaTrxEnd(bool multi_block) { - if ( !waitDmaStatus() ) { + if(m_curState != READ_STATE){ + if ( yieldTimeout(isBusyTransferComplete) ) { + DBG_PRINT(); + if (m_dir==TRX_RD) + return sdError(SD_CARD_ERROR_READ_CRC); + else + return sdError(SD_CARD_ERROR_WRITE); + } + } + + if ( !yieldDmaStatus() ) { DBG_PRINT(); return sdError(SD_CARD_ERROR_DMA); } - if ( waitTimeout(isBusyTransferComplete) ) { - if (m_dir==TRX_RD) - return sdError(SD_CARD_ERROR_READ_TIMEOUT); - else - return sdError(SD_CARD_ERROR_WRITE_TIMEOUT); - } + if (multi_block) { return trxStop(); } else { @@ -375,6 +469,10 @@ static bool dmaTrxEnd(bool multi_block) // Read 16 byte CID or CSD register. static bool readReg16(uint32_t xfertyp, void* data) { + // It's not safe to call this function if a multiblock read/write is going on. + if (m_curState != IDLE_STATE) { + return false; + } uint8_t* d = reinterpret_cast(data); if (!cardCommand(xfertyp, m_rca)) { return false; // Caller will set errorCode. @@ -389,21 +487,38 @@ static bool readReg16(uint32_t xfertyp, void* data) /*---------------------------------------------------------------------------*/ // Return true if timeout occurs. static bool yieldTimeout(bool (*fcn)()) { + m_busyFcn = fcn; uint32_t m = millis(); while (fcn()) { if ((millis() - m) > BUSY_TIMEOUT_MILLIS) { + m_busyFcn = 0; return true; } yield(); } + m_busyFcn = 0; return false; // Caller will set errorCode. } /*---------------------------------------------------------------------------*/ -static bool waitDmaStatus(void) +static bool yieldDmaStatus(void) { if (yieldTimeout(isBusyDMA)) { + dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); + return false; // Caller will set errorCode. + } + // Did not time out. Disable it and return true. + dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); + return true; +} +/*---------------------------------------------------------------------------*/ +static bool waitDmaStatus(void) +{ + if (waitTimeout(isBusyDMA)) { + dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); return false; // Caller will set errorCode. } + // Did not time out. Disable it and return true + dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); return true; } /*---------------------------------------------------------------------------*/ @@ -419,10 +534,12 @@ static bool waitTimeout(bool (*fcn)(void)) { return false; // Caller will set errorCode. } -uint32_t aligned[128]; // temporary buffer for misaligned buffers + //============================================================================= bool SdioCard::begin(void) { + + uint32_t arg; m_initDone = false; m_errorCode = SD_CARD_ERROR_NONE; m_highCapacity = false; @@ -447,6 +564,7 @@ delay(100); if (!cardCommand(CMD0_XFERTYP, 0)) { return sdError(SD_CARD_ERROR_CMD0); } + delay(50); //small pause after reset command // Try several times for case of reset delay. for (uint32_t i = 0; i < CMD8_RETRIES; i++) { if (cardCommand(CMD8_XFERTYP, 0X1AA)) { @@ -457,7 +575,7 @@ delay(100); break; } } - uint32_t arg = m_version2 ? 0X40300000 : 0x00300000; + arg = m_version2 ? 0X50300000 : 0x00300000; uint32_t m = millis(); do { if (!cardAcmd(0, ACMD41_XFERTYP, arg) || @@ -478,6 +596,7 @@ delay(100); return sdError(SD_CARD_ERROR_CMD3); } m_rca = SDIO->RESP[0] & 0xFFFF0000; + if (!readReg16(CMD9_XFERTYP, &m_csd)) { return sdError(SD_CARD_ERROR_CMD9); } @@ -487,14 +606,21 @@ delay(100); if (!cardCommand(CMD7_XFERTYP, m_rca)) { return sdError(SD_CARD_ERROR_CMD7); } + + arg = 0x00; //bit 0, Connect[1]/Disconnect[0] the 50 KOhm pull-up resistor on CD/DAT3 + if (!cardAcmd(m_rca, ACMD42_XFERTYP, arg)) { + _panic("*** ACMD42 to disconnect D3 pullup failed! ***", 0); + } + // Set card to bus width four. - /* if (!cardAcmd(m_rca, ACMD6_XFERTYP, 2)) { return sdError(SD_CARD_ERROR_ACMD6); } + + // Set SDHC to bus width four. sdio_set_dbus_width(SDIO_CLKCR_WIDBUS_4BIT); - */ +/* // Determine if High Speed mode is supported and set frequency. uint8_t status[64]; // see "Physical Layer Simplified Specification Version 6.00", chapter 4.3.10, Table 4-13. @@ -502,15 +628,17 @@ delay(100); // Function Selection of Function Group 1: bits 379:376, which is low nibble of byte [16] if (cardCMD6(0X00FFFFFF, status) && (2 & status[13]) && cardCMD6(0X80FFFFF1, status) && (status[16] & 0XF) == 1) { - //Serial.println("\n*** 50MHz clock supported ***"); + Serial.println("\n*** 50MHz clock supported ***"); + m_sdClkKhz = 24000; // set clock to 24MHz } else { //_panic("*** Only 25MHz clock supported! ***", 0); + m_sdClkKhz = 8000; // set clock to 24MHz } + */ + // delay seems to be needed for cards that take some time to adjust */ + delay(1); - /* - * Todo Raise clock to 24Mhz once transfers work - */ - m_sdClkKhz = 24000; // set clock to 24MHz + m_sdClkKhz = 18000; // set clock to 24MHz sdio_set_clock(m_sdClkKhz*1000); m_initDone = true; @@ -573,52 +701,157 @@ uint32_t SdioCard::kHzSdClk() { bool SdioCard::readBlock(uint32_t lba, uint8_t* buf) { #if USE_DEBUG_MODE - Serial.print("readBlock: "); Serial.println(lba); //Serial.print(", buf: "); Serial.println((uint32_t)buf, HEX); + Serial.print("readBlock: "); Serial.println(lba); //Serial.print(", buf: "); Serial.println((uint32_t)buf, HEX); #endif - // prepare SDIO and DMA for data read transfer - dmaTrxStart((uint32_t)buf & 3 ? (uint8_t*)aligned : buf, 512, TRX_RD); - // send command to start data transfer - if ( !cardCommand(CMD17_XFERTYP, (m_highCapacity ? lba : 512*lba)) ) { - return sdError(SD_CARD_ERROR_CMD17); - } - if ( dmaTrxEnd(0)) { - if ( (uint32_t)buf & 3 ) { - //memcpy(buf, aligned, 512); - register uint8_t * dst = buf; - register uint8_t * src = (uint8_t *)aligned; - register uint16_t i = 64; - while ( i-- ) { // do 8 byte copies, is much faster than single byte copy - *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; - *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; - } - } - return true; - } - return false; + volatile bool _state = false; + uint16_t retries = 3; + while ( retries-- ){ + /*if (yieldTimeout(isBusyCMD13)) { // wait for previous transmission end + return sdError(SD_CARD_ERROR_CMD13); + } + */ + + if (m_curState != READ_STATE || m_curLba != lba) { +#if USE_DEBUG_MODE + Serial.print("New lba, syncing :"); + Serial.println(lba); +#endif + _state = syncBlocks(); + DBG_PRINT(); + if (!_state) { + return false; + } + m_limitLba = (lba + 1024); //arbitrary limit, tested with 32KB before and worked fine. + // prepare DMA for data read transfer + _state = dmaTrxPrepare((uint32_t)buf & 3 ? (uint8_t*)aligned : buf, 512, TRX_RD); + DBG_PRINT(); + + // prepare SDIO data read transfer 0x8000 = 64*512 + _state = dmaTrxStart(512, TRX_RD); + DBG_PRINT(); + + // send command to start data transfer + _state = cardCommand(CMD18_XFERTYP, (m_highCapacity ? lba : 512*lba)); + DBG_PRINT(); + if ( !_state ) { + return sdError(SD_CARD_ERROR_CMD18); + } + + m_curLba = lba; + m_curState = READ_STATE; + } + else { + // prepare DMA for data read transfer + _state = dmaTrxPrepare((uint32_t)buf & 3 ? (uint8_t*)aligned : buf, 512, TRX_RD); + + // prepare SDIO data read transfer + _state = dmaTrxStart(512, TRX_RD); + } + + + _state = dmaTrxEnd(0); + + if ( _state ) { + if ( (uint32_t)buf & 3 ) { + //memcpy(buf, aligned, 512); + register uint8_t * dst = buf; + register uint8_t * src = (uint8_t *)aligned; + register uint16_t i = 64; + while ( i-- ) { // do 8 byte copies, is much faster than single byte copy + *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; + *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; + } + } + m_totalReadLbas++; + m_curLba++; + if (m_curLba >= m_limitLba) { + syncBlocks(); + } + sdError(SD_CARD_ERROR_NONE); + return true; + } + syncBlocks(); + m_readErrors++; + + } + DBG_PRINT() + syncBlocks(); + m_readErrors++; + return false; } /*---------------------------------------------------------------------------*/ bool SdioCard::readBlocks(uint32_t lba, uint8_t* buf, size_t n) { #if USE_DEBUG_MODE - Serial.print("readBlocks: "); Serial.print(lba); - //Serial.print(", buf: "); Serial.print((uint32_t)buf, HEX); - Serial.print(", "); Serial.println(n); + Serial.print("readBlocks: "); Serial.print(lba); + //Serial.print(", buf: "); Serial.print((uint32_t)buf, HEX); + Serial.print(", "); Serial.println(n); #endif - if ((uint32_t)buf & 3) { - for (size_t i = 0; i < n; i++, lba++, buf += 512) { - if (!readBlock(lba, buf)) { - return false; // readBlock will set errorCode. - } - } - return true; - } - // prepare SDIO and DMA for data read transfer - dmaTrxStart(buf, 512*n, TRX_RD); - // send command to start data transfer - if ( !cardCommand(CMD18_XFERTYP, (m_highCapacity ? lba : 512*lba)) ) { - return sdError(SD_CARD_ERROR_CMD18); - } - return dmaTrxEnd(1); + volatile bool _state = false; + uint16_t retries = 3; + while ( retries-- ){ + + if ((uint32_t)buf & 3) { + for (size_t i = 0; i < n; i++, lba++, buf += 512) { + if (!readBlock(lba, buf)) { + return false; // readBlock will set errorCode. + } + } + return true; + } + + if (m_curState != READ_STATE || m_curLba != lba) { + #if USE_DEBUG_MODE + Serial.print("New lba, syncing :"); + Serial.println(lba); + #endif + _state = syncBlocks(); + DBG_PRINT(); + if (!_state) { + return false; + } + m_limitLba = (lba + 1024); //arbitrary limit + // prepare DMA for data read transfer + _state = dmaTrxPrepare(buf, 512*n, TRX_RD); + + // prepare SDIO for data read transfer + _state = dmaTrxStart(512*n, TRX_RD); + + // send command to start data transfer + _state = cardCommand(CMD18_XFERTYP, (m_highCapacity ? lba : 512*lba)); + if ( !_state ) { + return sdError(SD_CARD_ERROR_CMD18); + } + m_curLba = lba; + m_curState = READ_STATE; + } + + else { + // prepare DMA for data read transfer + _state = dmaTrxPrepare(buf, 512*n, TRX_RD); + + // prepare SDIO data read transfer + _state = dmaTrxStart(512*n, TRX_RD); + } + + _state = dmaTrxEnd(0); + + if (_state){ + m_totalReadLbas += n; + m_curLba += n; + if (m_curLba >= m_limitLba) { + syncBlocks(); + } + sdError(SD_CARD_ERROR_NONE); + return true; + } + syncBlocks(); + m_readErrors++; + } + DBG_PRINT() + syncBlocks(); + m_readErrors++; + return false; } //----------------------------------------------------------------------------- bool SdioCard::readCID(void* cid) { @@ -631,6 +864,7 @@ bool SdioCard::readCSD(void* csd) { return true; } /*---------------------------------------------------------------------------*/ +/* replacing this one with DMA support. bool SdioCard::readData(uint8_t *dst) { //Serial.print("readData: "); Serial.print(m_lba); Serial.print(", m_cnt: "); Serial.println(m_cnt); @@ -675,6 +909,51 @@ bool SdioCard::readData(uint8_t *dst) m_cnt--; return !(SDIO->STA&SDIO_STA_TRX_ERROR_FLAGS); } +*/ +bool SdioCard::readData(uint8_t *buf) +{ + + volatile bool _state = false; + uint16_t retries = 3; + while ( retries-- ){ + // prepare DMA for data read transfer + _state = dmaTrxPrepare((uint32_t)buf & 3 ? (uint8_t*)aligned : buf, 512, TRX_RD); + + // prepare SDIO data read transfer + _state = dmaTrxStart(512, TRX_RD); + _state = dmaTrxEnd(0); + + if ( _state ) { + if ( (uint32_t)buf & 3 ) { + //memcpy(buf, aligned, 512); + register uint8_t * dst = buf; + register uint8_t * src = (uint8_t *)aligned; + register uint16_t i = 64; + while ( i-- ) { // do 8 byte copies, is much faster than single byte copy + *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; + *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; + } + } + m_curLba += 1; + return true; + } + else { + readStop(); + //_state = dmaTrxPrepare((uint32_t)buf & 3 ? (uint8_t*)aligned : buf, 512, TRX_RD); + //_state = dmaTrxStart(512, TRX_RD); + _state = cardCommand(CMD18_XFERTYP, (m_highCapacity ? m_curLba : 512*m_curLba)); + if ( !_state ) { + return sdError(SD_CARD_ERROR_CMD18); + } + } + } + DBG_PRINT() + m_readErrors++; + return sdError(SD_CARD_ERROR_READ); + +} + + //----------------------------------------------------------------------------- bool SdioCard::readOCR(uint32_t* ocr) { *ocr = m_ocr; @@ -683,29 +962,80 @@ bool SdioCard::readOCR(uint32_t* ocr) { //----------------------------------------------------------------------------- bool SdioCard::readStart(uint32_t lba) { + m_curLba = lba; + /* m_lba = lba; m_cnt = 1024; return true; + */ + volatile bool _state = false; + if (yieldTimeout(isBusyCMD13)) { // wait for previous transmission end + return sdError(SD_CARD_ERROR_CMD13); + } + _state = cardCommand(CMD18_XFERTYP, (m_highCapacity ? lba : 512*lba)); + DBG_PRINT(); + if ( !_state ) { + return sdError(SD_CARD_ERROR_CMD18); + } + m_curState = READ_STATE; + return true; } /*---------------------------------------------------------------------------*/ // SDHC will do Auto CMD12 after count blocks. bool SdioCard::readStart(uint32_t lba, uint32_t count) { //Serial.print("readStart: "); Serial.print(lba); Serial.print(", cnt: "); Serial.println(count); + m_curLba = lba; +/* m_lba = lba; m_cnt = count; return true; +*/ + volatile bool _state = false; + if (yieldTimeout(isBusyCMD13)) { // wait for previous transmission end + return sdError(SD_CARD_ERROR_CMD13); + } + _state = cardCommand(CMD18_XFERTYP, (m_highCapacity ? lba : 512*lba)); + DBG_PRINT(); + if ( !_state ) { + return sdError(SD_CARD_ERROR_CMD18); + } + m_curState = READ_STATE; + return true; } /*---------------------------------------------------------------------------*/ bool SdioCard::readStop() { - //Serial.println("readStop."); - m_lba = 0; - m_cnt = 0; + if ( isEnabledDMA()){ + yieldDmaStatus(); + } + sdio_setup_transfer(0x00FFFFFF, 0, 0); + // Empty SDIO FIFO + while ( SDIO->STA & SDIO_STA_RXDAVL) { + volatile uint32 _unused = SDIO->FIFO; + } + //Serial.println("readStop."); + //m_lba = 0; + if (!trxStop()) { + return false; + } return true; } //----------------------------------------------------------------------------- -bool SdioCard::syncBlocks() { +inline bool SdioCard::syncBlocks() { +/* if ( isEnabledDMA()){ + waitDmaStatus(); + } +*/ + if (m_curState == READ_STATE) { + m_curState = IDLE_STATE; + if (!readStop()) { + return false; + } + } else if (m_curState == WRITE_STATE) { + m_curState = IDLE_STATE; + return writeStop(); + } return true; } //----------------------------------------------------------------------------- @@ -733,17 +1063,48 @@ bool SdioCard::writeBlock(uint32_t lba, const uint8_t* buf) *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; } } - if (yieldTimeout(isBusyCMD13)) { // wait for previous transmission end - return sdError(SD_CARD_ERROR_CMD13); + + + + if (m_curState != WRITE_STATE || m_curLba != lba) { + if (!syncBlocks()) { + return false; + } + + m_limitLba = (lba + 1024); //arbitrary limit + + // prepare DMA for data transfer + dmaTrxPrepare(ptr, 512, TRX_WR); // 1 block, write transfer + + // send command to start data transfer + if ( !cardCommand(CMD25_XFERTYP, (m_highCapacity ? lba : 512*lba)) ) { + return sdError(SD_CARD_ERROR_CMD25); + } + m_curLba = lba; + m_curState = WRITE_STATE; + } - // send command to start data transfer - if ( !cardCommand(CMD24_XFERTYP, (m_highCapacity ? lba : 512*lba)) ) { - return sdError(SD_CARD_ERROR_CMD24); + else { + if (yieldTimeout(isBusyCMD13)) { // wait for previous transmission end + return sdError(SD_CARD_ERROR_CMD13); + } + // prepare DMA for data transfer + dmaTrxPrepare(ptr, 512, TRX_WR); // 1 block, write transfer } - // prepare SDIO and DMA for data transfer - dmaTrxStart(ptr, 512, TRX_WR); // 1 block, write transfer - return dmaTrxEnd(0); + // prepare SDIO for data transfer + dmaTrxStart(512, TRX_WR); // 1 block, write transfer + + if (!dmaTrxEnd(0)){ + m_curState = IDLE_STATE; + m_writeErrors++; + return false; + } + m_curLba++; + if (m_curLba >= m_limitLba) { + syncBlocks(); + } + return true; } /*---------------------------------------------------------------------------*/ bool SdioCard::writeBlocks(uint32_t lba, const uint8_t* buf, size_t n) @@ -770,16 +1131,46 @@ bool SdioCard::writeBlocks(uint32_t lba, const uint8_t* buf, size_t n) return sdError(SD_CARD_ERROR_ACMD23); } #endif - // send command to start data transfer - if ( !cardCommand(CMD25_XFERTYP, (m_highCapacity ? lba : 512*lba)) ) { - return sdError(SD_CARD_ERROR_CMD25); - } - // prepare SDIO and DMA for data transfer - dmaTrxStart((uint8_t *)buf, 512*n, TRX_WR); // n blocks, write transfer - return dmaTrxEnd(1); + if (m_curState != WRITE_STATE || m_curLba != lba) { + if (!syncBlocks()) { + return false; + } + + m_limitLba = (lba + 1024); //arbitrary limit, 512KB + // prepare DMA for data transfer + dmaTrxPrepare((uint8_t *)buf, 512*n, TRX_WR); // n blocks, write transfer + + // send command to start data transfer + if ( !cardCommand(CMD25_XFERTYP, (m_highCapacity ? lba : 512*lba)) ) { + return sdError(SD_CARD_ERROR_CMD25); + } + m_curLba = lba; + m_curState = WRITE_STATE; + + } + else { + // prepare DMA for data transfer + dmaTrxPrepare((uint8_t *)buf, 512*n, TRX_WR); // n blocks, write transfer + } + + // prepare SDIO for data transfer + dmaTrxStart(512*n, TRX_WR); // n blocks, write transfer + + if (!dmaTrxEnd(0)){ + m_writeErrors++; + m_curState = IDLE_STATE; + return false; + } + m_curLba += n; + if (m_curLba >= m_limitLba) { + syncBlocks(); + } + return true; + } /*---------------------------------------------------------------------------*/ +/* bool SdioCard::writeData(const uint8_t* src) { //Serial.print("writeData: "); Serial.print(m_lba); Serial.print(", cnt: "); Serial.println(m_cnt); @@ -826,27 +1217,91 @@ bool SdioCard::writeData(const uint8_t* src) } return !(SDIO->STA&SDIO_STA_TRX_ERROR_FLAGS); } +*/ +bool SdioCard::writeData(const uint8_t* src) +{ + uint8_t * ptr = (uint8_t *)src; + if (3 & (uint32_t)ptr) { + Serial.print("writeBlock: "); Serial.print(m_curLba); + Serial.print(", buf: "); Serial.print((uint32_t)ptr, HEX); + //memcpy(aligned, buf, 512); + register uint8_t * src = (uint8_t *)ptr; + ptr = (uint8_t *)aligned; + register uint8_t * dst = ptr; + register uint16_t i = 64; + while ( i-- ) { // do 8 byte copies, is much faster than single byte copy + *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; + *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; + } + } + + if (yieldTimeout(isBusyCMD13)) { // wait for previous transmission end + return sdError(SD_CARD_ERROR_CMD13); + } + // prepare DMA for data transfer + dmaTrxPrepare(ptr, 512, TRX_WR); // 1 block, write transfer + DBG_PRINT(); + + // prepare SDIO for data transfer + dmaTrxStart(512, TRX_WR); // 1 block, write transfer + DBG_PRINT(); + + if (!dmaTrxEnd(0)){ + m_writeErrors++; + return false; + } + return true; +} //----------------------------------------------------------------------------- bool SdioCard::writeStart(uint32_t lba) { + /* m_lba = lba; m_cnt = 1024; return true; + */ + DBG_PRINT(); + m_curLba = lba; + if (yieldTimeout(isBusyCMD13)) { + return sdError(SD_CARD_ERROR_CMD13); + } + if ( !cardCommand(CMD25_XFERTYP, (m_highCapacity ? lba : 512*lba)) ) { + return sdError(SD_CARD_ERROR_CMD25); + } + m_curState = WRITE_STATE; + return true; } /*---------------------------------------------------------------------------*/ // SDHC will do Auto CMD12 after count blocks. bool SdioCard::writeStart(uint32_t lba, uint32_t count) { //Serial.print("writeStart: "); Serial.print(lba); Serial.print(", cnt: "); Serial.println(count); + /* m_lba = lba; m_cnt = count; return true; + */ + m_curLba = lba; + if (yieldTimeout(isBusyCMD13)) { + return sdError(SD_CARD_ERROR_CMD13); + } + if ( !cardCommand(CMD25_XFERTYP, (m_highCapacity ? lba : 512*lba)) ) { + return sdError(SD_CARD_ERROR_CMD25); + } + m_curState = WRITE_STATE; + return true; } /*---------------------------------------------------------------------------*/ bool SdioCard::writeStop() { - //Serial.println("writeStop."); - m_lba = 0; - m_cnt = 0; - return true; + if ( isEnabledDMA()){ + if ( !yieldDmaStatus() ) { + DBG_PRINT(); + return sdError(SD_CARD_ERROR_DMA); + } + } + //m_lba = 0; + m_curState = IDLE_STATE; + return trxStop(); + //Serial.println("writeStop."); } diff --git a/STM32F1/libraries/SDIO/SdioF1.h b/STM32F1/libraries/SDIO/SdioF1.h index c995b1c5c..efa47749c 100644 --- a/STM32F1/libraries/SDIO/SdioF1.h +++ b/STM32F1/libraries/SDIO/SdioF1.h @@ -1,6 +1,6 @@ -#ifndef _SDIOF4_H_ -#define _SDIOF4_H_ +#ifndef _SDIOF1_H_ +#define _SDIOF1_H_ #include diff --git a/STM32F1/libraries/SPI/examples/spi_slave/spi_slave.ino b/STM32F1/libraries/SPI/examples/spi_slave/spi_slave.ino new file mode 100644 index 000000000..1e26db387 --- /dev/null +++ b/STM32F1/libraries/SPI/examples/spi_slave/spi_slave.ino @@ -0,0 +1,37 @@ +// SPI full-duplex slave example +// STM32 acts as a SPI slave and reads 8 bit data frames over SPI. +// Master also gets a reply from the slave, which is a a simple count (0, 1, 2, 3) +// that is incremented each time a data frame is received. +// Serial output is here for debug + +#include +#include + +void setupSPI(void) +{ + // The clock value is not used + // SPI1 is selected by default + // MOSI, MISO, SCK and NSS PINs are set by the library + SPI.beginTransactionSlave(SPISettings(18000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT)); +} + +void setup() +{ + Serial.begin(115200); + delay(100); + setupSPI(); +} + +uint8_t count = 0; +void loop() +{ + // Blocking call to read SPI message + uint8_t msg = SPI.transfer(++count); + Serial.print("Received = 0b"); + Serial.print(msg, BIN); + Serial.print(", 0x"); + Serial.print(msg, HEX); + Serial.print(", "); + Serial.println(msg); +} + diff --git a/STM32F1/libraries/SPI/src/SPI.cpp b/STM32F1/libraries/SPI/src/SPI.cpp index c07e2ea4a..58c6ec98c 100644 --- a/STM32F1/libraries/SPI/src/SPI.cpp +++ b/STM32F1/libraries/SPI/src/SPI.cpp @@ -61,6 +61,8 @@ static void configure_gpios(spi_dev *dev, bool as_master); static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq); +static uint16_t ff = 0XFFFF; + #if (BOARD_NR_SPI >= 3) && !defined(STM32_HIGH_DENSITY) #error "The SPI library is misconfigured: 3 SPI ports only available on high density STM32 devices" #endif @@ -86,6 +88,24 @@ static const spi_pins board_spi_pins[] __FLASH__ = { #endif }; +static const spi_pins board_alt_spi_pins[] __FLASH__ = { +#if defined(BOARD_SPI1_ALT_MOSI_PIN) + {BOARD_SPI1_ALT_NSS_PIN, + BOARD_SPI1_ALT_SCK_PIN, + BOARD_SPI1_ALT_MISO_PIN, + BOARD_SPI1_ALT_MOSI_PIN} +#endif +}; + +#if BOARD_NR_SPI >= 1 +static void (*_spi1_this); +#endif +#if BOARD_NR_SPI >= 2 +static void (*_spi2_this); +#endif +#if BOARD_NR_SPI >= 3 +static void (*_spi3_this); +#endif /* * Constructor @@ -120,16 +140,20 @@ SPIClass::SPIClass(uint32 spi_num) // Init things specific to each SPI device // clock divider setup is a bit of hack, and needs to be improved at a later date. +#if BOARD_NR_SPI >= 1 _settings[0].spi_d = SPI1; _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock); _settings[0].spiDmaDev = DMA1; _settings[0].spiTxDmaChannel = DMA_CH3; _settings[0].spiRxDmaChannel = DMA_CH2; +#endif +#if BOARD_NR_SPI >= 2 _settings[1].spi_d = SPI2; _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock); _settings[1].spiDmaDev = DMA1; _settings[1].spiTxDmaChannel = DMA_CH5; _settings[1].spiRxDmaChannel = DMA_CH4; +#endif #if BOARD_NR_SPI >= 3 _settings[2].spi_d = SPI3; _settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock); @@ -161,7 +185,7 @@ void SPIClass::begin(void) { void SPIClass::beginSlave(void) { spi_init(_currentSetting->spi_d); configure_gpios(_currentSetting->spi_d, 0); - uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_RX_ONLY); + uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize); spi_slave_enable(_currentSetting->spi_d, (spi_mode)_currentSetting->dataMode, flags); // added for DMA callbacks. _currentSetting->state = SPI_STATE_READY; @@ -178,10 +202,7 @@ void SPIClass::end(void) { // FIXME [0.1.0] remove this once you have an interrupt based driver volatile uint16 rx __attribute__((unused)) = spi_rx_reg(_currentSetting->spi_d); } - while (!spi_is_tx_empty(_currentSetting->spi_d)) - ; - while (spi_is_busy(_currentSetting->spi_d)) - ; + waitSpiTxEnd(_currentSetting->spi_d); spi_peripheral_disable(_currentSetting->spi_d); // added for DMA callbacks. // Need to add unsetting the callbacks for the DMA channels. @@ -251,6 +272,7 @@ If someone finds this is not the case or sees a logic error with this let me kno void SPIClass::beginTransaction(uint8_t pin, SPISettings settings) { + (void)pin; // unused setBitOrder(settings.bitOrder); setDataMode(settings.dataMode); setDataSize(settings.dataSize); @@ -325,8 +347,7 @@ void SPIClass::write(uint16 data) * This almost doubles the speed of this function. */ spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(_currentSetting->spi_d); } void SPIClass::write16(uint16 data) @@ -335,8 +356,7 @@ void SPIClass::write16(uint16 data) spi_tx_reg(_currentSetting->spi_d, data>>8); // write high byte while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // Wait until TXE=1 spi_tx_reg(_currentSetting->spi_d, data); // write low byte - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // Wait until TXE=1 - while (spi_is_busy(_currentSetting->spi_d) != 0); // wait until BSY=0 + waitSpiTxEnd(_currentSetting->spi_d); } void SPIClass::write(uint16 data, uint32 n) @@ -354,8 +374,7 @@ void SPIClass::write(const void *data, uint32 length) { spi_dev * spi_d = _currentSetting->spi_d; spi_tx(spi_d, data, length); // data can be array of bytes or words - while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(spi_d); // "5. Wait until TXE=1 and then wait until BSY=0 before disabling the SPI." } uint8 SPIClass::transfer(uint8 byte) const @@ -363,28 +382,46 @@ uint8 SPIClass::transfer(uint8 byte) const spi_dev * spi_d = _currentSetting->spi_d; spi_rx_reg(spi_d); // read any previous data spi_tx_reg(spi_d, byte); // Write the data item to be transmitted into the SPI_DR register - while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(spi_d); return (uint8)spi_rx_reg(spi_d); // "... and read the last received data." } uint16_t SPIClass::transfer16(uint16_t data) const { // Modified by stevestrong: write & read two consecutive bytes in 8 bit mode (DFF=0) - // This is more effective than two distinct byte transfers + // This is more effective than two distinct byte transfers spi_dev * spi_d = _currentSetting->spi_d; spi_rx_reg(spi_d); // read any previous data spi_tx_reg(spi_d, data>>8); // write high byte - while (spi_is_tx_empty(spi_d) == 0); // wait until TXE=1 - while (spi_is_busy(spi_d) != 0); // wait until BSY=0 - uint16_t ret = spi_rx_reg(spi_d)<<8; // read and shift high byte + waitSpiTxEnd(spi_d); // wait until TXE=1 and then wait until BSY=0 + uint16_t ret = spi_rx_reg(spi_d)<<8; // read and shift high byte spi_tx_reg(spi_d, data); // write low byte - while (spi_is_tx_empty(spi_d) == 0); // wait until TXE=1 - while (spi_is_busy(spi_d) != 0); // wait until BSY=0 - ret += spi_rx_reg(spi_d); // read low byte + waitSpiTxEnd(spi_d); // wait until TXE=1 and then wait until BSY=0 + ret += spi_rx_reg(spi_d); // read low byte return ret; } +void SPIClass::transfer(const uint8_t * tx_buf, uint8_t * rx_buf, uint32 len) +{ + if ( len == 0 ) return; + spi_rx_reg(_currentSetting->spi_d); // clear the RX buffer in case a byte is waiting on it. + spi_reg_map * regs = _currentSetting->spi_d->regs; + // start sequence: write byte 0 + regs->DR = *tx_buf++; // write the first byte + // main loop + while ( (--len) ) { + while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag + noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data + regs->DR = *tx_buf++; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag. + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register + *rx_buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag. + interrupts(); // let systick do its job + } + // read remaining last byte + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register + *rx_buf++ = (uint8)(regs->DR); // read and store the received byte +} + /* Roger Clark and Victor Perez, 2015 * Performs a DMA SPI transfer with at least a receive buffer. * If a TX buffer is not provided, FF is sent over and over for the lenght of the transfer. @@ -399,13 +436,13 @@ void SPIClass::dmaTransferSet(const void *transmitBuf, void *receiveBuf) { dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, receiveBuf, dma_bit_size, (DMA_MINC_MODE | DMA_TRNS_CMPLT ));// receive buffer DMA if (!transmitBuf) { - transmitBuf = &ff; - dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, - (volatile void*)transmitBuf, dma_bit_size, (DMA_FROM_MEM));// Transmit FF repeatedly + transmitBuf = &ff; + dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, + (volatile void*)transmitBuf, dma_bit_size, (DMA_FROM_MEM));// Transmit FF repeatedly } else { - dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, - (volatile void*)transmitBuf, dma_bit_size, (DMA_MINC_MODE | DMA_FROM_MEM ));// Transmit buffer DMA + dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, + (volatile void*)transmitBuf, dma_bit_size, (DMA_MINC_MODE | DMA_FROM_MEM ));// Transmit buffer DMA } dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, DMA_PRIORITY_LOW); dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, DMA_PRIORITY_VERY_HIGH); @@ -432,8 +469,7 @@ uint8 SPIClass::dmaTransferRepeat(uint16 length) { if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } } - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(_currentSetting->spi_d); // "5. Wait until TXE=1 and then wait until BSY=0 before disabling the SPI." spi_tx_dma_disable(_currentSetting->spi_d); spi_rx_dma_disable(_currentSetting->spi_d); dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); @@ -456,6 +492,12 @@ uint8 SPIClass::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16 le return dmaTransferRepeat(length); } +uint8 SPIClass::dmaTransfer(const uint16 value, void *receiveBuf, uint16 length) { + ff = value; + dmaTransferSet(NULL, receiveBuf); + return dmaTransferRepeat(length); +} + /* Roger Clark and Victor Perez, 2015 * Performs a DMA SPI send using a TX buffer. * On exit TX buffer is not modified. @@ -489,8 +531,7 @@ uint8 SPIClass::dmaSendRepeat(uint16 length) { //Avoid interrupts and just loop waiting for the flag to be set. if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } } - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(_currentSetting->spi_d); // "5. Wait until TXE=1 and then wait until BSY=0 before disabling the SPI." spi_tx_dma_disable(_currentSetting->spi_d); dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); @@ -515,8 +556,7 @@ uint8 SPIClass::dmaSendAsync(const void * transmitBuf, uint16 length, bool minc) if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } } - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(_currentSetting->spi_d); // "5. Wait until TXE=1 and then wait until BSY=0 before disabling the SPI." spi_tx_dma_disable(_currentSetting->spi_d); dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); _currentSetting->state = SPI_STATE_READY; @@ -550,12 +590,16 @@ void SPIClass::onReceive(void(*callback)(void)) { _currentSetting->receiveCallback = callback; if (callback){ switch (_currentSetting->spi_d->clk_id) { + #if BOARD_NR_SPI >= 1 case RCC_SPI1: dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi1EventCallback); break; + #endif + #if BOARD_NR_SPI >= 2 case RCC_SPI2: dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi2EventCallback); break; + #endif #if BOARD_NR_SPI >= 3 case RCC_SPI3: dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi3EventCallback); @@ -574,12 +618,16 @@ void SPIClass::onTransmit(void(*callback)(void)) { _currentSetting->transmitCallback = callback; if (callback){ switch (_currentSetting->spi_d->clk_id) { + #if BOARD_NR_SPI >= 1 case RCC_SPI1: dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi1EventCallback); break; - case RCC_SPI2: + #endif + #if BOARD_NR_SPI >= 2 + case RCC_SPI2: dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi2EventCallback); break; + #endif #if BOARD_NR_SPI >= 3 case RCC_SPI3: dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi3EventCallback); @@ -600,8 +648,7 @@ void SPIClass::onTransmit(void(*callback)(void)) { */ void SPIClass::EventCallback() { - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0" + waitSpiTxEnd(_currentSetting->spi_d); switch (_currentSetting->state) { case SPI_STATE_TRANSFER: while (spi_is_rx_nonempty(_currentSetting->spi_d)); @@ -679,30 +726,37 @@ uint8 SPIClass::recv(void) { } /* - DMA call back functions, one per port. -*/ - -void SPIClass::_spi1EventCallback() -{ + * DMA call back functions, one per port. + */ +#if BOARD_NR_SPI >= 1 +void SPIClass::_spi1EventCallback() { reinterpret_cast(_spi1_this)->EventCallback(); } - +#endif +#if BOARD_NR_SPI >= 2 void SPIClass::_spi2EventCallback() { reinterpret_cast(_spi2_this)->EventCallback(); } +#endif #if BOARD_NR_SPI >= 3 void SPIClass::_spi3EventCallback() { reinterpret_cast(_spi3_this)->EventCallback(); } #endif -/* -* Auxiliary functions -*/ +/* + * Auxiliary functions + */ static const spi_pins* dev_to_spi_pins(spi_dev *dev) { switch (dev->clk_id) { #if BOARD_NR_SPI >= 1 - case RCC_SPI1: return board_spi_pins; + case RCC_SPI1: +#if defined(BOARD_SPI1_ALT_MOSI_PIN) + if(afio_is_remapped(AFIO_REMAP_SPI1)) { + return board_alt_spi_pins; + } +#endif + return board_spi_pins; #endif #if BOARD_NR_SPI >= 2 case RCC_SPI2: return board_spi_pins + 1; @@ -758,14 +812,14 @@ static const spi_baud_rate baud_rates[8] __FLASH__ = { * (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz). */ static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) { - uint32_t clock = 0, i; - switch (rcc_dev_clk(dev->clk_id)) - { + uint32_t clock = 0; + switch (rcc_dev_clk(dev->clk_id)) { case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz + case RCC_AHB: break; //There is no SPI on this bus, but it removes warning } clock /= 2; - i = 0; + uint32_t i = 0; while (i < 7 && freq < clock) { clock /= 2; i++; diff --git a/STM32F1/libraries/SPI/src/SPI.h b/STM32F1/libraries/SPI/src/SPI.h index 686d23d4f..b4c6899a1 100644 --- a/STM32F1/libraries/SPI/src/SPI.h +++ b/STM32F1/libraries/SPI/src/SPI.h @@ -158,14 +158,8 @@ class SPISettings { /* - Should move this to within the class once tested out, just for tidyness -*/ -static uint8_t ff = 0XFF; -static void (*_spi1_this); -static void (*_spi2_this); -#if BOARD_NR_SPI >= 3 -static void (*_spi3_this); -#endif + * Kept for compat. + */ /** * @brief Wirish SPI interface. @@ -280,6 +274,12 @@ class SPIClass { */ void write(const void * buffer, uint32 length); + // Some libraries (like recent Adafruit graphics libraries) require + // the write function be availabe under the name transfer, so here it is: + inline void transfer(const void * buffer, uint32 length) { + write(buffer, (uint32)length); + } + /** * @brief Transmit a byte, then return the next unread byte. * @@ -290,6 +290,9 @@ class SPIClass { */ uint8 transfer(uint8 data) const; uint16_t transfer16(uint16_t data) const; + void transfer(const uint8_t * tx_buf, uint8_t * rx_buf, uint32 len); + void transfer(uint8_t * trx_buf, uint32 len) { transfer((const uint8_t *)trx_buf, trx_buf, len); } + /** * @brief Sets up a DMA Transfer for "length" bytes. @@ -302,6 +305,7 @@ class SPIClass { * @param length Number of bytes in buffer to transmit. */ uint8 dmaTransfer(const void * transmitBuf, void * receiveBuf, uint16 length); + uint8 dmaTransfer(const uint16 value, void * receiveBuf, uint16 length); void dmaTransferSet(const void *transmitBuf, void *receiveBuf); uint8 dmaTransferRepeat(uint16 length); @@ -411,8 +415,12 @@ class SPIClass { void EventCallback(void); + #if BOARD_NR_SPI >= 1 static void _spi1EventCallback(void); + #endif + #if BOARD_NR_SPI >= 2 static void _spi2EventCallback(void); + #endif #if BOARD_NR_SPI >= 3 static void _spi3EventCallback(void); #endif @@ -425,6 +433,14 @@ class SPIClass { */ }; +/** +* @brief Waits unti TXE (tx empy) flag set and BSY (busy) flag unset. +*/ +static inline void waitSpiTxEnd(spi_dev *spi_d) +{ + while (spi_is_tx_empty(spi_d) == 0); // wait until TXE=1 + while (spi_is_busy(spi_d) != 0); // wait until BSY=0 +} extern SPIClass SPI;//(1);// dummy params #endif diff --git a/STM32F1/libraries/STM32ADC/examples/AnalogWatchdogInterrupt/AnalogWatchdogInterrupt.ino b/STM32F1/libraries/STM32ADC/examples/AnalogWatchdogInterrupt/AnalogWatchdogInterrupt.ino new file mode 100644 index 000000000..7616413e5 --- /dev/null +++ b/STM32F1/libraries/STM32ADC/examples/AnalogWatchdogInterrupt/AnalogWatchdogInterrupt.ino @@ -0,0 +1,87 @@ +/* + This is an example how to use the analog watchdog functionality of the ADC. + + The analog watchdog has two limits and will generate an IRQ if + the input voltage is below the lower limit OR higher than the upper limit. + + Continuous or single conversion can be used. + In continuous mode the interrupts will be coninuously generated in very + short time intervals as long as the trigger condition is satisfied. + This will cause the ADC interrupts to be nested and leads to hang-up. + In order to avoid this, the AWD interrupt is disabled whithin the first IRQ. + +*/ + +#include + +STM32ADC myADC(ADC1); + +uint8 adc_pin = PA0; + +volatile static bool triggered; +// the AWD interrupt will be re-enabled 3 seconds after the last trigger +volatile uint32 trigger_time; + +//----------------------------------------------------------------------------- +// This function will be called when the AWD interrupt is triggered +//----------------------------------------------------------------------------- +void awd_int() +{ + myADC.disableAnalogWatchdog(); // to avoid ISR nesting + // a second IRQ will be triggered while we process the first ISR even before we disable the AWD + if (triggered==true) // avoid processing second IRQ + return; + triggered = true; + Serial.println("*** AWD triggered! ***"); + // Serial.print("ADC = "); Serial.println(myADC.getData()); + trigger_time = millis(); +} + +//----------------------------------------------------------------------------- +void setup() +{ + // Serial.begin(19200); // useless for USB serial + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); // off + + triggered = false; + + // disable the following line if you use a COM interface different from USB serial + while (!Serial); delay(10); + + Serial.print("Setup..."); + myADC.setPins(&adc_pin, 1); + myADC.calibrate(); + myADC.setSampleRate(ADC_SMPR_1_5); + + // this will trigger an IRQ if the input is set to 3.3V + myADC.setAnalogWatchdog(0, 4000, 0); // channel of PA0 = 0, high limit, low limit + + myADC.attachAnalogWatchdogInterrupt(awd_int); + myADC.enableAnalogWatchdog(); + + // in single conversion mode you need to call startConversion() regularily in the main loop + myADC.setContinuous(); + myADC.startConversion(); + + Serial.println("done."); + Serial.println("Waiting for AWD interrupt..."); +} + +//----------------------------------------------------------------------------- +void loop() +{ + // blink (optional), the IRQ will be triggered in the background + digitalWrite(LED_BUILTIN, HIGH); // off + delay(500); + digitalWrite(LED_BUILTIN, LOW); // on + delay(500); + + // re-enable the AWD interrupt 3 seconds after the last trigger + if ( (triggered==true) && (millis()-trigger_time)>3000 ) + { + Serial.println("\nRe-enabling AWD IRQ..."); + triggered = false; + myADC.enableAnalogWatchdog(); + } +} diff --git a/STM32F1/libraries/STM32ADC/examples/MultiChannelSingleConversion/MultiChannelSingleConversion.ino b/STM32F1/libraries/STM32ADC/examples/MultiChannelSingleConversion/MultiChannelSingleConversion.ino index f0ebbb1cf..9f95bcb01 100644 --- a/STM32F1/libraries/STM32ADC/examples/MultiChannelSingleConversion/MultiChannelSingleConversion.ino +++ b/STM32F1/libraries/STM32ADC/examples/MultiChannelSingleConversion/MultiChannelSingleConversion.ino @@ -1,16 +1,13 @@ /* - This example shows how to use the ADC library to sample several - channels/pins in one go. + This example shows how to use the ADC library to sample several channels/pins in one go. This example attaches an interrupt to the DMA completion to notify the user. - The DMA must be set together with the start conversion, so both setDMA and startConversion - Must be called. */ #include -#define BOARD_LED D33 //PB0 +#define BOARD_LED PC13 -uint8 pins[] = {11,10,9,8,7,6,5,4}; +uint8 pins[] = {PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7}; const int maxSamples = 8; // 8 channels @@ -21,46 +18,55 @@ volatile static bool dma1_ch1_Active; //flag for interrupt STM32ADC myADC(ADC1); -void setup() { -//start Serial - Serial.begin(19200); -//Start up blink from Pig-O-Scope - pinMode(BOARD_LED, OUTPUT); - pinMode(D32, INPUT); - digitalWrite(BOARD_LED, HIGH); - delay(1000); - digitalWrite(BOARD_LED, LOW); - delay(1000); -//calibrate ADC. - myADC.calibrate(); - - myADC.setSampleRate(ADC_SMPR_1_5); //sample ratio - myADC.setPins(pins, maxSamples); //pins to be converted - myADC.setScanMode(); //Set the ADC in Scan Mode +//----------------------------------------------------------------------------- +// Interrupt handler. +//----------------------------------------------------------------------------- +static void DMA1_CH1_Event() +{ + dma1_ch1_Active = 0; } +//----------------------------------------------------------------------------- +void setup() +{ + //start Serial + Serial.begin(19200); + pinMode(BOARD_LED, OUTPUT); + digitalWrite(BOARD_LED, HIGH); -void loop(){ -//start acquisition on button push. - if(digitalRead(D32) == 1 ) { - Serial.println("begin"); - dma1_ch1_Active = 1; - myADC.setDMA(dataPoints, 8, (DMA_MINC_MODE | DMA_TRNS_CMPLT), DMA1_CH1_Event); - myADC.startConversion(); - while (dma1_ch1_Active == 1); //wait for DMA to complete. - - for(unsigned int i = 0; i < maxSamples; i ++) { - Serial.print("sample["); - Serial.print(i); - Serial.print("] = "); - Serial.println(dataPoints[i]); - } - while(digitalRead(D32) == 1); //stay here. Another button push is required. - } -}; //end loop + while(!Serial); delay(10); -/* - Interrupt handler. eh eh -*/ -static void DMA1_CH1_Event() { - dma1_ch1_Active = 0; + Serial.println("MultiChannelSingleConversion demo started\n"); + // calibrate ADC. + myADC.calibrate(); + // setup ADC + myADC.setSampleRate(ADC_SMPR_1_5); //sample ratio + myADC.setPins(pins, maxSamples); //pins to be converted + myADC.setScanMode(); //Set the ADC in Scan Mode + myADC.setDMA(dataPoints, (DMA_MINC_MODE | DMA_TRNS_CMPLT), DMA1_CH1_Event); +} +//----------------------------------------------------------------------------- +void loop() +{ +// blink + digitalWrite(BOARD_LED, HIGH); // turn LED off + delay(1000); + digitalWrite(BOARD_LED, LOW); // turn LED on + +// start acquisition + Serial.println("begin"); + dma1_ch1_Active = 1; + + myADC.startDMA(maxSamples); + myADC.startConversion(); + + while (dma1_ch1_Active == 1); //wait for DMA to complete. + // print out the sampled values + for(unsigned int i = 0; i < maxSamples; i ++) { + Serial.print("sample["); + Serial.print(i); + Serial.print("] = "); + Serial.println(dataPoints[i]); + } + + delay(1000); } diff --git a/STM32F1/libraries/STM32ADC/examples/SingleChannelContinuousConversion/SingleChannelContinuousConversion.ino b/STM32F1/libraries/STM32ADC/examples/SingleChannelContinuousConversion/SingleChannelContinuousConversion.ino index 2844f9380..ac6cee4ab 100644 --- a/STM32F1/libraries/STM32ADC/examples/SingleChannelContinuousConversion/SingleChannelContinuousConversion.ino +++ b/STM32F1/libraries/STM32ADC/examples/SingleChannelContinuousConversion/SingleChannelContinuousConversion.ino @@ -5,7 +5,7 @@ */ #include -ADC myAdc(ADC1); +STM32ADC myAdc(ADC1); void setup() { Serial.begin(19200); diff --git a/STM32F1/libraries/STM32ADC/examples/SingleChannelSingleConversion/SingleChannelSingleConversion.ino b/STM32F1/libraries/STM32ADC/examples/SingleChannelSingleConversion/SingleChannelSingleConversion.ino index 8320712a8..9be90403d 100644 --- a/STM32F1/libraries/STM32ADC/examples/SingleChannelSingleConversion/SingleChannelSingleConversion.ino +++ b/STM32F1/libraries/STM32ADC/examples/SingleChannelSingleConversion/SingleChannelSingleConversion.ino @@ -5,11 +5,13 @@ */ #include -ADC myAdc(ADC1); +STM32ADC myADC(ADC1); uint8 pin[] = {D11}; void int_func() { + Serial.print("Readin: "); + uint32_t adc_result = myADC.getData(); Serial.println(adc_result); }; @@ -17,7 +19,9 @@ void setup() { Serial.begin(19200); myADC.setTrigger(ADC_EXT_EV_SWSTART);//start on SWStart bit myADC.setChannels(pin, 1); //this is actually the pin you want to measure - myADC.attachADCInterrupt(int_func); + myADC.attachInterrupt(int_func); + // + myADC.startConversion(); }; //end setup void loop(){ diff --git a/STM32F1/libraries/STM32ADC/examples/SingleConversionInterrupt/SingleConversionInterrupt.ino b/STM32F1/libraries/STM32ADC/examples/SingleConversionInterrupt/SingleConversionInterrupt.ino index c60eb1b54..8be6c4e1e 100644 --- a/STM32F1/libraries/STM32ADC/examples/SingleConversionInterrupt/SingleConversionInterrupt.ino +++ b/STM32F1/libraries/STM32ADC/examples/SingleConversionInterrupt/SingleConversionInterrupt.ino @@ -2,49 +2,53 @@ STM32ADC myADC(ADC1); -uint8 pin = D7; - -#define BOARD_LED D33 //this is for Maple Mini -volatile static bool triggered = 0; -uint32 dado_adc = 0; - - -void int_func() { - - triggered = 1; - dado_adc = myADC.getData(); - } - - - -void setup() { - Serial.begin(19200); - pinMode(BOARD_LED, OUTPUT); - pinMode(D32, INPUT); - pinMode(D11, INPUT_ANALOG);//AD pin. -//startup blink... good idea from Pig-O-Scope - digitalWrite(BOARD_LED, HIGH); - delay(1000); - digitalWrite(BOARD_LED, LOW); - delay(1000); - myADC.calibrate(); - myADC.setSampleRate(ADC_SMPR_1_5); - myADC.attachInterrupt(int_func, ADC_EOC); - myADC.setPins(&pin, 1); - +uint8 adc_pin = PA0; + +volatile static bool triggered; +volatile uint32 adc_value; + +//----------------------------------------------------------------------------- +// This function will be called after the conversion is done +//----------------------------------------------------------------------------- +void adc_int() +{ + adc_value = myADC.getData(); + triggered = 1; } +//----------------------------------------------------------------------------- +void setup() +{ + // Serial.begin(19200); // useless for USB serial + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); // LED off + while (!Serial); delay(10); -void loop() { - if(digitalRead(D32) == 1 ) { - Serial.println("begin"); - // Take our samples - myADC.startConversion(); - while (triggered == 0); //wait here... - - Serial.print("Readin: "); - Serial.println(dado_adc); - } + Serial.print("Setup..."); + myADC.setPins(&adc_pin, 1); + myADC.calibrate(); + myADC.setSampleRate(ADC_SMPR_1_5); + myADC.attachInterrupt(adc_int); + + Serial.println("done."); +} + +//----------------------------------------------------------------------------- +void loop() +{ + // Take our samples + triggered = 0; + myADC.startConversion(); + + while (triggered == 0); // wait here till conversion is finished + + Serial.print("Readin = "); + Serial.println(adc_value); + + digitalWrite(LED_BUILTIN, LOW); // on + delay(500); + digitalWrite(LED_BUILTIN, HIGH); // off + delay(500); } diff --git a/STM32F1/libraries/STM32ADC/src/STM32ADC.cpp b/STM32F1/libraries/STM32ADC/src/STM32ADC.cpp index 026dab12d..3ddb6390b 100644 --- a/STM32F1/libraries/STM32ADC/src/STM32ADC.cpp +++ b/STM32F1/libraries/STM32ADC/src/STM32ADC.cpp @@ -2,61 +2,13 @@ #include "boards.h" -/* - Constructor - Choose which ADC to use. - Start it up... -*/ - STM32ADC::STM32ADC (adc_dev * dev){ - _dev = dev; - //adc_calibrate(_dev);//get this out of the way. - - } - - uint32 STM32ADC::getData() { - return _dev->regs->DR; - }; - - -/* - Set the ADC Sampling Rate. - ADC_SMPR_1_5, < 1.5 ADC cycles - ADC_SMPR_7_5, < 7.5 ADC cycles - ADC_SMPR_13_5, < 13.5 ADC cycles - ADC_SMPR_28_5, < 28.5 ADC cycles - ADC_SMPR_41_5, < 41.5 ADC cycles - ADC_SMPR_55_5, < 55.5 ADC cycles - ADC_SMPR_71_5, < 71.5 ADC cycles - ADC_SMPR_239_5, < 239.5 ADC cycles -*/ - void STM32ADC::setSampleRate(adc_smp_rate SampleRate){ - adc_set_sample_rate(_dev, SampleRate); - } - -/* - Attach an interrupt to the ADC completion. -*/ - void STM32ADC::attachInterrupt(voidFuncPtr func, uint8 interrupt){ - adc_attach_interrupt(_dev,interrupt, func); - } - -/* - This will enable the internal readings. Vcc and Temperature -*/ - void STM32ADC::enableInternalReading(){ - enable_internal_reading(_dev); - } - /* This will read the Vcc and return something useful. Polling is being used. */ - float STM32ADC::readVcc(){ - unsigned int result = 0; - float vcc = 0.0; - result = adc_read(_dev, 17); - - vcc = (float)result * 1.1; //to be done later... + float STM32ADC::readVcc() { + uint16_t result = adc_read(_dev, 17); + float vcc = (float)result * 1.1; //to be done later... return vcc; } @@ -64,11 +16,10 @@ This will read the Temperature and return something useful. Polling is being used. */ - float STM32ADC::readTemp(){ - unsigned int result = 0; - float temperature = 0.0; - result = adc_read(_dev, 16); - temperature = (float)((_V25-result)/_AverageSlope)+ 25.0; + float STM32ADC::readTemp() { + uint16_t result = adc_read(_dev, 16); + float Vsense = (3300.0*result)/4096; + float temperature = ((_V25-Vsense)/_AverageSlope) + 25.0; return temperature; } @@ -80,9 +31,8 @@ //convert pins to channels. uint8 channels[length]; unsigned int records[3] = {0,0,0}; - unsigned char i = 0, j = 0; - for (unsigned char i = 0; i < length; i++) { //convert the channels from pins to ch. + for (uint8_t i = 0; i < length; i++) { //convert the channels from pins to ch. channels[i] = PIN_MAP[pins[i]].adc_channel; } @@ -93,7 +43,7 @@ records[2] |= (length - 1) << 20; //i goes through records, j goes through variables. - for (i = 0, j = 0; i < length; i++) {//go through the channel list. + for (uint8_t i = 0, j = 0; i < length; i++) {//go through the channel list. if (i!=0 && i%6 == 0) j++;//next variable, please!! records[j] |= (channels[i] << ((i%6)*5)); } @@ -103,57 +53,6 @@ _dev->regs->SQR3 = records[0]; } -/* - This function will set the number of channels to convert - And which channels. - This is the ADC channels and not the Maple Pins!!! Important!! - Also, this will allow you to sample the AD and Vref channels. -*/ - void STM32ADC::setChannels(uint8 *channels, uint8 length){ - adc_set_reg_seq_channel(_dev, channels, length); - } - -/* - This function will set the trigger to start the conversion - Timer, SWStart, etc... -*/ - void STM32ADC::setTrigger(adc_extsel_event trigger){ - adc_set_extsel(_dev, trigger); - } - -/* - this function will set the continuous conversion bit. -*/ - void STM32ADC::setContinuous(){ - _dev->regs->CR2 |= ADC_CR2_CONT; - }; - -/* - this function will reset the continuous bit. -*/ - void STM32ADC::resetContinuous(){ - _dev->regs->CR2 &= ~ADC_CR2_CONT; - }; - -/* - This will be used to start conversions -*/ - void STM32ADC::startConversion(){ - _dev->regs->CR2 |= ADC_CR2_SWSTART; - } - -/* - This will set the Scan Mode on. - This will use DMA. -*/ - void STM32ADC::setScanMode(){ - _dev->regs->CR1 |= ADC_CR1_SCAN; - } - - void STM32ADC::calibrate() { - adc_calibrate(_dev); - } - /* This function is used to setup DMA with the ADC. It will be independent of the mode used. It will either be used in continuous or scan mode @@ -162,23 +61,27 @@ The reason why this is a uint16 is that I am not ready for dual mode. */ - void STM32ADC::setDMA(uint16 * Buf, uint16 BufLen, uint32 dmaFlags, voidFuncPtr func) { + void STM32ADC::setDMA(uint16 * Buf, uint32 dmaFlags, voidFuncPtr func) + { //initialize DMA dma_init(DMA1); + dma_disable(DMA1, DMA_CH1); //if there is an int handler to be called... if (func != NULL) dma_attach_interrupt(DMA1, DMA_CH1, func); //enable ADC DMA transfer - //adc_dma_enable(ADC1); - _dev->regs->CR2 |= ADC_CR2_DMA; + adc_dma_enable(ADC1); + //_dev->regs->CR2 |= ADC_CR2_DMA; //set it up... dma_setup_transfer(DMA1, DMA_CH1, &ADC1->regs->DR, DMA_SIZE_16BITS, Buf, DMA_SIZE_16BITS, dmaFlags);// Receive buffer DMA -//how many are we making?? - dma_set_num_transfers(DMA1, DMA_CH1, BufLen); -//enable dma. - dma_enable(DMA1, DMA_CH1); // Enable the channel and start the transfer. } + void STM32ADC::startDMA(uint16 BufLen) + { + dma_disable(DMA1, DMA_CH1); + dma_set_num_transfers(DMA1, DMA_CH1, BufLen); + dma_enable(DMA1, DMA_CH1); // Enable the channel + } /* This function is used to setup DMA with the ADC. It will be independent of the mode used. It will either be used in continuous or scan mode @@ -194,24 +97,16 @@ dma_enable(DMA1, DMA_CH1); // Enable the channel and start the transfer. } -/* - This will set the Scan Mode on. - This will use DMA. -*/ - void STM32ADC::attachDMAInterrupt(voidFuncPtr func){ - _DMA_int = func; - dma_attach_interrupt(DMA1, DMA_CH1, func); - } - /* This will set an Analog Watchdog on a channel. It must be used with a channel that is being converted. */ - void STM32ADC::setAnalogWatchdog(uint8 channel, uint32 HighLimit, uint32 LowLimit){ - set_awd_low_limit(_dev, LowLimit); - set_awd_high_limit(_dev, HighLimit); - set_awd_channel(_dev, channel); - } + void STM32ADC::setAnalogWatchdog(uint8 channel, uint32 HighLimit, uint32 LowLimit) + { + set_awd_low_limit(_dev, LowLimit); + set_awd_high_limit(_dev, HighLimit); + set_awd_channel(_dev, channel); + } /* check analog watchdog @@ -220,13 +115,3 @@ uint8 STM32ADC::getAnalogWatchdog(){ return 1; } - -/* - Attach an interrupt to the Watchdog... - This can possibly be set together in one function and determine which peripheral - it relates to. -*/ - void STM32ADC::attachAnalogWatchdogInterrupt(voidFuncPtr func){ - _AWD_int = func; - - } diff --git a/STM32F1/libraries/STM32ADC/src/STM32ADC.h b/STM32F1/libraries/STM32ADC/src/STM32ADC.h index fd0588f5e..a9a6737ef 100644 --- a/STM32F1/libraries/STM32ADC/src/STM32ADC.h +++ b/STM32F1/libraries/STM32ADC/src/STM32ADC.h @@ -11,19 +11,35 @@ class STM32ADC{ Choose which ADC to use. Start it up... */ - STM32ADC (adc_dev * dev); + STM32ADC (adc_dev * dev) { + _dev = dev; + } /* Set the ADC Sampling Rate. + ADC_SMPR_1_5, < 1.5 ADC cycles + ADC_SMPR_7_5, < 7.5 ADC cycles + ADC_SMPR_13_5, < 13.5 ADC cycles + ADC_SMPR_28_5, < 28.5 ADC cycles + ADC_SMPR_41_5, < 41.5 ADC cycles + ADC_SMPR_55_5, < 55.5 ADC cycles + ADC_SMPR_71_5, < 71.5 ADC cycles + ADC_SMPR_239_5, < 239.5 ADC cycles */ - void setSampleRate(adc_smp_rate SampleRate); + void setSampleRate(adc_smp_rate SampleRate) { + adc_set_sample_rate(_dev, SampleRate); + } /* Attach an interrupt to the ADC completion. */ - void attachInterrupt(voidFuncPtr func, uint8 interrupt); + void attachInterrupt(voidFuncPtr func) { + adc_attach_interrupt(_dev, ADC_EOC, func); + } - void calibrate(); + void calibrate() { + adc_calibrate(_dev); + } /* This function is used to setup DMA with the ADC. @@ -32,8 +48,14 @@ class STM32ADC{ The reason why this is a uint16 is that I am not ready for dual mode. */ - void setDMA(uint16 * Buf, uint16 BufLen, uint32 dmaFlags, voidFuncPtr func); + void setDMA(uint16 * Buf, uint32 dmaFlags, voidFuncPtr func); + void startDMA(uint16 BufLen); + void setDMA(uint16 * Buf, uint16 BufLen, uint32 dmaFlags, voidFuncPtr func) { + setDMA(Buf, dmaFlags, func); + startDMA(BufLen); + } + /* This function is used to setup DMA with the ADC. It will be independent of the mode used. It will either be used in continuous or scan mode @@ -45,7 +67,9 @@ class STM32ADC{ /* This will enable the internal readings. Vcc and Temperature */ - void enableInternalReading(); + void enableInternalReading() { + enable_internal_reading(_dev); + } /* This will read the Vcc and return something useful. @@ -62,9 +86,13 @@ class STM32ADC{ /* This function will set the number of channels to convert And which channels. - For pin numbers, see setPins below + This is the ADC channels and not the Maple Pins!!! Important!! + However, PA0 to 7 correspond to ADC channels 0 to 7. + Also, this will allow you to sample the AD and Vref channels. */ - void setChannels(uint8 *pins, uint8 length); + void setChannels(uint8 *pins, uint8 length) { + adc_set_reg_seq_channel(_dev, pins, length); + } /* This function will set the number of pins to convert @@ -93,38 +121,49 @@ class STM32ADC{ ADC_EXT_EV_ADC12_TIM8_TRGO ADC_EXT_EV_TIM5_CC3 */ - void setTrigger(adc_extsel_event trigger); + void setTrigger(adc_extsel_event trigger) { + adc_set_extsel(_dev, trigger); + } /* this function will set the continuous conversion bit. */ - void setContinuous(); + void setContinuous() { + _dev->regs->CR2 |= ADC_CR2_CONT; + } /* this function will reset the continuous bit. */ - void resetContinuous(); + void resetContinuous() { + _dev->regs->CR2 &= ~ADC_CR2_CONT; + } /* This will be used to start conversions */ - void startConversion(); + void startConversion() { + _dev->regs->CR2 |= ADC_CR2_SWSTART; + } /* This will set the Scan Mode on. This will use DMA. */ - void setScanMode(); + void setScanMode() { + _dev->regs->CR1 |= ADC_CR1_SCAN; + } /* This will set the Scan Mode on. This will use DMA. */ - void attachDMAInterrupt(voidFuncPtr func); + void attachDMAInterrupt(voidFuncPtr func) { dma_attach_interrupt(DMA1, DMA_CH1, func); }; /* This will set an Analog Watchdog on a channel. It must be used with a channel that is being converted. + Set bit 7 of channel parameter to use all channels for AWD */ void setAnalogWatchdog(uint8 channel, uint32 HighLimit, uint32 LowLimit); @@ -139,20 +178,23 @@ class STM32ADC{ This can possibly be set together in one function and determine which peripheral it relates to. */ - void attachAnalogWatchdogInterrupt(voidFuncPtr func); + void attachAnalogWatchdogInterrupt(voidFuncPtr func) { + adc_attach_interrupt(_dev, ADC_AWD, func); + } + void enableAnalogWatchdog(void) { enable_awd(_dev); } + void disableAnalogWatchdog(void) { disable_awd(_dev); } /* Retrieve the contents of the DR register. */ - uint32 getData(); + uint32 getData() { + return _dev->regs->DR; + } private: adc_dev * _dev; - voidFuncPtr _DMA_int; - voidFuncPtr _ADC_int; - voidFuncPtr _AWD_int; - static const float _AverageSlope = 4.3; // mV/oC //4.0 to 4.6 - static const float _V25 = 1.43; //Volts //1.34 - 1.52 + static constexpr float _AverageSlope = 4.3; // mV/oC //4.0 to 4.6 + static constexpr float _V25 = 1.43; //Volts //1.34 - 1.52 }; diff --git a/STM32F1/libraries/STM32ADC/src/utility/util_adc.c b/STM32F1/libraries/STM32ADC/src/utility/util_adc.c index 360b235cd..79ec68fda 100644 --- a/STM32F1/libraries/STM32ADC/src/utility/util_adc.c +++ b/STM32F1/libraries/STM32ADC/src/utility/util_adc.c @@ -1,52 +1,51 @@ #include "util_adc.h" #include -//#include "boards.h" #include /* Interrupt function. This handles Analog watchdog and ADC1 and 2. */ -extern volatile unsigned int adc_result = 0; +//extern volatile unsigned int adc_result = 0; /* Starts a single conversion in one channel previously defined. Results must be read through interrupt or polled outside this function. */ -void start_single_convert(adc_dev* dev, uint8 channel) { -// int pinMapADCin = PIN_MAP[analogInPin].adc_channel; - adc_set_reg_seqlen(dev, 1); - dev->regs->SQR3 = channel;//use channels next time. - dev->regs->CR2 |= ADC_CR2_SWSTART; - } +void start_single_convert(adc_dev* dev, uint8 channel) +{ + adc_set_reg_seqlen(dev, 1); + dev->regs->SQR3 = channel;//use channels next time. + dev->regs->CR2 |= ADC_CR2_SWSTART; +} /* Starts the continuous mode on one channel of the AD. Results must be read through interrupt or polled outside this function. */ -void start_continuous_convert(adc_dev* dev, uint8 channel){ -// int pinMapADCin = PIN_MAP[analogInPin].adc_channel; - adc_set_reg_seqlen(dev, 1); - dev->regs->SQR3 = channel; - dev->regs->CR2 |= ADC_CR2_CONT; - dev->regs->CR2 |= ADC_CR2_SWSTART; - } +void start_continuous_convert(adc_dev* dev, uint8 channel) +{ + adc_set_reg_seqlen(dev, 1); + dev->regs->SQR3 = channel; + dev->regs->CR2 |= ADC_CR2_CONT; + dev->regs->CR2 |= ADC_CR2_SWSTART; +} /* Enable end of conversion interrupt on the ADC. This is for regular conversion, not injected. */ void enable_adc_irq(adc_dev* dev) {//ADC1 for now. - dev->regs->CR1 |= (1U<regs->CR1 |= (1U<regs->CR2 |= ADC_CR2_TSVREFE; - } + dev->regs->CR2 |= ADC_CR2_TSVREFE; +} /* Read internal variables. @@ -55,53 +54,35 @@ void enable_internal_reading(adc_dev *dev) { 17 - VrefInt Results must be read through interrupt or polled outside this function. */ -void internalRead(adc_dev *dev, uint8 channel) { - adc_reg_map *regs = dev->regs; - adc_set_reg_seqlen(dev, 1); - regs->SQR3 = channel; - regs->CR2 |= ADC_CR2_SWSTART; - } +void internalRead(adc_dev *dev, uint8 channel) +{ + adc_reg_map *regs = dev->regs; + adc_set_reg_seqlen(dev, 1); + regs->SQR3 = channel; + regs->CR2 |= ADC_CR2_SWSTART; +} /* Enable the Analog Watchdog interrupt */ -void enable_awd_irq(adc_dev * dev){ - dev->regs->CR1 |= (1U<regs->LTR = limit; - } - -/* - Set Analog Watchdog High Limit. - Results must be read through interrupt or polled outside this function. -*/ -void set_awd_high_limit(adc_dev * dev, uint32 limit) { - dev->regs->HTR = limit; - } +void enable_awd_irq(adc_dev * dev) +{ + dev->regs->CR1 |= (1U<regs->CR1 |= (awd_channel & ADC_CR1_AWDCH); - } - +void set_awd_channel(adc_dev * dev, uint8 awd_channel) +{ + dev->regs->CR1 &= ~(ADC_CR1_AWDSGL|ADC_CR1_AWDCH); // multi channel, clear single flag + if ( (awd_channel&0x80)==0 ) + dev->regs->CR1 |= (ADC_CR1_AWDSGL); // single channel -/* - Enable the Watchdog function on the ADC. -*/ -void enable_awd(adc_dev * dev){ - dev->regs->CR1 |= ADC_CR1_AWDEN; + dev->regs->CR1 |= (awd_channel & ADC_CR1_AWDCH); } - /* Used to configure the sequence and length of the scan mode. Can be used instead of adc_set_reg_seqlen() as it sets both information diff --git a/STM32F1/libraries/STM32ADC/src/utility/util_adc.h b/STM32F1/libraries/STM32ADC/src/utility/util_adc.h index 3c8ec1281..1d78e390d 100644 --- a/STM32F1/libraries/STM32ADC/src/utility/util_adc.h +++ b/STM32F1/libraries/STM32ADC/src/utility/util_adc.h @@ -1,3 +1,10 @@ +#ifndef UTIL_ADC_H +#define UTIL_ADC_H + +#ifdef __cplusplus +extern "C" { +#endif + #include @@ -11,13 +18,32 @@ void enable_internal_reading(adc_dev *dev); void internalRead(adc_dev *dev, uint8 channel); -void enable_awd_irq( adc_dev * dev); - -void set_awd_low_limit( adc_dev * dev, uint32 limit); - -void set_awd_high_limit( adc_dev * dev, uint32 limit); - -void enable_awd( adc_dev * dev); +/* + Enable the Watchdog function on the ADC. +*/ +static inline void enable_awd(adc_dev * dev) { + dev->regs->CR1 |= ADC_CR1_AWDEN; +} + +static inline void disable_awd(adc_dev * dev) { + dev->regs->CR1 &= ~ADC_CR1_AWDEN; +} + +/* + Set Analog Watchdog Low Limit. + Results must be read through interrupt or polled outside this function. +*/ +static inline void set_awd_low_limit(adc_dev * dev, uint32 limit) { + dev->regs->LTR = limit; +} + +/* + Set Analog Watchdog High Limit. + Results must be read through interrupt or polled outside this function. +*/ +static inline void set_awd_high_limit(adc_dev * dev, uint32 limit) { + dev->regs->HTR = limit; +} void set_awd_channel( adc_dev * dev, uint8 awd_channel); @@ -27,4 +53,10 @@ void set_continuous( adc_dev * dev); uint8 poll_adc_convert(adc_dev *dev); -void adc_dma_enable(adc_dev * dev); \ No newline at end of file +void adc_dma_enable(adc_dev * dev); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // UTIL_ADC_H diff --git a/STM32F1/libraries/Serasidis_XPT2046_touch/examples/TouchButtons/TouchButtons.ino b/STM32F1/libraries/Serasidis_XPT2046_touch/examples/TouchButtons/TouchButtons.ino index 5ca9606c0..c710c6a5d 100644 --- a/STM32F1/libraries/Serasidis_XPT2046_touch/examples/TouchButtons/TouchButtons.ino +++ b/STM32F1/libraries/Serasidis_XPT2046_touch/examples/TouchButtons/TouchButtons.ino @@ -32,12 +32,12 @@ XPT2046_touch ts(CS_PIN, mySPI); // Chip Select pin, SPI port uint16_t xy[2]; void setup() { - Serial1.begin(9600); - Serial1.println("-------------------------------------------------"); - Serial1.println("XPT2046 touch screen buttons"); - Serial1.println("Copyright (c) 02 Dec 2015 by Vassilis Serasidis"); - Serial1.println("Home: http://www.serasidis.gr"); - Serial1.println("-------------------------------------------------"); + Serial.begin(9600); + Serial.println("-------------------------------------------------"); + Serial.println("XPT2046 touch screen buttons"); + Serial.println("Copyright (c) 02 Dec 2015 by Vassilis Serasidis"); + Serial.println("Home: http://www.serasidis.gr"); + Serial.println("-------------------------------------------------"); ts.begin(); //Begin TouchScreen. ts.setButtonsNumber(COLUMNS, LINES); //Divide the Touch screen area into 4 columns and 2 lines and make them act as buttons. } @@ -46,15 +46,15 @@ void loop() { if(ts.read_XY(xy)){ //If the touch screen is preesed, read the X,Y coordinates and print them on Serial port. uint8_t buttonNumber = ts.getButtonNumber(); if(buttonNumber > 0){ - Serial1.print("Button: "); - Serial1.println(buttonNumber); + Serial.print("Button: "); + Serial.println(buttonNumber); - Serial1.print("X: "); - Serial1.println(xy[0]); //Print X value - Serial1.print("Y: "); - Serial1.println(xy[1]); //Print Y value - Serial1.println(); + Serial.print("X: "); + Serial.println(xy[0]); //Print X value + Serial.print("Y: "); + Serial.println(xy[1]); //Print Y value + Serial.println(); } delay(500); } -} \ No newline at end of file +} diff --git a/STM32F1/libraries/Serasidis_XPT2046_touch/src/XPT2046_touch.cpp b/STM32F1/libraries/Serasidis_XPT2046_touch/src/XPT2046_touch.cpp index d1b0bdf98..f24c67ad5 100644 --- a/STM32F1/libraries/Serasidis_XPT2046_touch/src/XPT2046_touch.cpp +++ b/STM32F1/libraries/Serasidis_XPT2046_touch/src/XPT2046_touch.cpp @@ -8,81 +8,97 @@ #include "Arduino.h" #include "XPT2046_touch.h" +XPT2046_touch::XPT2046_touch(uint8_t _cs_pin, SPIClass _spiChan) : cs_pin(_cs_pin), my_SPI(_spiChan){ + setOversampling(); + setThreshold(); +} -/****************************************************************************/ - XPT2046_touch::XPT2046_touch(uint8_t _cs_pin, SPIClass _spiChan) : cs_pin(_cs_pin), my_SPI(_spiChan){ - } - - -/****************************************************************************/ - - void XPT2046_touch::begin(){ +void XPT2046_touch::begin(){ pinMode(cs_pin, OUTPUT); digitalWrite(cs_pin, HIGH); my_SPI.begin(); - } +} + +uint16_t XPT2046_touch::gatherSamples(uint8_t command) { + uint32_t sample_sum = 0; + uint16_t samples[MAX_OVERSAMPLING]; + + my_SPI.transfer16(command); // discard first reading after switching MUX + for (int i = 0; i < oversampling; ++i) { + samples[i] = my_SPI.transfer16(command); + sample_sum += samples[i]; + } + int32_t avg = sample_sum / oversampling; + if (oversampling < 3) { + return avg >> 3; + } + + // occasionally, we get a reading that is a _far_ outlier. + // checking for, and removing those improves quality a lot. + uint8_t n = oversampling; + for (int i = 0; i < oversampling; ++i) { + if (abs(avg - samples[i]) > 80) { // NOTE: data is left shifted by 3 at this point. I.e. the test is for 10+ pixels deviation from average + sample_sum -= samples[i]; + --n; + } + } + if (n < 2) return avg >> 3; + else return (sample_sum / n) >> 3; +} - /****************************************************************************/ +TS_Point XPT2046_touch::getPoint() { + uint16_t z1, z2; - boolean XPT2046_touch::read_XY(uint16_t *xy){ - int z1, z2, tmpH, tmpL; + my_SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0)); // max clock freq for XPT2046 digitalWrite(cs_pin, LOW); + TS_Point ret; //Check if touch screen is pressed. - SPI.transfer(B10110011); // Z1 - delay(10); - tmpH = (my_SPI.transfer(0) << 5); - tmpL = (my_SPI.transfer(0) >> 3); - z1 = tmpH | tmpL; - - SPI.transfer(B11000011); // Z2 - delay(10); - tmpH = (my_SPI.transfer(0) << 5); - tmpL = (my_SPI.transfer(0) >> 3); - z2 = tmpH | tmpL; - - if((z2 - z1) < Z_THRESHOLD){ //If the touch screen is pressed, read the X,Y coordinates from XPT2046. - my_SPI.transfer(B11010011); // X - delay(10); - tmpH = (my_SPI.transfer(0) << 5); - tmpL = (my_SPI.transfer(0) >> 3); - xy[0] = tmpH | tmpL; - - my_SPI.transfer(B10010011); // Y - delay(10); - tmpH = (my_SPI.transfer(0) << 5); - tmpL = (my_SPI.transfer(0) >> 3); - xy[1] = tmpH | tmpL; - digitalWrite(cs_pin, HIGH); - return true; + my_SPI.transfer(B10110011); // trigger Z1 reading + z1 = my_SPI.transfer16(B11000011) >> 3; // read Z1, and trigger Z2 reading + z2 = my_SPI.transfer16(B10010011) >> 3; // read Z2, and trigger Y reading + ret.z = z1 + 4095 - z2; + + if(ret.z >= threshold){ //If the touch screen is pressed, read the X,Y coordinates from XPT2046. + ret.x = gatherSamples(B10010011); + ret.y = gatherSamples(B11010011); + } else { + ret.z = 0; } + my_SPI.transfer(B00000000); // enter power saving (and IRQ enable) + digitalWrite(cs_pin, HIGH); - return false; - } - - /****************************************************************************/ - void XPT2046_touch::setButtonsNumber(byte columnButtons, byte rowButtons ){ - _rowButtons = rowButtons; - _columnButtons = columnButtons; - } - - /****************************************************************************/ - uint8_t XPT2046_touch::getButtonNumber(){ + my_SPI.endTransaction(); + return ret; +} + +boolean XPT2046_touch::read_XY(uint16_t *xy) { + TS_Point p = getPoint(); + xy[0] = p.x; + xy[1] = p.y; + return p.z > 0; +} + +////////////////// Buttons //////////////// +void XPT2046_touch::setButtonsNumber(byte columnButtons, byte rowButtons ){ + _rowButtons = rowButtons; + _columnButtons = columnButtons; +} + +uint8_t XPT2046_touch::getButtonNumber(){ uint16_t xy[2]; uint8_t tmp, buttonNum; int div; if(read_XY(xy)){ - - div = (X_MAX + X_MIN) / (_columnButtons + 1); - buttonNum = ((xy[1] / div)); - - div = (Y_MAX + Y_MIN) / _rowButtons; - tmp = ((xy[0] / div)); - - return ((buttonNum * _rowButtons) + tmp + 1); //Return the button number. + div = (X_MAX + X_MIN) / (_columnButtons + 1); + buttonNum = ((xy[1] / div)); + + div = (Y_MAX + Y_MIN) / _rowButtons; + tmp = ((xy[0] / div)); + + return ((buttonNum * _rowButtons) + tmp + 1); //Return the button number. } return 0; //Touch screen is not pressed. - } -/****************************************************************************/ +} diff --git a/STM32F1/libraries/Serasidis_XPT2046_touch/src/XPT2046_touch.h b/STM32F1/libraries/Serasidis_XPT2046_touch/src/XPT2046_touch.h index 083016295..9fbea6a82 100644 --- a/STM32F1/libraries/Serasidis_XPT2046_touch/src/XPT2046_touch.h +++ b/STM32F1/libraries/Serasidis_XPT2046_touch/src/XPT2046_touch.h @@ -11,7 +11,8 @@ #include #include -#define Z_THRESHOLD 3000 +#define Z_THRESHOLD 3500 // Note: reversed for backwards compatiblity: 4095-x +#define MAX_OVERSAMPLING 32 // Pre-defined touch screen calibration for using the 2.4" ILI9341 LCD #define X_MIN 830 @@ -19,23 +20,54 @@ #define Y_MIN 550 #define Y_MAX 3550 + +class TS_Point { +public: + TS_Point(void) : x(0), y(0), z(0) {} + TS_Point(int16_t x, int16_t y, int16_t z) : x(x), y(y), z(z) {} + bool operator==(TS_Point p) { return ((p.x == x) && (p.y == y) && (p.z == z)); } + bool operator!=(TS_Point p) { return ((p.x != x) || (p.y != y) || (p.z != z)); } + int16_t x, y, z; +}; + /** * */ - -class XPT2046_touch{ +class XPT2046_touch { private: uint8_t cs_pin; SPIClass my_SPI; uint8_t _rowButtons = 1; uint8_t _columnButtons = 1; + uint8_t oversampling; + uint16_t threshold; + uint16_t gatherSamples(uint8_t command); public: - XPT2046_touch(uint8_t _cs_pin, SPIClass _spiChan); //Contructor. + /** c'tor. Note that no IRQ pin is supported, here. You can easily do that yourself: + * \code if(digitalRead(irq_pin)) { + * // no press: skip + * } else { + * // _may_ be touched, but not necessarily reach the threshold + * TS_Point p = ts.getPoint(); + * if (p.z > 0) { + * // do something + * } + * } + * \endcode */ + XPT2046_touch(uint8_t _cs_pin, SPIClass _spiChan); //Contructor void begin(); void setButtonsNumber(byte rowButtons, byte columnButtons); + /** Number of samples to average per point 0..32 */ + void setOversampling(uint8_t num_readings = 7) { + oversampling = max(1, min(num_readings, MAX_OVERSAMPLING)); + } + void setThreshold(uint16_t threshold = 4095 - Z_THRESHOLD) { + XPT2046_touch::threshold = threshold; + } uint8_t getButtonNumber(); boolean read_XY(uint16_t *xy); + TS_Point getPoint(); }; #endif diff --git a/STM32F1/libraries/USBComposite/AbsMouse.cpp b/STM32F1/libraries/USBComposite/AbsMouse.cpp new file mode 100644 index 000000000..4899bab83 --- /dev/null +++ b/STM32F1/libraries/USBComposite/AbsMouse.cpp @@ -0,0 +1,56 @@ +#include "USBComposite.h" + +//================================================================================ +//================================================================================ +// Mouse + +void HIDAbsMouse::begin(void){ +} + +void HIDAbsMouse::end(void){ +} + +void HIDAbsMouse::click(uint8_t b) +{ + report.wheel = 0; + report.buttons = b; + sendReport(); + report.buttons = 0; + sendReport(); +} + +void HIDAbsMouse::move(int16 x, int16 y, int8 wheel) +{ + report.x = x; + report.y = y; + report.wheel = wheel; + + sendReport(); +} + +void HIDAbsMouse::buttons(uint8_t b) +{ + if (b != report.buttons) + { + report.wheel = 0; + report.buttons = b; + sendReport(); + } +} + +void HIDAbsMouse::press(uint8_t b) +{ + buttons(report.buttons | b); +} + +void HIDAbsMouse::release(uint8_t b) +{ + buttons(report.buttons & ~b); +} + +bool HIDAbsMouse::isPressed(uint8_t b) +{ + if ((b & report.buttons) != 0) + return true; + return false; +} diff --git a/STM32F1/libraries/USBComposite/Consumer.cpp b/STM32F1/libraries/USBComposite/Consumer.cpp new file mode 100644 index 000000000..2409d9552 --- /dev/null +++ b/STM32F1/libraries/USBComposite/Consumer.cpp @@ -0,0 +1,13 @@ +#include "USBComposite.h" + +void HIDConsumer::begin(void) {} +void HIDConsumer::end(void) {} +void HIDConsumer::press(uint16_t button) { + report.button = button; + sendReport(); +} + +void HIDConsumer::release() { + report.button = 0; + sendReport(); +} diff --git a/STM32F1/libraries/USBComposite/Digitizer.cpp b/STM32F1/libraries/USBComposite/Digitizer.cpp new file mode 100644 index 000000000..48bdf8fba --- /dev/null +++ b/STM32F1/libraries/USBComposite/Digitizer.cpp @@ -0,0 +1,51 @@ +#include "USBComposite.h" + +//================================================================================ +//================================================================================ +// Mouse + +void HIDDigitizer::begin(void){ +} + +void HIDDigitizer::end(void){ +} + +void HIDDigitizer::move(uint16 x, uint16 y) +{ + report.x = x; + report.y = y; + + sendReport(); +} + +void HIDDigitizer::buttons(uint8_t b) +{ + if (b != report.buttons) + { + report.buttons = b; + sendReport(); + } +} + +void HIDDigitizer::click(uint8_t b) +{ + press(b); + release(b); +} + +void HIDDigitizer::press(uint8_t b) +{ + buttons(report.buttons | b); +} + +void HIDDigitizer::release(uint8_t b) +{ + buttons(report.buttons & ~b); +} + +bool HIDDigitizer::isPressed(uint8_t b) +{ + if ((b & report.buttons) == b) + return true; + return false; +} diff --git a/STM32F1/libraries/USBComposite/HIDReports.cpp b/STM32F1/libraries/USBComposite/HIDReports.cpp new file mode 100644 index 000000000..75f4662b3 --- /dev/null +++ b/STM32F1/libraries/USBComposite/HIDReports.cpp @@ -0,0 +1,18 @@ +#include "USBComposite.h" + +#define REPORT(name, ...) \ + static uint8_t raw_ ## name[] = { __VA_ARGS__ }; \ + static const HIDReportDescriptor desc_ ## name = { raw_ ##name, sizeof(raw_ ##name) }; \ + const HIDReportDescriptor* hidReport ## name = & desc_ ## name; + +REPORT(KeyboardMouseJoystick, HID_MOUSE_REPORT_DESCRIPTOR(), HID_KEYBOARD_REPORT_DESCRIPTOR(), HID_JOYSTICK_REPORT_DESCRIPTOR()); +REPORT(KeyboardMouse, HID_MOUSE_REPORT_DESCRIPTOR(), HID_KEYBOARD_REPORT_DESCRIPTOR()); +REPORT(Keyboard, HID_KEYBOARD_REPORT_DESCRIPTOR()); +REPORT(Mouse, HID_MOUSE_REPORT_DESCRIPTOR()); +REPORT(AbsMouse, HID_ABS_MOUSE_REPORT_DESCRIPTOR()); +REPORT(KeyboardJoystick, HID_KEYBOARD_REPORT_DESCRIPTOR(), HID_JOYSTICK_REPORT_DESCRIPTOR()); +REPORT(Joystick, HID_JOYSTICK_REPORT_DESCRIPTOR()); +REPORT(BootKeyboard, HID_BOOT_KEYBOARD_REPORT_DESCRIPTOR()); +REPORT(Consumer, HID_CONSUMER_REPORT_DESCRIPTOR()); +REPORT(Digitizer, HID_DIGITIZER_REPORT_DESCRIPTOR()); +REPORT(SwitchController, HID_SWITCH_CONTROLLER_REPORT_DESCRIPTOR()); diff --git a/STM32F1/libraries/USBComposite/Joystick.cpp b/STM32F1/libraries/USBComposite/Joystick.cpp new file mode 100644 index 000000000..4f39d55e6 --- /dev/null +++ b/STM32F1/libraries/USBComposite/Joystick.cpp @@ -0,0 +1,117 @@ +#include "USBComposite.h" + +// This code requires gcc on low-endian devices. + +//================================================================================ +//================================================================================ +// Joystick + +void HIDJoystick::begin(void){ +} + +void HIDJoystick::end(void){ +} + +void HIDJoystick::setManualReportMode(bool mode) { + manualReport = mode; +} + +bool HIDJoystick::getManualReportMode() { + return manualReport; +} + +void HIDJoystick::safeSendReport() { + if (!manualReport) { + sendReport(); + } +} + +void HIDJoystick::button(uint8_t button, bool val){ + uint32_t mask = ((uint32_t)1 << (button-1)); + + if (val) { + joyReport.buttons |= mask; + } else { + joyReport.buttons &= ~mask; + } + + safeSendReport(); +} + +void HIDJoystick::X(uint16_t val){ + if (val > 1023) val = 1023; + joyReport.x = val; + + safeSendReport(); +} + +void HIDJoystick::Y(uint16_t val){ + if (val > 1023) val = 1023; + joyReport.y = val; + + safeSendReport(); +} + +void HIDJoystick::position(uint16_t x, uint16_t y){ + if (x > 1023) x = 1023; + if (y > 1023) y = 1023; + joyReport.x = x; + joyReport.y = y; + + safeSendReport(); +} + +void HIDJoystick::Xrotate(uint16_t val){ + if (val > 1023) val = 1023; + joyReport.rx = val; + + safeSendReport(); +} + +void HIDJoystick::Yrotate(uint16_t val){ + if (val > 1023) val = 1023; + joyReport.ry = val; + + safeSendReport(); +} + +void HIDJoystick::sliderLeft(uint16_t val){ + if (val > 1023) val = 1023; + joyReport.sliderLeft = val; + + safeSendReport(); +} + +void HIDJoystick::sliderRight(uint16_t val){ + if (val > 1023) val = 1023; + joyReport.sliderRight = val; + + safeSendReport(); +} + +void HIDJoystick::slider(uint16_t val){ + if (val > 1023) val = 1023; + joyReport.sliderLeft = val; + joyReport.sliderRight = val; + + safeSendReport(); +} + +void HIDJoystick::hat(int16_t dir){ + uint8_t val; + if (dir < 0) val = 15; + else if (dir < 23) val = 0; + else if (dir < 68) val = 1; + else if (dir < 113) val = 2; + else if (dir < 158) val = 3; + else if (dir < 203) val = 4; + else if (dir < 245) val = 5; + else if (dir < 293) val = 6; + else if (dir < 338) val = 7; + else val = 15; + + joyReport.hat = val; + + safeSendReport(); +} + diff --git a/STM32F1/libraries/USBComposite/Keyboard.cpp b/STM32F1/libraries/USBComposite/Keyboard.cpp new file mode 100644 index 000000000..16b70b01f --- /dev/null +++ b/STM32F1/libraries/USBComposite/Keyboard.cpp @@ -0,0 +1,263 @@ +#include "USBComposite.h" +#include + +//================================================================================ +//================================================================================ +// Keyboard + +#define SHIFT 0x80 +static const uint8_t ascii_to_hid[128] = +{ + 0x00, // NUL + 0x00, // SOH + 0x00, // STX + 0x00, // ETX + 0x00, // EOT + 0x00, // ENQ + 0x00, // ACK + 0x00, // BEL + 0x2a, // BS Backspace + 0x2b, // TAB Tab + 0x28, // LF Enter + 0x00, // VT + 0x00, // FF + 0x00, // CR + 0x00, // SO + 0x00, // SI + 0x00, // DEL + 0x00, // DC1 + 0x00, // DC2 + 0x00, // DC3 + 0x00, // DC4 + 0x00, // NAK + 0x00, // SYN + 0x00, // ETB + 0x00, // CAN + 0x00, // EM + 0x00, // SUB + 0x00, // ESC + 0x00, // FS + 0x00, // GS + 0x00, // RS + 0x00, // US + + 0x2c, // ' ' + 0x1e|SHIFT, // ! + 0x34|SHIFT, // " + 0x20|SHIFT, // # + 0x21|SHIFT, // $ + 0x22|SHIFT, // % + 0x24|SHIFT, // & + 0x34, // ' + 0x26|SHIFT, // ( + 0x27|SHIFT, // ) + 0x25|SHIFT, // * + 0x2e|SHIFT, // + + 0x36, // , + 0x2d, // - + 0x37, // . + 0x38, // / + 0x27, // 0 + 0x1e, // 1 + 0x1f, // 2 + 0x20, // 3 + 0x21, // 4 + 0x22, // 5 + 0x23, // 6 + 0x24, // 7 + 0x25, // 8 + 0x26, // 9 + 0x33|SHIFT, // : + 0x33, // ; + 0x36|SHIFT, // < + 0x2e, // = + 0x37|SHIFT, // > + 0x38|SHIFT, // ? + 0x1f|SHIFT, // @ + 0x04|SHIFT, // A + 0x05|SHIFT, // B + 0x06|SHIFT, // C + 0x07|SHIFT, // D + 0x08|SHIFT, // E + 0x09|SHIFT, // F + 0x0a|SHIFT, // G + 0x0b|SHIFT, // H + 0x0c|SHIFT, // I + 0x0d|SHIFT, // J + 0x0e|SHIFT, // K + 0x0f|SHIFT, // L + 0x10|SHIFT, // M + 0x11|SHIFT, // N + 0x12|SHIFT, // O + 0x13|SHIFT, // P + 0x14|SHIFT, // Q + 0x15|SHIFT, // R + 0x16|SHIFT, // S + 0x17|SHIFT, // T + 0x18|SHIFT, // U + 0x19|SHIFT, // V + 0x1a|SHIFT, // W + 0x1b|SHIFT, // X + 0x1c|SHIFT, // Y + 0x1d|SHIFT, // Z + 0x2f, // [ + 0x31, // bslash + 0x30, // ] + 0x23|SHIFT, // ^ + 0x2d|SHIFT, // _ + 0x35, // ` + 0x04, // a + 0x05, // b + 0x06, // c + 0x07, // d + 0x08, // e + 0x09, // f + 0x0a, // g + 0x0b, // h + 0x0c, // i + 0x0d, // j + 0x0e, // k + 0x0f, // l + 0x10, // m + 0x11, // n + 0x12, // o + 0x13, // p + 0x14, // q + 0x15, // r + 0x16, // s + 0x17, // t + 0x18, // u + 0x19, // v + 0x1a, // w + 0x1b, // x + 0x1c, // y + 0x1d, // z + 0x2f|SHIFT, // + 0x31|SHIFT, // | + 0x30|SHIFT, // } + 0x35|SHIFT, // ~ + 0 // DEL +}; + +void HIDKeyboard::begin(void){ + HID.addOutputBuffer(&ledData); +} + +void HIDKeyboard::end(void) { +} + +// 136: non-printing key +// shift -> 0x02 +// modifiers: 128 --> bit shift + +uint8_t HIDKeyboard::getKeyCode(uint16_t k, uint8_t* modifiersP) +{ + if (k & 0x8000u) { + // backwards compatibility in case a caller has passed a signed 8-bit value + k &= 0xFFu; + } + + *modifiersP = 0; + + if (adjustForHostCapsLock && (getLEDs() & 0x02)) { // capslock is down on host OS, so host will reverse + if ('a' <= k && k <= 'z') + k += 'A'-'a'; + else if ('A' <= k && k <= 'Z') + k += 'a'-'A'; + } + + if (k < 0x80) { + k = ascii_to_hid[k]; + if (k & SHIFT) { + k &= 0x7f; + *modifiersP = 0x02; + } + return k; + } + if (k >= KEY_HID_OFFSET) { // non-printing key, Arduino format + return k - KEY_HID_OFFSET; + } + else { // shift key + *modifiersP = 1<<(k-0x80); + + return k-0x80+0xE0; + } +} + +size_t HIDKeyboard::press(uint16_t k) { + uint8_t modifiers; + + k = getKeyCode(k, &modifiers); + + if (k == 0) { + if (modifiers == 0) { + return 0; + } + } + else { + for (unsigned i = 0; i. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + \ No newline at end of file diff --git a/STM32F1/libraries/USBComposite/MidiSpecs.h b/STM32F1/libraries/USBComposite/MidiSpecs.h new file mode 100644 index 000000000..6d2acbe8c --- /dev/null +++ b/STM32F1/libraries/USBComposite/MidiSpecs.h @@ -0,0 +1,151 @@ +/*--------------------------------------------------------------------------MidiSpecs.h + * + * These defines are based on specs created by the USB and MMA standards organizations. + * There are not a lot of other ways to code them so licensing this is rather ludicrous. + * However, in order to be able to embed this in client projects, and avoid the stupidity + * of enforced open everything I will declare the following about this file. + * + * Copyright (c) 2011 Donald Delmar Davis, Suspect Devices + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation files (the "Software"), to deal in the Software + * without restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/* + * USB midi commands from + * MIDI10.pdf "Universal Serial Bus Device Class Definition for MIDI Devices" + * REV 1. (1999) + * http://www.usb.org/developers/devclass_docs/midi10.pdf + * + */ + +#ifndef __LETS_MIDI_SPECS_H__ +#define __LETS_MIDI_SPECS_H__ +#include +#include +// rework this for the different architectures.... +#if defined(__GNUC__) +typedef struct +{ + unsigned cin : 4; // this is the low nibble. + unsigned cable : 4; +// uint8_t cin; + uint8_t midi0; + uint8_t midi1; + uint8_t midi2; +} __attribute__ ((__packed__)) MIDI_EVENT_PACKET_t ; +#else +typedef struct // may need to be adjusted for other compilers and bitfield order... +{ + unsigned cable : 4; + unsigned cin : 4; + uint8_t midi0; + uint8_t midi1; + uint8_t midi2; +} MIDI_EVENT_PACKET_t ; +#endif + + +#define CIN_MISC_FUNCTION 0x00 /* Reserved for future extension. */ +#define CIN_CABLE_EVENT 0x01 /* Reserved for future extension. */ +#define CIN_2BYTE_SYS_COMMON 0x02 /* 2Bytes -- MTC, SongSelect, etc. */ +#define CIN_3BYTE_SYS_COMMON 0x03 /* 3Bytes -- SPP, etc. */ +#define CIN_SYSEX 0x04 /* 3Bytes */ +#define CIN_SYSEX_ENDS_IN_1 0x05 /* 1Bytes */ +#define CIN_SYSEX_ENDS_IN_2 0x06 /* 2Bytes */ +#define CIN_SYSEX_ENDS_IN_3 0x07 /* 3Bytes */ +#define CIN_NOTE_OFF 0x08 /* 3Bytes */ +#define CIN_NOTE_ON 0x09 /* 3Bytes */ +#define CIN_AFTER_TOUCH 0x0A /* 3Bytes */ +#define CIN_CONTROL_CHANGE 0x0B /* 3Bytes */ +#define CIN_PROGRAM_CHANGE 0x0C /* 2Bytes */ +#define CIN_CHANNEL_PRESSURE 0x0D /* 2Bytes */ +#define CIN_PITCH_WHEEL 0x0E /* 3Bytes */ +#define CIN_1BYTE 0x0F /* 1Bytes */ +//#define CIN_IS_SYSEX(cin) ((cin == CIN_SYSEX)||(cin == CIN_SYSEX_ENDS_IN_1)||(cin == CIN_SYSEX_ENDS_IN_2)||(cin == CIN_SYSEX_ENDS_IN_3)) +#define CIN_IS_SYSEX(cin) ( ((cin) & ~(0x08)) && ((cin) &0x04) ) + +/* + * MIDI V1 message definitions these are from the MMA document + * http://www.midi.org/techspecs/midimessages.php + */ +#define MIDIv1_BAUD_RATE 31250 + +/* + * parse midi (v1) message macros + */ +#define MIDIv1_IS_STATUS(b) ((b) & 0x80) +#define MIDIv1_IS_VOICE(b) ((b) <= 0xEF) +#define MIDIv1_VOICE_COMMAND(b) ((b) & 0xF0) +#define MIDIv1_VOICE_CHANNEL(b) ((b) & 0x0F) +#define MIDIv1_IS_SYSCOMMON(b) (((b) >= 0xF0) & ((b) < 0xF8)) +#define MIDIv1_IS_REALTIME(b) ((b) >= 0xF8) + +/* + * Voice category messages + */ +#define MIDIv1_NOTE_OFF 0x80 /* 2 bytes data -- CIN_NOTE_OFF */ +#define MIDIv1_NOTE_ON 0x90 /* 2 bytes data -- CIN_NOTE_ON */ +#define MIDIv1_AFTER_TOUCH 0xA0 /* 2 bytes data -- CIN_AFTER_TOUCH */ +#define MIDIv1_CONTROL_CHANGE 0xB0 /* 2 bytes data -- CIN_CONTROL_CHANGE */ +#define MIDIv1_PROGRAM_CHANGE 0xC0 /* 1 byte data -- CIN_PROGRAM_CHANGE */ +#define MIDIv1_CHANNEL_PRESSURE 0xD0 /* 1 byte data -- CIN_CHANNEL_PRESSURE */ +#define MIDIv1_PITCH_WHEEL 0xE0 /* 2 bytes data -- CIN_PITCH_WHEEL */ + +/* + * System common category messages + */ +#define MIDIv1_SYSEX_START 0xF0 +#define MIDIv1_SYSEX_END 0xF7 +#define MIDIv1_MTC_QUARTER_FRAME 0xF1 /* 1 byte data -- CIN_2BYTE_SYS_COMMON */ +#define MIDIv1_SONG_POSITION_PTR 0xF2 /* 2 bytes data -- CIN_3BYTE_SYS_COMMON */ +#define MIDIv1_SONG_SELECT 0xF3 /* 1 byte data -- CIN_2BYTE_SYS_COMMON */ +#define MIDIv1_TUNE_REQUEST 0xF6 /* no data -- CIN_1BYTE */ + +/* + * Realtime category messages, can be sent anytime + */ +#define MIDIv1_CLOCK 0xF8 /* no data -- CIN_1BYTE */ +#define MIDIv1_TICK 0xF9 /* no data -- CIN_1BYTE */ +#define MIDIv1_START 0xFA /* no data -- CIN_1BYTE */ +#define MIDIv1_CONTINUE 0xFB /* no data -- CIN_1BYTE */ +#define MIDIv1_STOP 0xFC /* no data -- CIN_1BYTE */ +#define MIDIv1_ACTIVE_SENSE 0xFE /* no data -- CIN_1BYTE */ +#define MIDIv1_RESET 0xFF /* no data -- CIN_1BYTE */ + +/* + * sysex universal id's + */ +#define MIDIv1_UNIVERSAL_REALTIME_ID 0x7F +#define MIDIv1_UNIVERSAL_NON_REALTIME_ID 0x7E +#define MIDIv1_UNIVERSAL_ALL_CHANNELS 0x7F +/* + * Susbset of universal sysex (general info request) + * As described http://www.blitter.com/~russtopia/MIDI/~jglatt/tech/midispec.htm + */ +#define USYSEX_NON_REAL_TIME 0x7E +#define USYSEX_REAL_TIME 0x7F +#define USYSEX_ALL_CHANNELS 0x7F +#define USYSEX_GENERAL_INFO 0x06 +#define USYSEX_GI_ID_REQUEST 0x01 +#define USYSEX_GI_ID_RESPONSE 0x02 + + +#endif + + diff --git a/STM32F1/libraries/USBComposite/MinSysex.c b/STM32F1/libraries/USBComposite/MinSysex.c new file mode 100644 index 000000000..f496f2732 --- /dev/null +++ b/STM32F1/libraries/USBComposite/MinSysex.c @@ -0,0 +1,269 @@ +// +// MinSysex.c +// LibMaple4Midi +// +// Created by Donald D Davis on 4/11/13. +// Copyright (c) 2013 Suspect Devices. All rights reserved. +// Modified BSD Liscense +/* + 0xF0 SysEx + 0x7E Non-Realtime + 0x7F The SysEx channel. Could be from 0x00 to 0x7F. + Here we set it to "disregard channel". + 0x06 Sub-ID -- General Information + 0x01 Sub-ID2 -- Identity Request + 0xF7 End of SysEx +---- response + 0xF0 SysEx + 0x7E Non-Realtime + 0x7F The SysEx channel. Could be from 0x00 to 0x7F. + Here we set it to "disregard channel". + 0x06 Sub-ID -- General Information + 0x02 Sub-ID2 -- Identity Reply + 0xID Manufacturer's ID + 0xf1 The f1 and f2 bytes make up the family code. Each + 0xf2 manufacturer assigns different family codes to his products. + 0xp1 The p1 and p2 bytes make up the model number. Each + 0xp2 manufacturer assigns different model numbers to his products. + 0xv1 The v1, v2, v3 and v4 bytes make up the version number. + 0xv2 + 0xv3 + 0xv4 + 0xF7 End of SysEx +*/ + +#define USB_MIDI +#ifdef USB_MIDI + +// change this to packets +#define STANDARD_ID_RESPONSE_LENGTH 7 + +#include "usb_midi_device.h" +#include +#include +//#include + + +#define MAX_SYSEX_SIZE 256 + +/********************************* ACHTUNG! ignores usbmidi cable ********************************/ +/*const MIDI_EVENT_PACKET_t standardIDResponse[]={ + { DEFAULT_MIDI_CABLE, + CIN_SYSEX, + MIDIv1_SYSEX_START, + USYSEX_NON_REAL_TIME, + USYSEX_ALL_CHANNELS}, + { DEFAULT_MIDI_CABLE, + CIN_SYSEX, + USYSEX_GENERAL_INFO, + USYSEX_GI_ID_RESPONSE, + LEAFLABS_MMA_VENDOR_1}, + { DEFAULT_MIDI_CABLE, + CIN_SYSEX, + LEAFLABS_MMA_VENDOR_2, // extended ID + LEAFLABS_MMA_VENDOR_3, // extended ID + 1}, // family #1 + { DEFAULT_MIDI_CABLE, + CIN_SYSEX, + 2, // family #2 + 1, // part #1 + 2}, // part #2 + { DEFAULT_MIDI_CABLE, + CIN_SYSEX, + 0, // version 1 + 0, // version 2 + 1}, // version 3 + { DEFAULT_MIDI_CABLE, + CIN_SYSEX_ENDS_IN_2, + '!', // lgl compatible + MIDIv1_SYSEX_END, + 0} +}; +*/ +const uint8 standardIDResponse[]={ + CIN_SYSEX, + MIDIv1_SYSEX_START, + USYSEX_NON_REAL_TIME, + USYSEX_ALL_CHANNELS, + CIN_SYSEX, + USYSEX_GENERAL_INFO, + USYSEX_GI_ID_RESPONSE, + LEAFLABS_MMA_VENDOR_1, + CIN_SYSEX, + LEAFLABS_MMA_VENDOR_2, // extended ID + LEAFLABS_MMA_VENDOR_3, // extended ID + 1, // family #1 + CIN_SYSEX, + 2, // family #2 + 1, // part #1 + 2, // part #2 + CIN_SYSEX, + 0, // version 1 + 0, // version 2 + 1, // version 3 + CIN_SYSEX_ENDS_IN_2, + '!', // lgl compatible + MIDIv1_SYSEX_END, + 0 +}; +//#define STANDARD_ID_RESPONSE_LENGTH (sizeof(standardIDResponse)) + +typedef enum {NOT_IN_SYSEX=0,COULD_BE_MY_SYSEX,YUP_ITS_MY_SYSEX,ITS_NOT_MY_SYSEX} sysexStates; +volatile uint8 sysexBuffer[MAX_SYSEX_SIZE]; +volatile sysexStates sysexState; +volatile int sysexFinger=0; + +/* + 0xF0 SysEx + 0x?? LEAFLABS_MMA_VENDOR_1 + 0x?? LEAFLABS_MMA_VENDOR_2 + + 0x?? LEAFLABS_MMA_VENDOR_3 + 0x10 LGL_DEVICE_NUMBER + 0xLE CMD: REBOOT + + 0xf7 EOSysEx +*/ +#define STACK_TOP 0x20000800 +#define EXC_RETURN 0xFFFFFFF9 +#define DEFAULT_CPSR 0x61000000 +#define RESET_DELAY 100000 + +/* -----------------------------------------------------------------------------dealWithItQuickly() + * Note: at this point we have established that the sysex belongs to us. + * So we need to respond to any generic requests like information requests. + * We also need to handle requests which are meant for us. At the moment this is just the + * reset request. + * + */ +void dealWithItQuickly(){ + switch (sysexBuffer[1]) { + case USYSEX_NON_REAL_TIME: + switch (sysexBuffer[3]) { + case USYSEX_GENERAL_INFO: + if (sysexBuffer[4]==USYSEX_GI_ID_REQUEST) { + usb_midi_tx((uint32 *) standardIDResponse, STANDARD_ID_RESPONSE_LENGTH); + } + } + case USYSEX_REAL_TIME: + break; + default: + break; + } + ;//turn the led on? +} + +/* -----------------------------------------------------------------------------LglSysexHandler() + * The idea here is to identify which Sysex's belong to us and deal with them. + */ +void LglSysexHandler(uint32 *midiBufferRx, uint32 *rx_offset, uint32 *n_unread_packets) { + MIDI_EVENT_PACKET_t * midiPackets = (MIDI_EVENT_PACKET_t *) (midiBufferRx+(*rx_offset)); + uint8 nPackets=((*n_unread_packets)-(*rx_offset)); + int cPacket; + uint8 soPackets=0; + /********************************* ACHTUNG! ignores usbmidi cable ********************************/ + MIDI_EVENT_PACKET_t *packet; + for (cPacket=0;cPacketcin)) { + continue; + } // else { + if (!soPackets) { + soPackets=cPacket*4; + } + if ((sysexState==YUP_ITS_MY_SYSEX) && ((sysexFinger+3)>=MAX_SYSEX_SIZE)){ + sysexState=ITS_NOT_MY_SYSEX; //eisenhower policy. Even if its mine I cant deal with it. + } + switch (packet->cin) { + case CIN_SYSEX: + switch (sysexState) { + case NOT_IN_SYSEX : // new sysex. + sysexFinger=0; + if (packet->midi0 == MIDIv1_SYSEX_START) { + if (packet->midi1==USYSEX_REAL_TIME + ||packet->midi1==USYSEX_NON_REAL_TIME) { + if ((packet->midi2==myMidiChannel) + ||(packet->midi2==USYSEX_ALL_CHANNELS) + ) { + sysexState=YUP_ITS_MY_SYSEX; + sysexBuffer[sysexFinger++]=MIDIv1_SYSEX_START; + sysexBuffer[sysexFinger++]=packet->midi1; + sysexBuffer[sysexFinger++]=packet->midi2; + break; + } + } else if ((packet->midi1==myMidiID[0]) + && (packet->midi2==myMidiID[1]) + ){ + sysexState=COULD_BE_MY_SYSEX; + sysexBuffer[sysexFinger++]=MIDIv1_SYSEX_START; + sysexBuffer[sysexFinger++]=packet->midi1; + sysexBuffer[sysexFinger++]=packet->midi2; + break; + } + } + break; + + case COULD_BE_MY_SYSEX: + if (packet->midi0==myMidiID[2]) { + sysexState=YUP_ITS_MY_SYSEX; + sysexBuffer[sysexFinger++]=packet->midi0; + sysexBuffer[sysexFinger++]=packet->midi1; + sysexBuffer[sysexFinger++]=packet->midi2; + } else { + sysexState=ITS_NOT_MY_SYSEX; + sysexFinger=0; + } + break; + default: + break; + + } + + break; + case CIN_SYSEX_ENDS_IN_1: + case CIN_SYSEX_ENDS_IN_2: + case CIN_SYSEX_ENDS_IN_3: + sysexBuffer[sysexFinger++]=packet->midi0; + sysexBuffer[sysexFinger++]=packet->midi1; + sysexBuffer[sysexFinger++]=packet->midi2; + if (sysexState==YUP_ITS_MY_SYSEX) { + if(cPacket>=(int32)(*n_unread_packets)){ + *n_unread_packets = soPackets; + *rx_offset = soPackets; + } else { + uint8 c = cPacket; + uint32 *s; + uint32 *d = midiBufferRx + soPackets; + for (s = midiBufferRx+c; + ((*n_unread_packets) && (s <= midiBufferRx+(usb_midi_txEPSize/4))); + d++,s++ + ) { + (*d)=(*s); + (*n_unread_packets)--; + (*rx_offset)++; + + } + // we need to reset the for loop variables to re process remaining data. + nPackets=((*n_unread_packets)-(*rx_offset)); + cPacket=(*rx_offset); + } + dealWithItQuickly(); + + } + sysexFinger=0; + sysexState=NOT_IN_SYSEX; + + break; + default: + return; + } + //} + + + + } + // its our sysex and we will cry if we want to + return; +} + +#endif diff --git a/STM32F1/libraries/USBComposite/MinSysex.h b/STM32F1/libraries/USBComposite/MinSysex.h new file mode 100644 index 000000000..958eded43 --- /dev/null +++ b/STM32F1/libraries/USBComposite/MinSysex.h @@ -0,0 +1,37 @@ +// +// lgl_min_sysex.h +// LibMaple4Midi +// +// Created by Donald D Davis on 4/11/13. +// Copyright (c) 2013 Suspect Devices. All rights reserved. +// + +#ifndef __LGL_MIN_SYSEX_H__ +#define __LGL_MIN_SYSEX_H__ 1 + + +#include "MidiSpecs.h" +//#include "LGL.h" + +#define LEAFLABS_MMA_VENDOR_1 0x7D +#define LEAFLABS_MMA_VENDOR_2 0x1E +#define LEAFLABS_MMA_VENDOR_3 0x4F + +// move to LGL.h +#define LGL_RESET_CMD 0x1e + +#define DEFAULT_MIDI_CHANNEL 0x0A +#define DEFAULT_MIDI_DEVICE 0x0A +#define DEFAULT_MIDI_CABLE 0x00 + +// eventually all of this should be in a place for settings which can be written to flash. +extern volatile uint8 myMidiChannel; +extern volatile uint8 myMidiDevice; +extern volatile uint8 myMidiCable; +extern volatile uint8 myMidiID[]; + + +void LglSysexHandler(uint32 *midiBufferRx,uint32 *rx_offset,uint32 *n_unread_bytes); + +#endif + diff --git a/STM32F1/libraries/USBComposite/Mouse.cpp b/STM32F1/libraries/USBComposite/Mouse.cpp new file mode 100644 index 000000000..afcbc5744 --- /dev/null +++ b/STM32F1/libraries/USBComposite/Mouse.cpp @@ -0,0 +1,56 @@ +#include "USBComposite.h" + +//================================================================================ +//================================================================================ +// Mouse + +void HIDMouse::begin(void){ +} + +void HIDMouse::end(void){ +} + +void HIDMouse::click(uint8_t b) +{ + _buttons = b; + move(0,0,0); + _buttons = 0; + move(0,0,0); +} + +void HIDMouse::move(signed char x, signed char y, signed char wheel) +{ + reportBuffer[1] = _buttons; + reportBuffer[2] = x; + reportBuffer[3] = y; + reportBuffer[4] = wheel; + + sendReport(); +} + +void HIDMouse::buttons(uint8_t b) +{ + if (b != _buttons) + { + _buttons = b; + move(0,0,0); + } +} + +void HIDMouse::press(uint8_t b) +{ + buttons(_buttons | b); +} + +void HIDMouse::release(uint8_t b) +{ + buttons(_buttons & ~b); +} + +bool HIDMouse::isPressed(uint8_t b) +{ + if ((b & _buttons) > 0) + return true; + return false; +} + diff --git a/STM32F1/libraries/USBComposite/README.md b/STM32F1/libraries/USBComposite/README.md new file mode 100644 index 000000000..ab512354e --- /dev/null +++ b/STM32F1/libraries/USBComposite/README.md @@ -0,0 +1,205 @@ +# USB Composite library for Roger's Melbourne's STM32F1 core: https://github.com/rogerclarkmelbourne/Arduino_STM32/ + +## Protocols supported + +- standard USB HID, with many built-in profiles, and customizable with more + +- MIDI over USB + +- XBox360 wired/wireless controllers + +- Mass storage + +- USB Audio (unidirectional, but both directions are supported) + +## Basic concepts + +Start with: +``` +#include +``` + +The library defines one central singleton object: + +``` +extern USBCompositeDevice USBComposite; +``` + +This controls USB device identification as well as registers the plugins that are connected to it. + +Plugin classes included in the library: + +``` +USBHID +USBMIDI +USBMultiXBox360 / USBXBox360 / USBXBox360W +USBMassStorage +USBCompositeSerial +USBMultiSerial +``` + +**NOTE:** Only one of USBMultiXBox360 / USBXBox360 / USBXBox360W can be registered at a time: +they cannot be composited together. + +To use the plugins, you need to create instances of them. NOTE: Only one instance of each plugin class +can be created. + +If you want to make a simple (non-composite) USB device, you can create an instance of the plugin class +and call the `begin()` method, and it will take care of registering itself with `USBComposite` and starting up +`USBComposite`. If you want to make a composite USB device, however, +you need to control the device with `USBComposite`: + +``` +USBComposite.clear(); // clear any plugins previously registered +plugin1.registerComponent(); +plugin2.registerComponent(); +USBComposite.begin(); +``` + +Of course, you may need to do some further configuring of the plugins (e.g., if plugin1 is USBHID, then +you may want to do `USBHID.setReportDescriptor(HID_KEYBOARD)`) or of the `USBComposite` device +before the `USBComposite.begin()` call. + +After starting up USBComposite, it's a good idea to wait for it to become ready before sending any data: +``` +while(!USBComposite); +``` + +Finally, there are a number of classes that implement particular protocols for the `USBHID` class plugin. +These include: +``` +HIDMouse +HIDKeyboard +HIDJoystick +HIDAbsMouse +HIDConsumer +HIDRaw +HIDSwitchController +``` +And you can customize with more. Moreover, the `USBHID` plugin itself allows for compositing +multiple HID profiles, e.g., Mouse / Keyboard / three joysticks. Each of these has at least +one required parameter, which is an instance of `USBHID`. + +Not all combinations will fit within the constraints of the STM32F1 USB system, and not all +combinations will be supported by all operating systems. + +I recommend calling `USBComposite.setDeviceId(device)` with a different device number for each combination +of plugins and profiles to prevent problems with cached configurations on the host computer. + +## Uploading with STM32duino bootloader + +Normally, the STM32duino bootloader upload method in the Roger Melbourne STM32F1 core sends a command +to reset the board via the USB serial port, and thereby put it in bootloader mode, just prior to uploading. +If you have installed a sketch that includes a USB serial port in the composite device, this should still +work. But if the sketch you've installed doesn't include a USB serial port, then you need to manually activate +the bootloader mode next time you want to upload a sketch. + +The bootloader mode is active for a short period after the board powers up or resets. So just initiate +the upload in the Arduino IDE as usual, but when "Searching for DFU device [1EAF:0003]" is displayed, +hit the reset button (or if the device is USB-powered, keep it unplugged from USB and plug it in when you +get this message). + +## Simple USB device configuration + +A simple USB device uses a single plugin. You need to create an instance of the plugin class, +call any setup methods for the plugin and the `begin()` method for the plugin. For instance, +to inject keyboard data, you should do: + +``` +USBHID HID; // create instance of USBHID plugin +HIDKeyboard Keyboard(HID); // create a profile + +HID.begin(); +``` + +and then call `Keyboard.print("TextToInject")` to inject keyboard data. Some plugin configurations +may require further initialization code or further code that needs to be called inside the Arduino +`loop()` function. + +See the `BootKeyboard`, `midiout` and `x360` example code for variants on this procedure. + +(Additionally, the `USBHID` plugin has a convenience `begin()` method that lets you include an +instance of a `USBCompositeSerial` plugin class, and that creates a composite HID-Serial device.) + +However, if you want a USB device using more than one plugin, then you will NOT call the plugin's +`begin()` method. + +Note that a single HID plugin can support a device with multiple report profiles including a keyboard, several joysticks, +a mouse, etc.: +``` +USBHID HID; // create instance of USBHID plugin +HIDKeyboard Keyboard(HID); // create a profile +HIDJoystick Joystick1(HID); // create a profile +HIDJoystick Joystick2(HID); // create a profile +HIDMouse Mouse(HID); // create a profile + +HID.begin(); +``` + +Each of the profiles (e.g., Joystick1) contributes a part of the HID report descriptor to USBHID which automatically stitches +them together and assigns report IDs. However, you can also make a single overarching custom HID report descriptor and include +it in the HID.begin() call. The `softjoystick` example does this. + +## Memory limitations + +There are 320 bytes of hardware buffer memory available after endpoint 0 is taken into account. The following +are the default buffer memory needs of the current components: + + * USB Serial: 144 bytes + + * USB HID: 64 bytes + + * USB Mass Storage: 128 bytes + + * USB MIDI: 128 bytes + + * XBox360 Controller: 64 bytes + +This places a limit on what combinations can be used together. For instance, HID+Mass storage+MIDI should be theoretically +OK (320 bytes), but Serial+HID+Mass storage (336 bytes) will fail with default settings (and return false from +USBComposite.begin()) due to lack of memory. + +However, USB Serial, USB HID and USB MIDI allow you to decrease buffer sizes (and allow for more complex composite devices) +by calling: +``` +USBHID HID; +USBCompositeSerial CompositeSerial; +USBMIDI MIDI; + +CompositeSerial.setRXPacketSize(size); +CompositeSerial.setTXPacketSize(size); +HID.setTXPacketSize(size); +MIDI.setRXPacketSize(size); +MIDI.setTXPacketSize(size); +``` +The maximum and default packet size is 64. Smaller packet sizes have not been thoroughly tested and may slow things down. In +particular, for HID you should make sure your packet size is sufficient for your largest HID report. The CompositeSerial +device also has a control channel whose 16 byte packet size is not adjustable. Note that for reasons that I do not currently +understand, CompositeSerial RX packets must be a power of two in size. + +Note also that in the above, RX and TX are from the point of view of the MCU, not the host (i.e., RX corresponds to USB Out and TX +to USB In). + +## Endpoint limitations + +There is one bidirectional endpoint 0 that all endpoints share, and the hardware allows for seven more in each direction, +but there are some complications in that the same endpoint number when used in different directions must have some +of the same parameters. The USBComposite library takes care of these complications when allocating endpoints, but if you +have too many plugins, you USBComposite.begin() will return `false` to indicate that you've used up too many. + +This is pretty complicated, but a rule of thumb for having enough endpoints is to make sure that when you add up the +following contributions for the plugins you use, your total is at most seven. + +* USB Serial: 2 (= 2 TX, 1 RX) + +* USB HID: 1 (= 1 TX) + +* USB Mass Storage: 1 (= 1 TX, 1 RX) + +* USB MIDI: 1 (= 1 TX, 1 RX) + +* XBox360 Controller: 1 per controller (= 1 TX, 1 RX) + +* USB Audio: 1 (= 1 TX or 1 RX depending on mode) + +* USB Multi Serial: 2 per port (= 2 TX, 1 RX) diff --git a/STM32F1/libraries/USBComposite/UPGRADING-TO-0.90.txt b/STM32F1/libraries/USBComposite/UPGRADING-TO-0.90.txt new file mode 100644 index 000000000..612350ea9 --- /dev/null +++ b/STM32F1/libraries/USBComposite/UPGRADING-TO-0.90.txt @@ -0,0 +1,19 @@ +Version 0.90 of the library has changed the API significantly in order to save flash and RAM. +The main change is that other than USBComposite, all pre-declared object instances have been +removed. + +When upgrading to 0.90 or higher, you will have to make a number of changes to your code. + +1. Use a single include file instead of USBHID.h, USBMIDI.h, etc.: + #include + +2. Declare all instances other than USBComposite. This includes instances of plugin classes + like USBHID as well as of HID profiles like HIDKeyboard (which need an instance of USBHID). + +3. Note that USBHID is now a class (for consistency with other class names) and there is no + USBHID instance. You need to declare an instance, e.g.: + USBHID HID; + and replace calls to USBHID.* with calls to HID.*. + +4. Replace USBHID_begin_with_serial(...) with HID.begin(CompositeSerial,...) where HID is your + instance of USBHID. \ No newline at end of file diff --git a/STM32F1/libraries/USBComposite/USBAudio.cpp b/STM32F1/libraries/USBComposite/USBAudio.cpp new file mode 100644 index 000000000..8cbecfc5f --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBAudio.cpp @@ -0,0 +1,106 @@ +/* Copyright (c) 2019, Scott Moreau +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "USBComposite.h" + +#include + +static bool enabledAUDIO = false; + +/* + * USB AUDIO interface + */ + +bool USBAUDIO::init(USBAUDIO* me) { + uint32 txPacketSize = usb_audio_init(me->type, me->sampleRate); + usb_audio_setEPSize(txPacketSize); + + return true; +} + +bool USBAUDIO::registerComponent() { + + return USBComposite.add(&usbAUDIOPart, this, (USBPartInitializer)&USBAUDIO::init); +} + +uint32 USBAUDIO::write(const uint8* buffer, uint32 length) +{ + return usb_audio_write_tx_data(buffer, length); +} + +uint32 USBAUDIO::read(uint8* buffer, uint32 length) +{ + return usb_audio_read_rx_data(buffer, length); +} + +uint16 USBAUDIO::getSamplePeriod(void) +{ + return samplePeriod; +} + +static void setSamplePeriod(uint16 *samplePeriod, uint16 sampleRate) +{ + *samplePeriod = 1000000 / sampleRate - 1; +} + +void USBAUDIO::setPacketCallback(void (*callback)(uint8 size)) { + audio_set_packet_callback(callback); +} + +void USBAUDIO::setParameters(uint16 _type, uint16 _sampleRate) { + type = _type; + sampleRate = _sampleRate; + setSamplePeriod(&samplePeriod, sampleRate); +} + +void USBAUDIO::begin(uint16 _type, uint16 _sampleRate) { + if (enabledAUDIO) + return; + + setParameters(_type, _sampleRate); + + USBComposite.clear(); + + registerComponent(); + + USBComposite.begin(); + + enabledAUDIO = true; +} + +void USBAUDIO::begin(USBCompositeSerial serial, uint16 _type, uint16 _sampleRate) { + if (enabledAUDIO) + return; + + setParameters(_type, _sampleRate); + + USBComposite.clear(); + + registerComponent(); + + serial.registerComponent(); + + USBComposite.begin(); + + enabledAUDIO = true; +} + +void USBAUDIO::end(void){ + if(enabledAUDIO) { + USBComposite.end(); + enabledAUDIO = false; + } +} diff --git a/STM32F1/libraries/USBComposite/USBAudio.h b/STM32F1/libraries/USBComposite/USBAudio.h new file mode 100644 index 000000000..2843d3aa6 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBAudio.h @@ -0,0 +1,35 @@ +/* Copyright (c) 2019, Scott Moreau +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "usb_audio.h" + +class USBAUDIO { +private: + uint16 samplePeriod; + uint16 sampleRate = 24000; + uint16 type = MIC_STEREO; +public: + static bool init(USBAUDIO* me); + bool registerComponent(); + void begin(uint16 type = MIC_STEREO, uint16 sampleRate = 24000); + void begin(USBCompositeSerial serial, uint16 type = MIC_STEREO, uint16 sampleRate = 24000); + void setParameters(uint16 type = MIC_STEREO, uint16 sampleRate = 24000); + void end(void); + void setPacketCallback(void (*callback)(uint8 size)); + uint32 write(const uint8* buffer, uint32 length); + uint32 read(uint8* buffer, uint32 length); + uint16 getSamplePeriod(void); +}; diff --git a/STM32F1/libraries/USBComposite/USBComposite.cpp b/STM32F1/libraries/USBComposite/USBComposite.cpp new file mode 100644 index 000000000..8d772f450 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBComposite.cpp @@ -0,0 +1,119 @@ +#include "USBComposite.h" +#undef true +#undef false +#include + +#define DEFAULT_VENDOR_ID 0x1EAF +#define DEFAULT_PRODUCT_ID 0x0024 + +static char* putSerialNumber(char* out, int nibbles, uint32 id) { + for (int i=0; i>= 4) { + uint8 nibble = id & 0xF; + if (nibble <= 9) + *out++ = nibble + '0'; + else + *out++ = nibble - 10 + 'a'; + } + return out; +} + +char* getDeviceIDString() { + static char string[80/4+1]; + char* p = string; + + uint32 id = (uint32) *(uint16*) (0x1FFFF7E8+0x02); + p = putSerialNumber(p, 4, id); + + id = *(uint32*) (0x1FFFF7E8+0x04); + p = putSerialNumber(p, 8, id); + + id = *(uint32*) (0x1FFFF7E8+0x08); + p = putSerialNumber(p, 8, id); + + *p = 0; + + return string; +} + +USBCompositeDevice::USBCompositeDevice(void) { + vendorId = 0; + productId = 0; + numParts = 0; + setManufacturerString(NULL); + setProductString(NULL); + setSerialString(NULL); +} + +void USBCompositeDevice::setVendorId(uint16 _vendorId) { + if (_vendorId != 0) + vendorId = _vendorId; + else + vendorId = DEFAULT_VENDOR_ID; +} + +void USBCompositeDevice::setProductId(uint16 _productId) { + if (_productId != 0) + productId = _productId; + else + productId = DEFAULT_PRODUCT_ID; +} + +void USBCompositeDevice::setManufacturerString(const char* s) { + iManufacturer = s; +} + +void USBCompositeDevice::setProductString(const char* s) { + iProduct = s; +} + +void USBCompositeDevice::setSerialString(const char* s) { + iSerialNumber = s; +} + +bool USBCompositeDevice::begin() { + if (enabled) + return true; + for (uint32 i = 0 ; i < numParts ; i++) { + if (init[i] != NULL && !init[i](plugin[i])) + return false; + } + usb_generic_set_info(vendorId, productId, iManufacturer, iProduct, iSerialNumber); + if (! usb_generic_set_parts(parts, numParts)) + return false; + usb_generic_enable(); + enabled = true; + return true; +} + +void USBCompositeDevice::end() { + if (!enabled) + return; + usb_generic_disable(); + for (uint32 i = 0 ; i < numParts ; i++) + if (stop[i] != NULL) + stop[i](plugin[i]); + enabled = false; +} + +void USBCompositeDevice::clear() { + numParts = 0; +} + +bool USBCompositeDevice::add(USBCompositePart* part, void* _plugin, USBPartInitializer _init, USBPartStopper _stop) { + unsigned i; + + for (i = 0; i= USB_COMPOSITE_MAX_PARTS) + return false; + parts[i] = part; + init[i] = _init; + stop[i] = _stop; + plugin[i] = _plugin; + if (i >= numParts) + numParts++; + return true; +} + +USBCompositeDevice USBComposite; diff --git a/STM32F1/libraries/USBComposite/USBComposite.h b/STM32F1/libraries/USBComposite/USBComposite.h new file mode 100644 index 000000000..72eac2f6e --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBComposite.h @@ -0,0 +1,67 @@ +#ifndef _USBCOMPOSITE_H_ +#define _USBCOMPOSITE_H_ + +#include +#include "Stream.h" +#include "usb_generic.h" +//#include + +#define USB_COMPOSITE_MAX_PARTS 6 + +// You could use this for a serial number, but you'll be revealing the device ID to the host, +// and hence burning it for cryptographic purposes. +char* getDeviceIDString(); + +class USBCompositeDevice; + +#define DEFAULT_SERIAL_STRING "00000000000000000001" + +typedef bool(*USBPartInitializer)(void*); +typedef void(*USBPartStopper)(void*); + +class USBCompositeDevice { +private: + const char* iManufacturer = NULL; + const char* iProduct = NULL; + const char* iSerialNumber = NULL; + uint16 vendorId; + uint16 productId; + USBCompositePart* parts[USB_COMPOSITE_MAX_PARTS]; + USBPartInitializer init[USB_COMPOSITE_MAX_PARTS]; + USBPartStopper stop[USB_COMPOSITE_MAX_PARTS]; + void* plugin[USB_COMPOSITE_MAX_PARTS]; + uint32 numParts; + bool enabled = false; +public: + USBCompositeDevice(void); + void setVendorId(uint16 vendor=0); + void setProductId(uint16 product=0); + void setManufacturerString(const char* manufacturer=NULL); + void setProductString(const char* product=NULL); + void setSerialString(const char* serialNumber=DEFAULT_SERIAL_STRING); + bool begin(void); + void end(void); + void clear(); + void setDisconnectDelay(uint32 delay=500) { // in microseconds + usb_generic_set_disconnect_delay(delay); + } + bool isReady() { + return enabled && usb_is_connected(USBLIB) && usb_is_configured(USBLIB); + } + operator bool() { + return isReady(); + } + bool add(USBCompositePart* part, void* plugin, USBPartInitializer init = NULL, USBPartStopper stop = NULL); +}; + +extern USBCompositeDevice USBComposite; + +#include +#include +#include +#include +#include +#include +#include +#endif + \ No newline at end of file diff --git a/STM32F1/libraries/USBComposite/USBCompositeSerial.cpp b/STM32F1/libraries/USBComposite/USBCompositeSerial.cpp new file mode 100644 index 000000000..a2cf443d3 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBCompositeSerial.cpp @@ -0,0 +1,279 @@ +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "USBComposite.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "usb_composite_serial.h" + +#define USB_TIMEOUT 50 + +#if defined(SERIAL_USB) +static void rxHook(unsigned, void*); +static void ifaceSetupHook(unsigned, void*); +#endif + +bool USBCompositeSerial::init(USBCompositeSerial* me) { +#if defined(SERIAL_USB) + composite_cdcacm_set_hooks(USBHID_CDCACM_HOOK_RX, rxHook); + composite_cdcacm_set_hooks(USBHID_CDCACM_HOOK_IFACE_SETUP, ifaceSetupHook); +#endif + composite_cdcacm_setTXEPSize(me->txPacketSize); + composite_cdcacm_setRXEPSize(me->rxPacketSize); + return true; +} + +void USBCompositeSerial::begin(long speed) { + (void)speed; + if (!enabled) { + USBComposite.clear(); + registerComponent(); + USBComposite.begin(); + enabled = true; + } +} + +void USBCompositeSerial::end() { + if (enabled) { + USBComposite.end(); + enabled = false; + } +} + +size_t USBCompositeSerial::write(uint8 ch) { +size_t n = 0; + this->write(&ch, 1); + return n; +} + +size_t USBCompositeSerial::write(const char *str) { +size_t n = 0; + this->write((const uint8*)str, strlen(str)); + return n; +} + +size_t USBCompositeSerial::write(const uint8 *buf, uint32 len) +{ + size_t n = 0; + + if (!this->isConnected() || !buf) { + return 0; + } + + uint32 txed = 0; + while (txed < len) { + txed += composite_cdcacm_tx((const uint8*)buf + txed, len - txed); + } + + return n; +} + +int USBCompositeSerial::available(void) { + return composite_cdcacm_data_available(); +} + +int USBCompositeSerial::peek(void) +{ + uint8 b; + if (composite_cdcacm_peek(&b, 1)==1) + { + return b; + } + else + { + return -1; + } +} + +bool USBCompositeSerial::registerComponent() { + return USBComposite.add(&usbSerialPart, this, (USBPartInitializer)&USBCompositeSerial::init); +} + +void USBCompositeSerial::flush(void) +{ +/*Roger Clark. Rather slow method. Need to improve this */ + uint8 b; + while(composite_cdcacm_data_available()) + { + this->read(&b, 1); + } + return; +} + +uint32 USBCompositeSerial::read(uint8 * buf, uint32 len) { + uint32 rxed = 0; + while (rxed < len) { + rxed += composite_cdcacm_rx(buf + rxed, len - rxed); + } + + return rxed; +} + +/* Blocks forever until 1 byte is received */ +int USBCompositeSerial::read(void) { + uint8 b; + /* + this->read(&b, 1); + return b; + */ + + if (composite_cdcacm_rx(&b, 1)==0) + { + return -1; + } + else + { + return b; + } +} + +uint8 USBCompositeSerial::pending(void) { + return composite_cdcacm_get_pending(); +} + +uint8 USBCompositeSerial::isConnected(void) { + return usb_is_connected(USBLIB) && usb_is_configured(USBLIB) && composite_cdcacm_get_dtr(); +} + +uint8 USBCompositeSerial::getDTR(void) { + return composite_cdcacm_get_dtr(); +} + +uint8 USBCompositeSerial::getRTS(void) { + return composite_cdcacm_get_rts(); +} + +#if defined(SERIAL_USB) + +enum reset_state_t { + DTR_UNSET, + DTR_HIGH, + DTR_NEGEDGE, + DTR_LOW +}; + +static reset_state_t reset_state = DTR_UNSET; + +static void ifaceSetupHook(unsigned hook, void *requestvp) { + (void)hook; + uint8 request = *(uint8*)requestvp; + + // Ignore requests we're not interested in. + if (request != USBHID_CDCACM_SET_CONTROL_LINE_STATE) { + return; + } + + // We need to see a negative edge on DTR before we start looking + // for the in-band magic reset byte sequence. + uint8 dtr = composite_cdcacm_get_dtr(); + switch (reset_state) { + case DTR_UNSET: + reset_state = dtr ? DTR_HIGH : DTR_LOW; + break; + case DTR_HIGH: + reset_state = dtr ? DTR_HIGH : DTR_NEGEDGE; + break; + case DTR_NEGEDGE: + reset_state = dtr ? DTR_HIGH : DTR_LOW; + break; + case DTR_LOW: + reset_state = dtr ? DTR_HIGH : DTR_LOW; + break; + } + + if ((composite_cdcacm_get_baud() == 1200) && (reset_state == DTR_NEGEDGE)) { + iwdg_init(IWDG_PRE_4, 10); + while (1); + } +} + +#define RESET_DELAY 100000 +static void wait_reset(void) { + delay_us(RESET_DELAY); + nvic_sys_reset(); +} + +#define STACK_TOP 0x20000800 +#define EXC_RETURN 0xFFFFFFF9 +#define DEFAULT_CPSR 0x61000000 +static void rxHook(unsigned hook, void *ignored) { + (void)hook; + (void)ignored; + /* FIXME this is mad buggy; we need a new reset sequence. E.g. NAK + * after each RX means you can't reset if any bytes are waiting. */ + if (reset_state == DTR_NEGEDGE) { + reset_state = DTR_LOW; + + if (composite_cdcacm_data_available() >= 4) { + // The magic reset sequence is "1EAF". + static const uint8 magic[4] = {'1', 'E', 'A', 'F'}; + + uint8 chkBuf[4]; + + // Peek at the waiting bytes, looking for reset sequence, + // bailing on mismatch. + composite_cdcacm_peek_ex(chkBuf, composite_cdcacm_data_available() - 4, 4); + for (unsigned i = 0; i < sizeof(magic); i++) { + if (chkBuf[i] != magic[i]) { + return; + } + } + + // Got the magic sequence -> reset, presumably into the bootloader. + // Write 0x424C to backup register 0x0A to tell the bootloader to wait + bkp_init(); + bkp_enable_writes(); + bkp_write(0x0a,0x424c); + bkp_disable_writes(); + + // Return address is wait_reset, but we must set the thumb bit. + uintptr_t target = (uintptr_t)wait_reset | 0x1; + asm volatile("mov r0, %[stack_top] \n\t" // Reset stack + "mov sp, r0 \n\t" + "mov r0, #1 \n\t" + "mov r1, %[target_addr] \n\t" + "mov r2, %[cpsr] \n\t" + "push {r2} \n\t" // Fake xPSR + "push {r1} \n\t" // PC target addr + "push {r0} \n\t" // Fake LR + "push {r0} \n\t" // Fake R12 + "push {r0} \n\t" // Fake R3 + "push {r0} \n\t" // Fake R2 + "push {r0} \n\t" // Fake R1 + "push {r0} \n\t" // Fake R0 + "mov lr, %[exc_return] \n\t" + "bx lr" + : + : [stack_top] "r" (STACK_TOP), + [target_addr] "r" (target), + [exc_return] "r" (EXC_RETURN), + [cpsr] "r" (DEFAULT_CPSR) + : "r0", "r1", "r2"); + + /* Can't happen. */ + ASSERT_FAULT(0); + } + } +} +#endif + diff --git a/STM32F1/libraries/USBComposite/USBCompositeSerial.h b/STM32F1/libraries/USBComposite/USBCompositeSerial.h new file mode 100644 index 000000000..2b5a02512 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBCompositeSerial.h @@ -0,0 +1,49 @@ +#ifndef _COMPOSITE_SERIAL_H_ +#define _COMPOSITE_SERIAL_H_ + +#include "usb_composite_serial.h" + +class USBCompositeSerial : public Stream { +private: + bool enabled = false; + uint32 txPacketSize = 64; + uint32 rxPacketSize = 64; +public: + void begin(long speed=9600); + void end(); + static bool init(USBCompositeSerial* me); + bool registerComponent(); + + operator bool() { return USBComposite.isReady(); } // Roger Clark. This is needed because in cardinfo.ino it does if (!Serial) . It seems to be a work around for the Leonardo that we needed to implement just to be compliant with the API + + virtual int available(void);// Changed to virtual + + uint32 read(uint8 * buf, uint32 len); + // uint8 read(void); + + // Roger Clark. added functions to support Arduino 1.0 API + virtual int peek(void); + virtual int read(void); + int availableForWrite(void); + virtual void flush(void); + + size_t write(uint8); + size_t write(const char *str); + size_t write(const uint8*, uint32); + + uint8 getRTS(); + uint8 getDTR(); + uint8 isConnected(); + uint8 pending(); + + void setRXPacketSize(uint32 size=64) { + rxPacketSize = size; + } + + void setTXPacketSize(uint32 size=64) { + txPacketSize = size; + } +}; + +extern USBCompositeSerial CompositeSerial; +#endif diff --git a/STM32F1/libraries/USBComposite/USBHID.cpp b/STM32F1/libraries/USBComposite/USBHID.cpp new file mode 100644 index 000000000..d350c0256 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBHID.cpp @@ -0,0 +1,322 @@ +/* Copyright (c) 2011, Peter Barrett + * Copyright (c) 2017-2018, Alexander Pruss +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "USBComposite.h" + +#include +#include +#include +#include "usb_hid.h" +#include "usb_composite_serial.h" +#include "usb_generic.h" +#include +#include +#include + +/* + * USB HID interface + */ + +bool USBHID::init(USBHID* me) { + usb_hid_setTXEPSize(me->txPacketSize); + + HIDReporter* r = me->profiles; + + if (me->baseChunk.data != NULL) { + /* user set an explicit report for USBHID */ + while (r != NULL) { + r->reportID = r->userSuppliedReportID; + if (r->reportID != 0) + r->reportBuffer[0] = r->reportID; + r = r->next; + } + usb_hid_set_report_descriptor(&(me->baseChunk)); + } + else { + uint8 reportID = HID_AUTO_REPORT_ID_START; + + while (r != NULL) { + if (r->forceUserSuppliedReportID) + r->reportID = r->userSuppliedReportID; + else + r->reportID = reportID++; + + if (r->reportID != 0) + r->reportBuffer[0] = r->reportID; + + r = r->next; + } + usb_hid_set_report_descriptor(me->chunkList); + } + + return true; +} + +bool USBHID::registerComponent() { + return USBComposite.add(&usbHIDPart, this, (USBPartInitializer)&USBHID::init); +} + +void USBHID::setReportDescriptor(const uint8_t* report_descriptor, uint16_t report_descriptor_length) { + baseChunk.dataLength = report_descriptor_length; + baseChunk.data = report_descriptor; + baseChunk.next = NULL; +} + +void USBHID::clear() { + clearBuffers(); + baseChunk.data = NULL; + baseChunk.dataLength = 0; + baseChunk.next = NULL; + chunkList = NULL; + profiles = NULL; +} + +void USBHID::addReport(HIDReporter* r, bool always) { + if (! always && ! autoRegister) + return; + + r->next = NULL; + if (profiles == NULL) { + profiles = r; + } + else { + HIDReporter* tail = profiles; + while (tail != r && tail->next != NULL) { + tail = tail->next; + } + if (tail == r) + return; + tail->next = r; + } + + struct usb_chunk* chunkTail = chunkList; + + if (chunkTail == NULL) { + chunkList = &(r->reportChunks[0]); + chunkTail = chunkList; + } + else { + while (chunkTail->next != NULL) + chunkTail = chunkTail->next; + chunkTail->next = &(r->reportChunks[0]); + chunkTail = chunkTail->next; + } + chunkTail->next = &(r->reportChunks[1]); + chunkTail = chunkTail->next; + chunkTail->next = &(r->reportChunks[2]); + chunkTail = chunkTail->next; + chunkTail->next = NULL; +} + +void USBHID::setReportDescriptor(const HIDReportDescriptor* report) { + if (report == NULL) + setReportDescriptor(NULL, 0); + else + setReportDescriptor(report->descriptor, report->length); +} + +void USBHID::begin(const uint8_t* report_descriptor, uint16_t report_descriptor_length) { + if (enabledHID) + return; + + setReportDescriptor(report_descriptor, report_descriptor_length); + + USBComposite.clear(); + registerComponent(); + + USBComposite.begin(); + + enabledHID = true; +} + +void USBHID::begin(const HIDReportDescriptor* report) { + if (report == NULL) + begin(NULL, 0); + else + begin(report->descriptor, report->length); +} + +void USBHID::setBuffers(uint8_t type, volatile HIDBuffer_t* fb, int count) { + usb_hid_set_buffers(type, fb, count); +} + +bool USBHID::addBuffer(uint8_t type, volatile HIDBuffer_t* buffer) { + return 0 != usb_hid_add_buffer(type, buffer); +} + +void USBHID::clearBuffers(uint8_t type) { + usb_hid_clear_buffers(type); +} + +void USBHID::clearBuffers() { + clearBuffers(HID_REPORT_TYPE_OUTPUT); + clearBuffers(HID_REPORT_TYPE_FEATURE); +} + +void USBHID::end(void){ + if(enabledHID) { + USBComposite.end(); + enabledHID = false; + } +} + +void USBHID::begin(USBCompositeSerial serial, const uint8_t* report_descriptor, uint16_t report_descriptor_length) { + if (enabledHID) + return; + + USBComposite.clear(); + + setReportDescriptor(report_descriptor, report_descriptor_length); + registerComponent(); + + serial.registerComponent(); + + USBComposite.begin(); +} + +void USBHID::begin(USBCompositeSerial serial, const HIDReportDescriptor* report) { + if (report == NULL) + begin(serial, NULL, 0); + else + begin(serial, report->descriptor, report->length); +} + +void HIDReporter::sendReport() { + unsigned toSend = bufferSize; + uint8* b = reportBuffer; + + while (toSend) { + unsigned delta = usb_hid_tx(b, toSend); + toSend -= delta; + b += delta; + } + + /* flush out to avoid having the pc wait for more data */ + /* TODO: remove? this does nothing right now! */ + usb_hid_tx(NULL, 0); +} + +void HIDReporter::registerProfile(bool always) { + for (uint32 i=0; i<3; i++) { + reportChunks[i].data = NULL; + reportChunks[i].dataLength = 0; + } + if (reportDescriptor.descriptor != NULL) { + int32_t reportIDOffset = -1; + if (! forceUserSuppliedReportID) { + uint32_t i = 0; + + /* + * parse bits of beginning of report looking for a single-byte report ID (0x85 ID) + */ + while (i < reportDescriptor.length && reportIDOffset < 0) { + if (reportDescriptor.descriptor[i]==0x85) { + if (i+1 < reportDescriptor.length) + reportIDOffset = i+1; + } + // the lowest 2 bit determine the data length of the tag + if ((reportDescriptor.descriptor[i] & 3) == 3) + i += 5; + else + i += 1 + (reportDescriptor.descriptor[i] & 3); + } + if (i >= reportDescriptor.length) { + forceUserSuppliedReportID = true; + } + } + if (forceUserSuppliedReportID) { + reportChunks[0].data = reportDescriptor.descriptor; + reportChunks[0].dataLength = reportDescriptor.length; + } + else { + reportChunks[0].data = reportDescriptor.descriptor; + reportChunks[0].dataLength = reportIDOffset; + reportID = reportDescriptor.descriptor[reportIDOffset]; + reportChunks[1].data = &(reportID); + reportChunks[1].dataLength = 1; + reportChunks[2].data = reportDescriptor.descriptor+reportIDOffset+1; + reportChunks[2].dataLength = reportDescriptor.length - (reportIDOffset+1); + } + } + HID.addReport(this, always); +} + +HIDReporter::HIDReporter(USBHID& _HID, const HIDReportDescriptor* r, uint8_t* _buffer, unsigned _size, uint8_t _reportID, bool forceReportID) : HID(_HID) { + if (r != NULL) { + memcpy(&reportDescriptor, r, sizeof(reportDescriptor)); + } + else { + reportDescriptor.descriptor = NULL; + reportDescriptor.length = 0; + } + + if (_reportID == 0) { + reportBuffer = _buffer+1; + bufferSize = _size-1; + } + else { + reportBuffer = _buffer; + bufferSize = _size; + } + memset(reportBuffer, 0, bufferSize); + userSuppliedReportID = _reportID; + + if (_size > 0 && _reportID != 0 && ! forceReportID) { + reportBuffer[0] = _reportID; + forceUserSuppliedReportID = false; + } + else { + forceUserSuppliedReportID = true; + } + + registerProfile(false); +} + +HIDReporter::HIDReporter(USBHID& _HID, const HIDReportDescriptor* r, uint8_t* _buffer, unsigned _size) : HID(_HID) { + if (r != NULL) { + memcpy(&reportDescriptor, r, sizeof(reportDescriptor)); + } + else { + reportDescriptor.descriptor = NULL; + reportDescriptor.length = 0; + } + + reportBuffer = _buffer; + bufferSize = _size; + memset(_buffer, 0, _size); + userSuppliedReportID = 0; + forceUserSuppliedReportID = true; + + registerProfile(false); +} + +void HIDReporter::setFeature(uint8_t* in) { + return usb_hid_set_feature(reportID, in); +} + +uint16_t HIDReporter::getData(uint8_t type, uint8_t* out, uint8_t poll) { + return usb_hid_get_data(type, reportID, out, poll); +} + +uint16_t HIDReporter::getFeature(uint8_t* out, uint8_t poll) { + return usb_hid_get_data(HID_REPORT_TYPE_FEATURE, reportID, out, poll); +} + +uint16_t HIDReporter::getOutput(uint8_t* out, uint8_t poll) { + return usb_hid_get_data(HID_REPORT_TYPE_OUTPUT, reportID, out, poll); +} + diff --git a/STM32F1/libraries/USBComposite/USBHID.h b/STM32F1/libraries/USBComposite/USBHID.h new file mode 100644 index 000000000..9de64757a --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBHID.h @@ -0,0 +1,945 @@ +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#ifndef _USBHID_H_ +#define _USBHID_H_ + +#include +#include +#include "Stream.h" +#include "usb_hid.h" + +#define HID_MAX_REPORT_CHUNKS 24 + +#define HID_REPORT_ID_NONE -1 +#define HID_REPORT_ID_AUTO -2 + +#define HID_MOUSE_REPORT_ID 1 +#define HID_KEYBOARD_REPORT_ID 2 +#define HID_CONSUMER_REPORT_ID 3 +#define HID_DIGITIZER_REPORT_ID 4 +#define HID_JOYSTICK_REPORT_ID 20 + +#define HID_KEYBOARD_ROLLOVER 6 + +#define HID_AUTO_REPORT_ID_START 0x80 + +#define MACRO_GET_ARGUMENT_2(x, y, ...) y +#define MACRO_GET_ARGUMENT_1_WITH_DEFAULT(default, ...) MACRO_GET_ARGUMENT_2(placeholder, ## __VA_ARGS__, default) +#define MACRO_ARGUMENT_2_TO_END(skip, ...) __VA_ARGS__ + +// HIDBuffer_t data buffers must have even memory length because of how PMA transfers work +#define HID_DATA_BUFFER_SIZE(n) (((n)+1)/2*2) + +/* note that featureSize must be 1 less than the buffer size for the feature, + since the latter must include the reportId */ +/* this only works in a collection with a report_id */ +#define HID_FEATURE_REPORT_DESCRIPTOR(dataSize) \ + 0x06, 0x00, 0xFF, /* USAGE_PAGE (Vendor Defined Page 1) */ \ + 0x09, 0x01, /* USAGE (Vendor Usage 1) */ \ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ + 0x26, 0xff, 0x00, /* LOGICAL_MAXIMUM (255) */ \ + 0x75, 0x08, /* REPORT_SIZE (8) */ \ + 0x95, dataSize, /* REPORT_COUNT (xx) */ \ + 0xB1, 0x02, /* FEATURE (Data,Var,Abs) */ \ + +#define HID_OUTPUT_REPORT_DESCRIPTOR(dataSize) \ + 0x06, 0x00, 0xFF, /* USAGE_PAGE (Vendor Defined Page 1) */ \ + 0x09, 0x01, /* USAGE (Vendor Usage 1) */ \ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ + 0x26, 0xff, 0x00, /* LOGICAL_MAXIMUM (255) */ \ + 0x75, 0x08, /* REPORT_SIZE (8) */ \ + 0x95, dataSize, /* REPORT_COUNT (32) */ \ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ \ + +#define HID_CONSUMER_REPORT_DESCRIPTOR(...) \ + 0x05, 0x0C, /* usage page (consumer device) */ \ + 0x09, 0x01, /* usage -- consumer control */ \ + 0xA1, 0x01, /* collection (application) */ \ + 0x85, MACRO_GET_ARGUMENT_1_WITH_DEFAULT(HID_CONSUMER_REPORT_ID, ## __VA_ARGS__), /* REPORT_ID */ \ + 0x15, 0x00, /* logical minimum */ \ + 0x26, 0xFF, 0x03, /* logical maximum (3ff) */ \ + 0x19, 0x00, /* usage minimum (0) */ \ + 0x2A, 0xFF, 0x03, /* usage maximum (3ff) */ \ + 0x75, 0x10, /* report size (16) */ \ + 0x95, 0x01, /* report count (1) */ \ + 0x81, 0x00, /* input */ \ + MACRO_ARGUMENT_2_TO_END(__VA_ARGS__) \ + 0xC0 /* end collection */ + +#define HID_MOUSE_REPORT_DESCRIPTOR(...) \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) // 54 */ \ + 0x09, 0x02, /* USAGE (Mouse) */ \ + 0xa1, 0x01, /* COLLECTION (Application) */ \ + 0x85, MACRO_GET_ARGUMENT_1_WITH_DEFAULT(HID_MOUSE_REPORT_ID, ## __VA_ARGS__), /* REPORT_ID */ \ + 0x09, 0x01, /* USAGE (Pointer) */ \ + 0xa1, 0x00, /* COLLECTION (Physical) */ \ + 0x05, 0x09, /* USAGE_PAGE (Button) */ \ + 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ \ + 0x29, 0x08, /* USAGE_MAXIMUM (Button 8) */ \ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \ + 0x95, 0x08, /* REPORT_COUNT (8) */ \ + 0x75, 0x01, /* REPORT_SIZE (1) */ \ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ \ + 0x09, 0x30, /* USAGE (X) */ \ + 0x09, 0x31, /* USAGE (Y) */ \ + 0x09, 0x38, /* USAGE (Wheel) */ \ + 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */ \ + 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */ \ + 0x75, 0x08, /* REPORT_SIZE (8) */ \ + 0x95, 0x03, /* REPORT_COUNT (3) */ \ + 0x81, 0x06, /* INPUT (Data,Var,Rel) */ \ + 0xc0, /* END_COLLECTION */ \ + MACRO_ARGUMENT_2_TO_END(__VA_ARGS__) \ + 0xc0 /* END_COLLECTION */ + +#define HID_ABS_MOUSE_REPORT_DESCRIPTOR(...) \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) // 54 */ \ + 0x09, 0x02, /* USAGE (Mouse) */ \ + 0xa1, 0x01, /* COLLECTION (Application) */ \ + 0x85, MACRO_GET_ARGUMENT_1_WITH_DEFAULT(HID_MOUSE_REPORT_ID, ## __VA_ARGS__), /* REPORT_ID */ \ + 0x09, 0x01, /* USAGE (Pointer) */ \ + 0xa1, 0x00, /* COLLECTION (Physical) */ \ + 0x05, 0x09, /* USAGE_PAGE (Button) */ \ + 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ \ + 0x29, 0x08, /* USAGE_MAXIMUM (Button 8) */ \ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \ + 0x95, 0x08, /* REPORT_COUNT (8) */ \ + 0x75, 0x01, /* REPORT_SIZE (1) */ \ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ \ + 0x09, 0x30, /* USAGE (X) */ \ + 0x09, 0x31, /* USAGE (Y) */ \ + 0x16, 0x00, 0x80, /* LOGICAL_MINIMUM (-32768) */ \ + 0x26, 0xFF, 0x7f, /* LOGICAL_MAXIMUM (32767) */ \ + 0x75, 0x10, /* REPORT_SIZE (16) */ \ + 0x95, 0x02, /* REPORT_COUNT (2) */ \ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ + 0x09, 0x38, /* USAGE (Wheel) */ \ + 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */ \ + 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */ \ + 0x75, 0x08, /* REPORT_SIZE (8) */ \ + 0x95, 0x01, /* REPORT_COUNT (1) */ \ + 0x81, 0x06, /* INPUT (Data,Var,Rel) */ \ + 0xc0, /* END_COLLECTION */ \ + MACRO_ARGUMENT_2_TO_END(__VA_ARGS__) \ + 0xc0 /* END_COLLECTION */ + +#define HID_DIGITIZER_REPORT_DESCRIPTOR(...) \ + /* based on https://stackoverflow.com/questions/46033581/what-is-a-correct-usbhidreportdescriptor-for-android and https://forum.pjrc.com/threads/48762-USB-mouse-touchscreen-with-Teensy3-2-for-Android */ \ + 0x05, 0x0d, /* USAGE_PAGE (Digitizer) */ \ + /*0x09, 0x02, */ /* USAGE (Pen) */ \ + 0x09, 0x04, /* USAGE (Touch Screen) */ \ + 0xa1, 0x01, /* COLLECTION (Application) */ \ + 0x85, MACRO_GET_ARGUMENT_1_WITH_DEFAULT(HID_DIGITIZER_REPORT_ID, ## __VA_ARGS__), /* REPORT_ID */ \ + /* declare a finger collection */ \ + 0x09, 0x20, /* Usage (Stylus) */ \ + 0xA1, 0x00, /* Collection (Physical) */ \ + /* Declare a finger touch (finger up/down) */ \ + 0x09, 0x42, /* Usage (Tip Switch) */ \ + 0x09, 0x32, /* USAGE (In Range) */ \ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \ + 0x75, 0x01, /* REPORT_SIZE (1) */ \ + 0x95, 0x08, /* REPORT_COUNT (8) */ \ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ + /* Define absolute X and Y coordinates of 12 bits each */ \ + /* http://www.usb.org/developers/hidpage/Hut1_12v2.pdf */ \ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ \ + 0x09, 0x01, /* Usage (Pointer) */ \ + 0xA1, 0x00, /* Collection (Physical) */ \ + 0x09, 0x30, /* Usage (X) */ \ + 0x09, 0x31, /* Usage (Y) */ \ + 0x16, 0x00, 0x00, /* Logical Minimum (0) */ \ + 0x26, 0xFF, 0x0F, /* Logical Maximum (4095) */ \ + 0x36, 0x00, 0x00, /* Physical Minimum (0) */ \ + 0x46, 0xFF, 0x0F, /* Physical Maximum (4095) */ \ + 0x66, 0x00, 0x00, /* UNIT (None) */ \ + 0x75, 0x0C, /* Report Size (12), */ \ + 0x95, 0x02, /* Report Count (2), */ \ + 0x81, 0x02, /* Input (Data,Var,Abs) */ \ + 0xc0, /* END_COLLECTION */ \ + 0xc0, /* END_COLLECTION */ \ + MACRO_ARGUMENT_2_TO_END(__VA_ARGS__) \ + 0xc0 /* END_COLLECTION */ +// With this declaration a data packet must be sent as: +// bits 0-7 -> "touch" state (bit 0 = pen up/down, bit 1 = In Range) +// bits 8-19 -> absolute X coordinate (0...4095) +// bits 20-31-> absolute Y coordinate (0...4095) + +#define HID_KEYBOARD_REPORT_DESCRIPTOR(...) \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) // 47 */ \ + 0x09, 0x06, /* USAGE (Keyboard) */ \ + 0xa1, 0x01, /* COLLECTION (Application) */ \ + 0x85, MACRO_GET_ARGUMENT_1_WITH_DEFAULT(HID_KEYBOARD_REPORT_ID, ## __VA_ARGS__), /* REPORT_ID */ \ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ \ + 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */ \ + 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ \ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \ + 0x75, 0x01, /* REPORT_SIZE (1) */ \ + 0x95, 0x08, /* REPORT_COUNT (8) */ \ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ +\ + 0x95, 0x01, /* REPORT_COUNT (1) */ \ + 0x75, 0x08, /* REPORT_SIZE (8) */ \ + 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ \ +\ + 0x95, HID_KEYBOARD_ROLLOVER, /* REPORT_COUNT (6) */ \ + 0x75, 0x08, /* REPORT_SIZE (8) */ \ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ + 0x26, 0xDD, 0x00, /* LOGICAL_MAXIMUM (261) */ \ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ \ +\ + 0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */ \ + 0x29, 0xDD, /* USAGE_MAXIMUM (Keypad Hexadecimal) */ \ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ \ +\ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ \ + 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ \ + 0x29, 0x08, /* USAGE_MAXIMUM (Kana + 3 custom)*/ \ + 0x95, 0x08, /* REPORT_COUNT (8) */ \ + 0x75, 0x01, /* REPORT_SIZE (1) */ \ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ \ + MACRO_ARGUMENT_2_TO_END(__VA_ARGS__) \ + 0xc0 /* END_COLLECTION */ + +#define HID_BOOT_KEYBOARD_REPORT_DESCRIPTOR(...) \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) // 47 */ \ + 0x09, 0x06, /* USAGE (Keyboard) */ \ + 0xa1, 0x01, /* COLLECTION (Application) */ \ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ \ + 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */ \ + 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ \ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \ + 0x75, 0x01, /* REPORT_SIZE (1) */ \ + 0x95, 0x08, /* REPORT_COUNT (8) */ \ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ +\ + 0x95, 0x01, /* REPORT_COUNT (1) */ \ + 0x75, 0x08, /* REPORT_SIZE (8) */ \ + 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ \ +\ + 0x95, 0x06, /* REPORT_COUNT (6) */ \ + 0x75, 0x08, /* REPORT_SIZE (8) */ \ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ + 0x25, 0x65, /* LOGICAL_MAXIMUM (101) */ \ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ \ +\ + 0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */ \ + 0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */ \ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ \ +\ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ \ + 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ \ + 0x29, 0x08, /* USAGE_MAXIMUM (Kana + 3 custom)*/ \ + 0x95, 0x08, /* REPORT_COUNT (8) */ \ + 0x75, 0x01, /* REPORT_SIZE (1) */ \ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ \ + __VA_ARGS__ \ + 0xc0 /* END_COLLECTION */ + +#define HID_JOYSTICK_REPORT_DESCRIPTOR(...) \ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ \ + 0x09, 0x04, /* Usage (Joystick) */ \ + 0xA1, 0x01, /* Collection (Application) */ \ + 0x85, MACRO_GET_ARGUMENT_1_WITH_DEFAULT(HID_JOYSTICK_REPORT_ID, ## __VA_ARGS__), /* REPORT_ID */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x25, 0x01, /* Logical Maximum (1) */ \ + 0x75, 0x01, /* Report Size (1) */ \ + 0x95, 0x20, /* Report Count (32) */ \ + 0x05, 0x09, /* Usage Page (Button) */ \ + 0x19, 0x01, /* Usage Minimum (Button #1) */ \ + 0x29, 0x20, /* Usage Maximum (Button #32) */ \ + 0x81, 0x02, /* Input (variable,absolute) */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x25, 0x07, /* Logical Maximum (7) */ \ + 0x35, 0x00, /* Physical Minimum (0) */ \ + 0x46, 0x3B, 0x01, /* Physical Maximum (315) */ \ + 0x75, 0x04, /* Report Size (4) */ \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x65, 0x14, /* Unit (20) */ \ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ \ + 0x09, 0x39, /* Usage (Hat switch) */ \ + 0x81, 0x42, /* Input (variable,absolute,null_state) */ \ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ \ + 0x09, 0x01, /* Usage (Pointer) */ \ + 0xA1, 0x00, /* Collection () */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x26, 0xFF, 0x03, /* Logical Maximum (1023) */ \ + 0x75, 0x0A, /* Report Size (10) */ \ + 0x95, 0x04, /* Report Count (4) */ \ + 0x09, 0x30, /* Usage (X) */ \ + 0x09, 0x31, /* Usage (Y) */ \ + 0x09, 0x33, /* Usage (Rx) */ \ + 0x09, 0x34, /* Usage (Ry) */ \ + 0x81, 0x02, /* Input (variable,absolute) */ \ + 0xC0, /* End Collection */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x26, 0xFF, 0x03, /* Logical Maximum (1023) */ \ + 0x75, 0x0A, /* Report Size (10) */ \ + 0x95, 0x02, /* Report Count (2) */ \ + 0x09, 0x36, /* Usage (Slider) */ \ + 0x09, 0x36, /* Usage (Slider) */ \ + 0x81, 0x02, /* Input (variable,absolute) */ \ + MACRO_ARGUMENT_2_TO_END(__VA_ARGS__) \ + 0xC0 + +#define HID_SWITCH_CONTROLLER_REPORT_DESCRIPTOR(...) \ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ \ + 0x09, 0x05, /* Usage (Joystick) */ \ + 0xA1, 0x01, /* Collection (Application) */ \ + /* buttons */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x25, 0x01, /* Logical Maximum (1) */ \ + 0x35, 0x00, /* Physical Minimum (0) */ \ + 0x45, 0x01, /* Physical Maximum (1) */ \ + 0x75, 0x01, /* Report Size (1) */ \ + 0x95, 0x0e, /* Report Count (16) */ \ + 0x05, 0x09, /* Usage Page (9) */ \ + 0x19, 0x01, /* Usage Minimum (1) */ \ + 0x29, 0x0e, /* Usage Maximum (16) */ \ + 0x81, 0x02, /* Input (Data,Var,Abs) */ \ + 0x95, 0x02, \ + 0x81, 0x01, \ + /* HAT Switch */ \ + 0x05, 0x01, /* Usage Page (1) */ \ + 0x25, 0x07, /* Logical Maximum (7) */ \ + 0x46, 315&0xFF,315>>8, /* Physical Maximum (315) */ \ + 0x75, 0x04, /* Report Size (4) */ \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x65, 20, /* Unit (20) */ \ + 0x09, 57, /* Usage (57) */ \ + 0x81, 66, /* Input (66) */ \ + /* additional nibble here for Switch Pro Controller? */ \ + 0x65, 0, /* Unit (0) */ \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x81, 1, /* Input (1) */ \ + /* sticks */ \ + 0x26, 255 & 0xFF, 255 >> 8, /* Logical Maximum (255) */ \ + 0x46, 255 & 0xFF, 255 >> 8, /* Physical Maximum (255) */ \ + 0x09, 48, /* Usage (48) */ \ + 0x09, 49, /* Usage (49) */ \ + 0x09, 50, /* Usage (50) */ \ + 0x09, 53, /* Usage (53) */ \ + 0x75, 0x08, /* Report Size (8) */ \ + 0x95, 0x04, /* Report Count (4) */ \ + 0x81, 0x02, /* Input (Data,Var,Abs) */ \ + 0x75, 0x08, /* Report Size (8) */ \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x81, 0x01, /* Input (1) */ \ + __VA_ARGS__ \ + 0xC0, /* End Collection */ + + +#define RAWHID_USAGE_PAGE 0xFFC0 // recommended: 0xFF00 to 0xFFFF +#define RAWHID_USAGE 0x0C00 // recommended: 0x0100 to 0xFFFF + +#define LSB(x) ((x) & 0xFF) +#define MSB(x) (((x) & 0xFF00) >> 8) +// TODO: make this work for txSize > 255 +#define HID_RAW_REPORT_DESCRIPTOR(txSize, rxSize) \ + 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), \ + 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), \ + 0xA1, 0x01, /* Collection 0x01 */ \ +/* 0x85, 10, */ /* REPORT_ID (1) */ \ + 0x75, 0x08, /* report size = 8 bits */ \ + 0x15, 0x00, /* logical minimum = 0 */ \ + 0x26, 0xFF, 0x00, /* logical maximum = 255 */ \ +\ + 0x96, LSB(txSize), MSB(txSize), /* report count TX */ \ + 0x09, 0x01, /* usage */ \ + 0x81, 0x02, /* Input (array) */ \ +\ + 0x75, 0x08, /* report size = 8 bits */ \ + 0x15, 0x00, /* logical minimum = 0 */ \ + 0x26, 0xFF, 0x00, /* logical maximum = 255 */ \ + 0x96, LSB(rxSize), MSB(rxSize), /* report count RX */ \ + 0x09, 0x02, /* usage */ \ + 0x91, 0x02, /* OUTPUT (0x91) */ \ + 0xC0 /* end collection */ + +typedef struct { + const uint8_t* descriptor; + uint16_t length; +} HIDReportDescriptor; + +extern const HIDReportDescriptor* hidReportMouse; +extern const HIDReportDescriptor* hidReportKeyboard; +extern const HIDReportDescriptor* hidReportJoystick; +extern const HIDReportDescriptor* hidReportKeyboardMouse; +extern const HIDReportDescriptor* hidReportKeyboardJoystick; +extern const HIDReportDescriptor* hidReportKeyboardMouseJoystick; +extern const HIDReportDescriptor* hidReportBootKeyboard; +extern const HIDReportDescriptor* hidReportAbsMouse; +extern const HIDReportDescriptor* hidReportDigitizer; +extern const HIDReportDescriptor* hidReportConsumer; +extern const HIDReportDescriptor* hidReportSwitchController; + +#define HID_MOUSE hidReportMouse +#define HID_KEYBOARD hidReportKeyboard +#define HID_JOYSTICK hidReportJoystick +#define HID_KEYBOARD_MOUSE hidReportKeyboardMouse +#define HID_KEYBOARD_JOYSTICK hidReportKeyboardJoystick +#define HID_KEYBOARD_MOUSE_JOYSTICK hidReportKeyboardMouseJoystick +#define HID_BOOT_KEYBOARD hidReportBootKeyboard + +class HIDReporter; + +class USBHID { +private: + bool autoRegister = true; + bool enabledHID = false; + uint32 txPacketSize = 64; + struct usb_chunk* chunkList = nullptr; + // baseChunk holds any explicitly specified report descriptor that + // overrides any report descriptors from the chain of registered profiles + struct usb_chunk baseChunk = { 0, 0, 0 }; + HIDReporter* profiles = nullptr; +public: + static bool init(USBHID* me); + // add a report to the list ; if always is false, then it only works if autoRegister is true + void addReport(HIDReporter* r, bool always=true); + void clear(); + bool registerComponent(); + void setReportDescriptor(const uint8_t* report_descriptor, uint16_t report_descriptor_length); + void setReportDescriptor(const HIDReportDescriptor* reportDescriptor=NULL); + // All the strings are zero-terminated ASCII strings. Use NULL for defaults. + void begin(const uint8_t* report_descriptor, uint16_t length); + void begin(const HIDReportDescriptor* reportDescriptor = NULL); + void begin(USBCompositeSerial serial, const uint8_t* report_descriptor, uint16_t length); + void begin(USBCompositeSerial serial, const HIDReportDescriptor* reportDescriptor = NULL); + void setBuffers(uint8_t buffers, volatile HIDBuffer_t* fb=NULL, int count=0); // type = HID_REPORT_TYPE_FEATURE or HID_REPORT_TYPE_OUTPUT + bool addBuffer(uint8_t type, volatile HIDBuffer_t* buffer); + void clearBuffers(uint8_t type); + void clearBuffers(); + inline bool addFeatureBuffer(volatile HIDBuffer_t* buffer) { + return addBuffer(HID_REPORT_TYPE_FEATURE, buffer); + } + inline bool addOutputBuffer(volatile HIDBuffer_t* buffer) { + return addBuffer(HID_REPORT_TYPE_OUTPUT, buffer); + } + inline void setFeatureBuffers(volatile HIDBuffer_t* fb=NULL, int count=0) { + setBuffers(HID_REPORT_TYPE_FEATURE, fb, count); + } + inline void setOutputBuffers(volatile HIDBuffer_t* fb=NULL, int count=0) { + setBuffers(HID_REPORT_TYPE_OUTPUT, fb, count); + } + void end(void); + void setTXPacketSize(uint32 size=64) { + txPacketSize = size; + } + USBHID(bool _autoRegister=true) { + autoRegister = _autoRegister; + } + void setTXInterval(uint8 t) { + usb_hid_setTXInterval(t); + } + void setRXInterval(uint8 t) { + usb_hid_setRXInterval(t); + } +}; + +class HIDReporter { + private: + uint8_t* reportBuffer; + uint8_t reportID; + uint8_t userSuppliedReportID; + bool forceUserSuppliedReportID; + uint16_t bufferSize; + HIDReportDescriptor reportDescriptor; + struct usb_chunk reportChunks[3]; + class HIDReporter* next; + friend class USBHID; + + protected: + USBHID& HID; + + public: + void sendReport(); + uint8_t* getReport() { + return reportBuffer; + } + uint16_t getReportSize() { + return bufferSize; + } + // if you use this init function, the buffer starts with a reportID, even if the reportID is zero, + // and bufferSize includes the reportID; if reportID is zero, sendReport() will skip the initial + // reportID byte + HIDReporter(USBHID& _HID, const HIDReportDescriptor* r, uint8_t* _buffer, unsigned _size, uint8_t _reportID, bool forceReportID=false); + HIDReporter(USBHID& _HID, uint8_t* _buffer, unsigned _size, uint8_t _reportID, bool forceReportID=false) : HIDReporter(_HID, NULL, _buffer, _size, _reportID, forceReportID) {} + // if you use these init functions, the buffer has no reportID byte in it + HIDReporter(USBHID& _HID, const HIDReportDescriptor* r, uint8_t* _buffer, unsigned _size); + HIDReporter(USBHID& _HID, uint8_t* _buffer, unsigned _size) : HIDReporter(_HID, NULL, _buffer, _size) {} + uint16_t getFeature(uint8_t* out=NULL, uint8_t poll=1); + uint16_t getOutput(uint8_t* out=NULL, uint8_t poll=1); + uint16_t getData(uint8_t type, uint8_t* out, uint8_t poll=1); // type = HID_REPORT_TYPE_FEATURE or HID_REPORT_TYPE_OUTPUT + void setFeature(uint8_t* feature); + void registerProfile(bool always=true); +}; + +//================================================================================ +//================================================================================ +// Mouse + +#define MOUSE_LEFT 1 +#define MOUSE_RIGHT 2 +#define MOUSE_MIDDLE 4 +#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) + +class HIDMouse : public HIDReporter { +protected: + uint8_t _buttons; + void buttons(uint8_t b); + uint8_t reportBuffer[5]; +public: + HIDMouse(USBHID& HID, uint8_t reportID=HID_MOUSE_REPORT_ID) : HIDReporter(HID, hidReportMouse, reportBuffer, sizeof(reportBuffer), reportID), _buttons(0) {} + void begin(void); + void end(void); + void click(uint8_t b = MOUSE_LEFT); + void move(signed char x, signed char y, signed char wheel = 0); + void press(uint8_t b = MOUSE_LEFT); // press LEFT by default + void release(uint8_t b = MOUSE_LEFT); // release LEFT by default + bool isPressed(uint8_t b = MOUSE_ALL); // check all buttons by default +}; + +typedef struct { + uint8_t reportID; + uint8_t buttons; + int16_t x; + int16_t y; + uint8_t wheel; +} __packed AbsMouseReport_t; + +class HIDAbsMouse : public HIDReporter { +protected: + void buttons(uint8_t b); + AbsMouseReport_t report; +public: + HIDAbsMouse(USBHID& HID, uint8_t reportID=HID_MOUSE_REPORT_ID) : HIDReporter(HID, hidReportAbsMouse, (uint8_t*)&report, sizeof(report), reportID) { + report.buttons = 0; + report.x = 0; + report.y = 0; + report.wheel = 0; + } + void begin(void); + void end(void); + void click(uint8_t b = MOUSE_LEFT); + void move(int16_t x, int16_t y, int8_t wheel = 0); + void press(uint8_t b = MOUSE_LEFT); // press LEFT by default + void release(uint8_t b = MOUSE_LEFT); // release LEFT by default + bool isPressed(uint8_t b = MOUSE_ALL); // check all buttons by default +}; + +#define DIGITIZER_TOUCH 1 // for touch to be processed it could be required to be "in range" first +#define DIGITIZER_IN_RANGE 2 +#define DIGITIZER_TOUCH_IN_RANGE (DIGITIZER_TOUCH | DIGITIZER_IN_RANGE) + +typedef struct { + uint8_t reportID; + uint8_t buttons; + uint16_t x:12; + uint16_t y:12; +} __packed DigitizerReport_t; + +class HIDDigitizer : public HIDReporter { +protected: + void buttons(uint8_t b); + DigitizerReport_t report; +public: + HIDDigitizer(USBHID& HID, uint8_t reportID=HID_DIGITIZER_REPORT_ID) : HIDReporter(HID, hidReportDigitizer, (uint8_t*)&report, sizeof(report), reportID) { + report.buttons = 0; + report.x = 0; + report.y = 0; + } + void begin(void); + void end(void); + void move(uint16_t x, uint16_t y); // coordinates are 0 to 16383 + void click(uint8_t b = DIGITIZER_TOUCH_IN_RANGE); + void press(uint8_t b = DIGITIZER_TOUCH_IN_RANGE); + void release(uint8_t b = DIGITIZER_TOUCH_IN_RANGE); + bool isPressed(uint8_t b = DIGITIZER_TOUCH_IN_RANGE); +}; + +typedef struct { + uint8_t reportID; + uint16_t button; +} __packed ConsumerReport_t; + +class HIDConsumer : public HIDReporter { +protected: + ConsumerReport_t report; +public: + enum { + BRIGHTNESS_UP = 0x6F, + BRIGHTNESS_DOWN = 0x70, + NEXT_TRACK = 0xB5, + PREVIOUS_TRACK = 0xB6, + PLAY_OR_PAUSE = 0xCD, + VOLUME_UP = 0xE9, + VOLUME_DOWN = 0xEA, + REWIND = 0xB4, + FAST_FORWARD = 0xB3, + MUTE = 0xE2, + MENU = 0x40, + MENU_PICK = 0x41, + MENU_UP = 0x42, + MENU_DOWN = 0x43, + MENU_LEFT = 0x44, + MENU_RIGHT = 0x45, + MENU_ESCAPE = 0x46, + // see pages 117 of https://www.usb.org/sites/default/files/hut1_22.pdf + }; + HIDConsumer(USBHID& HID, uint8_t reportID=HID_CONSUMER_REPORT_ID) : HIDReporter(HID, hidReportConsumer, (uint8_t*)&report, sizeof(report), reportID) { + report.button = 0; + } + void begin(void); + void end(void); + void press(uint16_t button); + void release(); +}; + +#define KEY_LEFT_CTRL 0x80 +#define KEY_LEFT_SHIFT 0x81 +#define KEY_LEFT_ALT 0x82 +#define KEY_LEFT_GUI 0x83 +#define KEY_RIGHT_CTRL 0x84 +#define KEY_RIGHT_SHIFT 0x85 +#define KEY_RIGHT_ALT 0x86 +#define KEY_RIGHT_GUI 0x87 + +#define KEY_HID_OFFSET 0x88 + +// The following definitions takes their value from the document at https://www.usb.org/sites/default/files/hut1_22.pdf, starting p82 +// However, their value are augmented by KEY_HID_OFFSET (for example, KEY_F12 real value is 0x45) +#define KEY_UP_ARROW 0xDA +#define KEY_DOWN_ARROW 0xD9 +#define KEY_LEFT_ARROW 0xD8 +#define KEY_RIGHT_ARROW 0xD7 +#define KEY_BACKSPACE 0xB2 +#define KEY_TAB 0xB3 +#define KEY_RETURN 0xB0 +#define KEY_ESC 0xB1 +#define KEY_INSERT 0xD1 +#define KEY_DELETE 0xD4 +#define KEY_PAGE_UP 0xD3 +#define KEY_PAGE_DOWN 0xD6 +#define KEY_HOME 0xD2 +#define KEY_END 0xD5 +#define KEY_CAPS_LOCK 0xC1 +#define KEY_F1 0xC2 +#define KEY_F2 0xC3 +#define KEY_F3 0xC4 +#define KEY_F4 0xC5 +#define KEY_F5 0xC6 +#define KEY_F6 0xC7 +#define KEY_F7 0xC8 +#define KEY_F8 0xC9 +#define KEY_F9 0xCA +#define KEY_F10 0xCB +#define KEY_F11 0xCC +#define KEY_F12 0xCD +#define KEY_F13 (KEY_HID_OFFSET+0x68) +#define KEY_F14 (KEY_HID_OFFSET+0x69) +#define KEY_F15 (KEY_HID_OFFSET+0x6A) +#define KEY_KP_DOT (KEY_HID_OFFSET+0x63) +#define KEY_KP_ASTERISK (KEY_HID_OFFSET+0x55) +#define KEY_KP_PLUS (KEY_HID_OFFSET+0x57) +#define KEY_NUM_LOCK (KEY_HID_OFFSET+0x53) +#define KEY_KP_SLASH (KEY_HID_OFFSET+0x54) +#define KEY_KP_ENTER (KEY_HID_OFFSET+0x58) +#define KEY_KP_MINUS (KEY_HID_OFFSET+0x56) +#define KEY_KP_EQUAL (KEY_HID_OFFSET+0x86) +#define KEY_KP_0 (KEY_HID_OFFSET+0x62) +#define KEY_KP_1 (KEY_HID_OFFSET+0x59) +#define KEY_KP_2 (KEY_HID_OFFSET+0x5a) +#define KEY_KP_3 (KEY_HID_OFFSET+0x5b) +#define KEY_KP_4 (KEY_HID_OFFSET+0x5c) +#define KEY_KP_5 (KEY_HID_OFFSET+0x5d) +#define KEY_KP_6 (KEY_HID_OFFSET+0x5e) +#define KEY_KP_7 (KEY_HID_OFFSET+0x5f) +#define KEY_KP_8 (KEY_HID_OFFSET+0x60) +#define KEY_KP_9 (KEY_HID_OFFSET+0x61) +#define KEY_VOLUME_UP (KEY_HID_OFFSET+0x80) +#define KEY_VOLUME_DOWN (KEY_HID_OFFSET+0x81) +#define KEY_MUTE (KEY_HID_OFFSET+0x7f) +#define KEY_HELP (KEY_HID_OFFSET+0x75) +#define KEY_POWER (KEY_HID_OFFSET+0x66) +#define KEY_102ND (KEY_HID_OFFSET+0x64) +#define KEY_PRINT_SCREEN (KEY_HID_OFFSET+0x46) +#define KEY_SCROLL_LOCK (KEY_HID_OFFSET+0x47) +#define KEY_PAUSE (KEY_HID_OFFSET+0x48) + + + +typedef struct{ + uint8_t reportID; + uint8_t modifiers; + uint8_t reserved; + uint8_t keys[HID_KEYBOARD_ROLLOVER]; +} __packed KeyReport_t; + +class HIDKeyboard : public Print, public HIDReporter { +public: + KeyReport_t keyReport; + +protected: + uint8_t leds[HID_BUFFER_ALLOCATE_SIZE(1,1)]; + HIDBuffer_t ledData; + uint8_t reportID; + uint8_t getKeyCode(uint16_t k, uint8_t* modifiersP); + bool adjustForHostCapsLock = true; + +public: + HIDKeyboard(USBHID& HID, uint8_t _reportID=HID_KEYBOARD_REPORT_ID) : + HIDReporter(HID, hidReportKeyboard, (uint8*)&keyReport, sizeof(KeyReport_t), _reportID), + ledData(leds, HID_BUFFER_SIZE(1,_reportID), _reportID, HID_BUFFER_MODE_NO_WAIT), + reportID(_reportID) + {} + void begin(void); + void end(void); + void setAdjustForHostCapsLock(bool state) { + adjustForHostCapsLock = state; + } + inline uint8 getLEDs(void) { + return leds[reportID != 0 ? 1 : 0]; + } + virtual size_t write(uint8_t k); + virtual size_t press(uint16_t k); + virtual size_t release(uint16_t k); + virtual void releaseAll(void); +}; + + +//================================================================================ +//================================================================================ +// Joystick + +// only works for little-endian machines, but makes the code so much more +// readable +typedef struct { + uint8_t reportID; + uint32_t buttons; + unsigned hat:4; + unsigned x:10; + unsigned y:10; + unsigned rx:10; + unsigned ry:10; + unsigned sliderLeft:10; + unsigned sliderRight:10; +} __packed JoystickReport_t; + +static_assert(sizeof(JoystickReport_t)==13, "Wrong endianness/packing!"); + +class HIDJoystick : public HIDReporter { +protected: + JoystickReport_t joyReport; + bool manualReport = false; + void safeSendReport(void); +public: + inline void send(void) { + sendReport(); + } + void setManualReportMode(bool manualReport); // in manual report mode, report only sent when send() is called + bool getManualReportMode(); + void begin(void); + void end(void); + void button(uint8_t button, bool val); + void buttons(uint32_t b) { + joyReport.buttons = b; + } + void X(uint16_t val); + void Y(uint16_t val); + void position(uint16_t x, uint16_t y); + void Xrotate(uint16_t val); + void Yrotate(uint16_t val); + void sliderLeft(uint16_t val); + void sliderRight(uint16_t val); + void slider(uint16_t val); + void hat(int16_t dir); + HIDJoystick(USBHID& HID, uint8_t reportID=HID_JOYSTICK_REPORT_ID) + : HIDReporter(HID, hidReportJoystick, (uint8_t*)&joyReport, sizeof(joyReport), reportID) { + joyReport.buttons = 0; + joyReport.hat = 15; + joyReport.x = 512; + joyReport.y = 512; + joyReport.rx = 512; + joyReport.ry = 512; + joyReport.sliderLeft = 0; + joyReport.sliderRight = 0; + } +}; + +typedef struct { + uint16_t buttons; + uint8_t dpad; + uint8_t leftX; + uint8_t leftY; + uint8_t rightX; + uint8_t rightY; + uint8_t pad; +} __packed SwitchControllerReport_t; + +class HIDSwitchController : public HIDReporter { +protected: + SwitchControllerReport_t report; + bool manualReport = false; + +public: + const int32_t AXIS_MAX = 255; + const int32_t AXIS_NEUTRAL = 128; + const int32_t AXIS_MIN = 0; + + enum { + DPAD_TOP = 0, + DPAD_TOPRIGHT = 1, + DPAD_RIGHT = 2, + DPAD_BOTRIGHT = 3, + DPAD_BOTTOM = 4, + DPAD_BOTLEFT = 5, + DPAD_LEFT = 6, + DPAD_TOPLEFT = 7, + DPAD_NEUTRAL = 8, + }; + + enum { + BUTTON_Y = 0, + BUTTON_B = 1, + BUTTON_A = 2, + BUTTON_X = 3, + BUTTON_L = 4, + BUTTON_R = 5, + BUTTON_ZL = 6, + BUTTON_ZR = 7, + BUTTON_MINUS = 8, + BUTTON_PLUS = 9, + BUTTON_LEFT_CLICK = 10, + BUTTON_RIGHT_CLICK = 11, + BUTTON_HOME = 12, + BUTTON_CAPTURE = 13, + BUTTON_EXTRA1 = 14, + BUTTON_EXTRA2 = 15, + }; + + void setManualReportMode(bool m) { + manualReport = m; + } + bool getManualReportMode() { + return manualReport; + } + void safeSendReport() { + if (!manualReport) + sendReport(); + } + void send() { + sendReport(); + } + + + void button(uint8_t b, bool val) { + uint16_t mask = ((uint16_t)1 << b); + + if (val) { + report.buttons |= mask; + } else { + report.buttons &= ~mask; + } + safeSendReport(); + } + + void buttons(uint16_t b) { + report.buttons = b & 0x3FFF; + safeSendReport(); + } + + void dpad(uint8_t value) { + report.dpad = value & 0xF; + safeSendReport(); + } + + void X(uint8_t v) { + report.leftX = v; + safeSendReport(); + } + + void Y(uint8_t v) { + report.leftY = v; + safeSendReport(); + } + + void XRight(uint8_t v) { + report.rightX = v; + safeSendReport(); + } + + void YRight(uint8_t v) { + report.rightY = v; + safeSendReport(); + } + + void begin() { + USBComposite.setVendorId(0x0F0D); + USBComposite.setProductId(0x00c1); + USBComposite.setProductString("HORIPAD S"); + USBComposite.setManufacturerString("Omega Centauri Software"); + HID.begin(hidReportSwitchController); + } + + void end() { + HID.end(); + } + + HIDSwitchController(USBHID& HID) + : HIDReporter(HID, (uint8_t*)&report, sizeof(report)) { + report.buttons = 0; + report.dpad = DPAD_NEUTRAL; + report.leftX = AXIS_NEUTRAL; + report.leftY = AXIS_NEUTRAL; + report.rightX = AXIS_NEUTRAL; + report.rightY = AXIS_NEUTRAL; + report.pad = 0; + } +}; + +templateclass HIDRaw : public HIDReporter { +private: + uint8_t txBuffer[txSize]; + uint8_t rxBuffer[HID_BUFFER_ALLOCATE_SIZE(rxSize,0)]; + HIDBuffer_t buf; +public: + HIDRaw(USBHID& HID) : HIDReporter(HID, txBuffer, sizeof(txBuffer)) {} + void begin(void) { + buf.buffer = rxBuffer; + buf.bufferSize = HID_BUFFER_SIZE(rxSize,0); + buf.reportID = 0; + HID.addOutputBuffer(&buf); + } + void end(void); + void send(const uint8_t* data, unsigned n=sizeof(txBuffer)) { + memset(txBuffer, 0, sizeof(txBuffer)); + memcpy(txBuffer, data, n>sizeof(txBuffer)?sizeof(txBuffer):n); + sendReport(); + } +}; + + + +#endif + diff --git a/STM32F1/libraries/USBComposite/USBMIDI.cpp b/STM32F1/libraries/USBComposite/USBMIDI.cpp new file mode 100644 index 000000000..d08bfd732 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBMIDI.cpp @@ -0,0 +1,563 @@ +/****************************************************************************** + * This started out as a munging of Tymm Twillman's arduino Midi Library into the Libusb class, + * though by now very little of the original code is left, except for the class API and + * comments. Tymm Twillman kindly gave Alexander Pruss permission to relicense his code under the MIT + * license, which fixed a nasty licensing mess. + * + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * Copyright (c) 2013 Magnus Lundin. + * Copyright (c) 2013 Donald Delmar Davis, Suspect Devices. + * (c) 2003-2008 Tymm Twillman + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * + *****************************************************************************/ + +/** + * @brief USB MIDI device with a class compatible with maplemidi + */ + +#include "USBComposite.h" + +#include +#include +#undef true +#undef false +#include +#include "usb_midi_device.h" +#include +#include "usb_generic.h" + + +/* + * USBMIDI interface + */ + +#define USB_TIMEOUT 50 + +void USBMIDI::setChannel(unsigned int channel) { + channelIn_ = channel; + +} + +bool USBMIDI::init(USBMIDI* me) { + usb_midi_setTXEPSize(me->txPacketSize); + usb_midi_setRXEPSize(me->rxPacketSize); + return true; +} + +bool USBMIDI::registerComponent() { + return USBComposite.add(&usbMIDIPart, this, (USBPartInitializer)&USBMIDI::init); +} + +void USBMIDI::begin(unsigned channel) { + setChannel(channel); + + if (enabled) + return; + + USBComposite.clear(); + registerComponent(); + USBComposite.begin(); + + enabled = true; +} + +void USBMIDI::end(void) { + if (enabled) { + USBComposite.end(); + enabled = false; + } +} + +void USBMIDI::writePacket(uint32 p) { + this->writePackets(&p, 1); +} + +void USBMIDI::writePackets(const void *buf, uint32 len) { + if (!this->isConnected() || !buf) { + return; + } + + uint32 txed = 0; + uint32 old_txed = 0; + uint32 start = millis(); + + uint32 sent = 0; + + while (txed < len && (millis() - start < USB_TIMEOUT)) { + sent = usb_midi_tx((const uint32*)buf + txed, len - txed); + txed += sent; + if (old_txed != txed) { + start = millis(); + } + old_txed = txed; + } + + + if (sent == usb_midi_txEPSize) { + while (usb_midi_is_transmitting() != 0) { + } + /* flush out to avoid having the pc wait for more data */ + usb_midi_tx(NULL, 0); + } +} + +uint32 USBMIDI::available(void) { + return usb_midi_data_available(); +} + +uint32 USBMIDI::readPackets(void *buf, uint32 len) { + if (!buf) { + return 0; + } + + uint32 rxed = 0; + while (rxed < len) { + rxed += usb_midi_rx((uint32*)buf + rxed, len - rxed); + } + + return rxed; +} + +/* Blocks forever until 1 byte is received */ +uint32 USBMIDI::readPacket(void) { + uint32 p; + this->readPackets(&p, 1); + return p; +} + +uint8 USBMIDI::pending(void) { + return usb_midi_get_pending(); +} + +uint8 USBMIDI::isConnected(void) { + return usb_is_connected(USBLIB) && usb_is_configured(USBLIB); +} + + + + +// These are midi status message types are defined in MidiSpec.h + +union EVENT_t { + uint32 i; + uint8 b[4]; + MIDI_EVENT_PACKET_t p; +}; + +// Handle decoding incoming MIDI traffic a word at a time -- remembers +// what it needs to from one call to the next. +// +// This is a private function & not meant to be called from outside this class. +// It's used whenever data is available from the USB port. +// +void USBMIDI::dispatchPacket(uint32 p) +{ + union EVENT_t e; + e.i=p; + + switch (e.p.cin) { + case CIN_SYSEX: + handleSysExData(e.p.midi0); + handleSysExData(e.p.midi1); + handleSysExData(e.p.midi2); + break; + case CIN_SYSEX_ENDS_IN_1: + handleSysExData(e.p.midi0); + handleSysExEnd(); + break; + case CIN_SYSEX_ENDS_IN_2: + handleSysExData(e.p.midi0); + handleSysExData(e.p.midi1); + handleSysExEnd(); + break; + case CIN_SYSEX_ENDS_IN_3: + handleSysExData(e.p.midi0); + handleSysExData(e.p.midi1); + handleSysExData(e.p.midi2); + handleSysExEnd(); + break; + case CIN_3BYTE_SYS_COMMON: + if (e.p.midi0 == MIDIv1_SONG_POSITION_PTR) { + handleSongPosition(((uint16)e.p.midi2)<<7|((uint16)e.p.midi1)); + } + break; + + case CIN_2BYTE_SYS_COMMON: + switch (e.p.midi0) { + case MIDIv1_SONG_SELECT: + handleSongSelect(e.p.midi1); + break; + case MIDIv1_MTC_QUARTER_FRAME: + // reference library doesnt handle quarter frame. + break; + } + break; + case CIN_NOTE_OFF: + handleNoteOff(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1, e.p.midi2); + break; + case CIN_NOTE_ON: + handleNoteOn(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1, e.p.midi2); + break; + case CIN_AFTER_TOUCH: + handleVelocityChange(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1, e.p.midi2); + break; + case CIN_CONTROL_CHANGE: + handleControlChange(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1, e.p.midi2); + break; + case CIN_PROGRAM_CHANGE: + handleProgramChange(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1); + break; + case CIN_CHANNEL_PRESSURE: + handleAfterTouch(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1); + break; + + case CIN_PITCH_WHEEL: + handlePitchChange(MIDIv1_VOICE_CHANNEL(e.p.midi0), ((uint16)e.p.midi2)<<7|((uint16)e.p.midi1)); + break; + case CIN_1BYTE: + switch (e.p.midi0) { + case MIDIv1_CLOCK: + handleSync(); + break; + case MIDIv1_TICK: + break; + case MIDIv1_START: + handleStart(); + break; + case MIDIv1_CONTINUE: + handleContinue(); + break; + case MIDIv1_STOP: + handleStop(); + break; + case MIDIv1_ACTIVE_SENSE: + handleActiveSense(); + break; + case MIDIv1_RESET: + handleReset(); + break; + case MIDIv1_TUNE_REQUEST: + handleTuneRequest(); + break; + + default: + break; + } + break; + } +} + + +// Try to read data from USB port & pass anything read to processing function +void USBMIDI::poll(void) +{ while(available()) { + dispatchPacket(readPacket()); + } +} + +static union EVENT_t outPacket; // since we only use one at a time no point in reallocating it + +void USBMIDI::sendNoteOff(unsigned int channel, unsigned int note, unsigned int velocity) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_NOTE_OFF; + outPacket.p.midi0=MIDIv1_NOTE_OFF|(channel & 0x0f); + outPacket.p.midi1=note; + outPacket.p.midi2=velocity; + writePacket(outPacket.i); + +} + +// Send Midi NOTE ON message to a given channel, with note 0-127 and velocity 0-127 +void USBMIDI::sendNoteOn(unsigned int channel, unsigned int note, unsigned int velocity) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_NOTE_ON; + outPacket.p.midi0=MIDIv1_NOTE_ON|(channel & 0x0f); + outPacket.p.midi1=note; + outPacket.p.midi2=velocity; + writePacket(outPacket.i); + +} + +// Send a Midi VELOCITY CHANGE message to a given channel, with given note 0-127, +// and new velocity 0-127 +// Note velocity change == polyphonic aftertouch. +// Note aftertouch == channel pressure. +void USBMIDI::sendVelocityChange(unsigned int channel, unsigned int note, unsigned int velocity) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_AFTER_TOUCH; + outPacket.p.midi0=MIDIv1_AFTER_TOUCH |(channel & 0x0f); + outPacket.p.midi1=note; + outPacket.p.midi2=velocity; + writePacket(outPacket.i); + +} + + +// Send a Midi CC message to a given channel, as a given controller 0-127, with given +// value 0-127 +void USBMIDI::sendControlChange(unsigned int channel, unsigned int controller, unsigned int value) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_CONTROL_CHANGE; + outPacket.p.midi0=MIDIv1_CONTROL_CHANGE |(channel & 0x0f); + outPacket.p.midi1=controller; + outPacket.p.midi2=value; + writePacket(outPacket.i); + +} + +// Send a Midi PROGRAM CHANGE message to given channel, with program ID 0-127 +void USBMIDI::sendProgramChange(unsigned int channel, unsigned int program) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_PROGRAM_CHANGE; + outPacket.p.midi0=MIDIv1_PROGRAM_CHANGE |(channel & 0x0f); + outPacket.p.midi1=program; + writePacket(outPacket.i); + +} + +// Send a Midi AFTER TOUCH message to given channel, with velocity 0-127 +void USBMIDI::sendAfterTouch(unsigned int channel, unsigned int velocity) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_CHANNEL_PRESSURE; + outPacket.p.midi0=MIDIv1_CHANNEL_PRESSURE |(channel & 0x0f); + outPacket.p.midi1=velocity; + writePacket(outPacket.i); + +} + +// Send a Midi PITCH CHANGE message, with a 14-bit pitch (always for all channels) +void USBMIDI::sendPitchChange(unsigned int channel, unsigned int pitch) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_PITCH_WHEEL; + outPacket.p.midi0=MIDIv1_PITCH_WHEEL |(channel & 0x0f); + outPacket.p.midi1= (uint8) pitch & 0x07F; + outPacket.p.midi2= (uint8) (pitch>>7) & 0x7f; + writePacket(outPacket.i); + +} + +// Send a Midi SONG POSITION message, with a 14-bit position (always for all channels) +void USBMIDI::sendSongPosition(unsigned int position) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_3BYTE_SYS_COMMON; + outPacket.p.midi0=MIDIv1_SONG_POSITION_PTR; + outPacket.p.midi1= (uint8) position & 0x07F; + outPacket.p.midi2= (uint8) (position>>7) & 0x7f; + writePacket(outPacket.i); + +} + +// Send a Midi SONG SELECT message, with a song ID of 0-127 (always for all channels) +void USBMIDI::sendSongSelect(unsigned int song) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_2BYTE_SYS_COMMON; + outPacket.p.midi0=MIDIv1_SONG_SELECT; + outPacket.p.midi1= (uint8) song & 0x07F; + writePacket(outPacket.i); + +} + +// Send a Midi TUNE REQUEST message (TUNE REQUEST is always for all channels) +void USBMIDI::sendTuneRequest(void) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_1BYTE; + outPacket.p.midi0=MIDIv1_TUNE_REQUEST; + writePacket(outPacket.i); +} + + +// Send a Midi SYNC message (SYNC is always for all channels) +void USBMIDI::sendSync(void) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_1BYTE; + outPacket.p.midi0=MIDIv1_CLOCK; + writePacket(outPacket.i); +} + +// Send a Midi START message (START is always for all channels) +void USBMIDI::sendStart(void) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_1BYTE; + outPacket.p.midi0=MIDIv1_START ; + writePacket(outPacket.i); +} + + +// Send a Midi CONTINUE message (CONTINUE is always for all channels) +void USBMIDI::sendContinue(void) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_1BYTE; + outPacket.p.midi0=MIDIv1_CONTINUE ; + writePacket(outPacket.i); +} + + +// Send a Midi STOP message (STOP is always for all channels) +void USBMIDI::sendStop(void) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_1BYTE; + outPacket.p.midi0=MIDIv1_STOP ; + writePacket(outPacket.i); +} + +// Send a Midi ACTIVE SENSE message (ACTIVE SENSE is always for all channels) +void USBMIDI::sendActiveSense(void) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_1BYTE; + outPacket.p.midi0=MIDIv1_ACTIVE_SENSE ; + writePacket(outPacket.i); +} + +// Send a Midi RESET message (RESET is always for all channels) +void USBMIDI::sendReset(void) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_1BYTE; + outPacket.p.midi0=MIDIv1_RESET ; + writePacket(outPacket.i); +} + +void USBMIDI::sendSysex(uint8_t b0, uint8_t b1, uint8_t b2) +{ + outPacket.p.cable = DEFAULT_MIDI_CABLE; + outPacket.p.cin = CIN_SYSEX_ENDS_IN_3; + outPacket.p.midi0 = b0; + outPacket.p.midi1 = b1; + outPacket.p.midi2 = b2; + writePacket(outPacket.i); +} + +void USBMIDI::sendSysexEndsIn1(uint8_t b0) +{ + outPacket.p.cable = DEFAULT_MIDI_CABLE; + outPacket.p.cin = CIN_SYSEX_ENDS_IN_1; + outPacket.p.midi0 = b0; + outPacket.p.midi1 = 0; + outPacket.p.midi2 = 0; + writePacket(outPacket.i); +} + +void USBMIDI::sendSysexEndsIn2(uint8_t b0, uint8_t b1) +{ + outPacket.p.cable = DEFAULT_MIDI_CABLE; + outPacket.p.cin = CIN_SYSEX_ENDS_IN_2; + outPacket.p.midi0 = b0; + outPacket.p.midi1 = b1; + outPacket.p.midi2 = 0; + writePacket(outPacket.i); +} + +void USBMIDI::sendSysexEndsIn3(uint8_t b0, uint8_t b1, uint8_t b2) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + outPacket.p.cin=CIN_SYSEX_ENDS_IN_3; + outPacket.p.midi0= b0; + outPacket.p.midi1= b1; + outPacket.p.midi2= b2; + writePacket(outPacket.i); +} + +void USBMIDI::sendSysexPayload(uint8_t *payload, uint32 length) +{ + outPacket.p.cable=DEFAULT_MIDI_CABLE; + if (length == 1) + { + sendSysexEndsIn3(MIDIv1_SYSEX_START, payload[0], MIDIv1_SYSEX_END); + return; + } + + sendSysex(MIDIv1_SYSEX_START, payload[0], payload[1]); + + unsigned int offset = 2; + for (; offset < length - 2; offset += 3) + { + sendSysex(payload[offset], payload[offset + 1], payload[offset + 2]); + } + + unsigned int remaining = length - offset; + if (remaining == 0) + { + sendSysexEndsIn1(MIDIv1_SYSEX_END); + } + else if (remaining == 1) + { + sendSysexEndsIn2(payload[offset], MIDIv1_SYSEX_END); + } + else + { + sendSysexEndsIn3(payload[offset], payload[offset + 1], MIDIv1_SYSEX_END); + } +} + + +const uint32 midiNoteFrequency_10ths[128] = { + 82, 87, 92, 97, 103, 109, 116, 122, 130, 138, 146, 154, 164, 173, 184, 194, + 206, 218, 231, 245, 260, 275, 291, 309, 327, 346, 367, 389, 412, 437, 462, 490, + 519, 550, 583, 617, 654, 693, 734, 778, 824, 873, 925, 980, 1038, 1100, 1165, 1235, + 1308, 1386, 1468, 1556, 1648, 1746, 1850, 1960, 2077, 2200, 2331, 2469, 2616, 2772, 2937, 3111, + 3296, 3492, 3700, 3920, 4153, 4400, 4662, 4939, 5233, 5544, 5873, 6223, 6593, 6985, 7400, 7840, + 8306, 8800, 9323, 9878, 10465, 11087, 11747, 12445, 13185, 13969, 14800, 15680, 16612, 17600, 18647, 19755, + 20930, 22175, 23493, 24890, 26370, 27938, 29600, 31360, 33224, 35200, 37293, 39511, 41860, 44349, 46986, 49780, + 52740, 55877, 59199, 62719, 66449, 70400, 74586, 79021, 83720, 88698, 93973, 99561, 105481, 111753, 118398, 125439 }; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +// Placeholders. You should subclass the Midi base class and define these to have your +// version called. +void USBMIDI::handleNoteOff(unsigned int channel, unsigned int note, unsigned int velocity) {} +void USBMIDI::handleNoteOn(unsigned int channel, unsigned int note, unsigned int velocity) {} +void USBMIDI::handleVelocityChange(unsigned int channel, unsigned int note, unsigned int velocity) {} +void USBMIDI::handleControlChange(unsigned int channel, unsigned int controller, unsigned int value) {} +void USBMIDI::handleProgramChange(unsigned int channel, unsigned int program) {} +void USBMIDI::handleAfterTouch(unsigned int channel, unsigned int velocity) {} +void USBMIDI::handlePitchChange(unsigned int channel, unsigned int pitch) {} +void USBMIDI::handleSongPosition(unsigned int position) {} +void USBMIDI::handleSongSelect(unsigned int song) {} +void USBMIDI::handleTuneRequest(void) {} +void USBMIDI::handleSync(void) {} +void USBMIDI::handleStart(void) {} +void USBMIDI::handleContinue(void) {} +void USBMIDI::handleStop(void) {} +void USBMIDI::handleActiveSense(void) {} +void USBMIDI::handleReset(void) {} +void USBMIDI::handleSysExData(unsigned char) {} +void USBMIDI::handleSysExEnd(void) {} +#pragma GCC diagnostic pop diff --git a/STM32F1/libraries/USBComposite/USBMIDI.h b/STM32F1/libraries/USBComposite/USBMIDI.h new file mode 100644 index 000000000..2c990bdf2 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBMIDI.h @@ -0,0 +1,204 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * Copyright (c) 2013 Magnus Lundin. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief Wirish USB MIDI port (MidiUSB). + */ + +#ifndef _USBMIDI_H_ +#define _USBMIDI_H_ + +//#include +#include +#include +#include "usb_generic.h" + +/* + * This is the Midi class. If you are just sending Midi data, you only need to make an + * instance of the class, passing it your USB port -- in most cases it looks like + * + * USBMidi midi; + * + * then you don't need to do anything else; you can start using it to send Midi messages, + * e.g. + * + * midi.sendNoteOn(1, note, velocity); + * + * If you are using it to receive Midi data, it's a little more complex & you will need + * to subclass the Midi class. + * + * For people not used to C++ this may look confusing, but it's actually pretty easy. + * Note that you only need to write the functions for event types you want to handle. + * They should match the names & prototypes of the functions in the class; look at + * the functions in the Midi class below that have the keyword "virtual" to see which + * ones you can use. + * + * Here's an example of one that takes NOTE ON, NOTE OFF, and CONTROL CHANGE: + * + * class MyMidi : public USBMidi { + * public: + * + * // Need this to compile; it just hands things off to the Midi class. + * MyMidi() : USBMidi(s) {} + * + * void handleNoteOn(unsigned int channel, unsigned int note, unsigned int velocity) + * { + * if (note == 40) {digitalWrite(13, HIGH); } + * } + * + * void handleNoteOff(unsigned int channel, unsigned int note, unsigned int velocity) + * { + * if (note == 40) { digitalWrite(13, LOW); } + * } + * + * void handleControlChange(unsigned int channel, unsigned int controller, + * unsigned int value) + * { + * analogWrite(6, value * 2); + * } + * + * Then you need to make an instance of this class: + * + * MyMidi midi(); + * + * If receiving Midi data, you also need to call the poll function every time through + * loop(); e.g. + * + * void loop() { + * midi.poll(); + * } + * + * This causes the Midi class to read data from the USB port and process it. + */ + +class USBMIDI { +private: + bool enabled = false; + + /* Private Receive Parameters */ + + // The channel this Midi instance receives data for (0 means all channels) + int channelIn_; + + /* Internal functions */ + + // Called whenever data is read from the USB port + void dispatchPacket(uint32 packet); + + uint32 txPacketSize = 64; + uint32 rxPacketSize = 64; + +public: + static bool init(USBMIDI* me); + // This registers this USB composite device component with the USBComposite class instance. + bool registerComponent(); + void setChannel(unsigned channel=0); + unsigned getChannel() { + return channelIn_; + } + + void setRXPacketSize(uint32 size=64) { + rxPacketSize = size; + } + + void setTXPacketSize(uint32 size=64) { + txPacketSize = size; + } + + // Call to start the USB port, at given baud. For many applications + // the default parameters are just fine (which will cause messages for all + // MIDI channels to be delivered) + void begin(unsigned int channel = 0); + //void begin(); + void end(); + + uint32 available(void); + + uint32 readPackets(void *buf, uint32 len); + uint32 readPacket(void); + + void writePacket(uint32); +// void write(const char *str); + void writePackets(const void*, uint32); + + uint8 isConnected(); + uint8 pending(); + + // poll() should be called every time through loop() IF dealing with incoming MIDI + // (if you're only SENDING MIDI events from the Arduino, you don't need to call + // poll); it causes data to be read from the USB port and processed. + void poll(); + + // Call these to send MIDI messages of the given types + void sendNoteOff(unsigned int channel, unsigned int note, unsigned int velocity); + void sendNoteOn(unsigned int channel, unsigned int note, unsigned int velocity); + void sendVelocityChange(unsigned int channel, unsigned int note, unsigned int velocity); + void sendControlChange(unsigned int channel, unsigned int controller, unsigned int value); + void sendProgramChange(unsigned int channel, unsigned int program); + void sendAfterTouch(unsigned int channel, unsigned int velocity); + void sendPitchChange(unsigned int channel, unsigned int pitch); + void sendSongPosition(unsigned int position); + void sendSongSelect(unsigned int song); + void sendTuneRequest(void); + void sendSync(void); + void sendStart(void); + void sendContinue(void); + void sendStop(void); + void sendActiveSense(void); + void sendReset(void); + void sendSysex(uint8_t b0, uint8_t b1, uint8_t b2); + void sendSysexEndsIn1(uint8_t b0); + void sendSysexEndsIn2(uint8_t b0, uint8_t b1); + void sendSysexEndsIn3(uint8_t b0, uint8_t b1, uint8_t b2); + void sendSysexPayload(uint8_t *payload, uint32 length); + + + // Overload these in a subclass to get MIDI messages when they come in + virtual void handleNoteOff(unsigned int channel, unsigned int note, unsigned int velocity); + virtual void handleNoteOn(unsigned int channel, unsigned int note, unsigned int velocity); + virtual void handleVelocityChange(unsigned int channel, unsigned int note, unsigned int velocity); + virtual void handleControlChange(unsigned int channel, unsigned int controller, unsigned int value); + virtual void handleProgramChange(unsigned int channel, unsigned int program); + virtual void handleAfterTouch(unsigned int channel, unsigned int velocity); + virtual void handlePitchChange(unsigned int channel, unsigned int pitch); + virtual void handleSongPosition(unsigned int position); + virtual void handleSongSelect(unsigned int song); + virtual void handleTuneRequest(void); + virtual void handleSync(void); + virtual void handleStart(void); + virtual void handleContinue(void); + virtual void handleStop(void); + virtual void handleActiveSense(void); + virtual void handleReset(void); + virtual void handleSysExData(unsigned char data); + virtual void handleSysExEnd(void); + +}; + +extern const uint32 midiNoteFrequency_10ths[128]; + +#endif \ No newline at end of file diff --git a/STM32F1/libraries/USBComposite/USBMassStorage.cpp b/STM32F1/libraries/USBComposite/USBMassStorage.cpp new file mode 100644 index 000000000..a7fa07909 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBMassStorage.cpp @@ -0,0 +1,44 @@ +#include "USBComposite.h" +#include "usb_mass.h" +#include "usb_mass_mal.h" +#include "usb_composite_serial.h" +#include + +void USBMassStorage::begin() { + if(!enabled) { + USBComposite.clear(); + registerComponent(); + USBComposite.begin(); + + enabled = true; + } +} + +void USBMassStorage::end() { + USBComposite.end(); +} + +void USBMassStorage::loop() { + usb_mass_loop(); +} + +bool USBMassStorage::registerComponent() { + return USBComposite.add(&usbMassPart, this); +} + +void USBMassStorage::setDriveData(uint32 driveNumber, uint32 numSectors, MassStorageReader reader, + MassStorageWriter writer, MassStorageStatuser statuser, MassStorageInitializer initializer) { + if (driveNumber >= USB_MASS_MAX_DRIVES) + return; + usb_mass_drives[driveNumber].blockCount = numSectors; + usb_mass_drives[driveNumber].read = reader; + usb_mass_drives[driveNumber].write = writer; + usb_mass_drives[driveNumber].status = statuser; + usb_mass_drives[driveNumber].init = initializer; + usb_mass_drives[driveNumber].format = initializer; +} + +void USBMassStorage::clearDrives() { + memset(usb_mass_drives, 0, sizeof(usb_mass_drives)); +} + diff --git a/STM32F1/libraries/USBComposite/USBMassStorage.h b/STM32F1/libraries/USBComposite/USBMassStorage.h new file mode 100644 index 000000000..3fb1817db --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBMassStorage.h @@ -0,0 +1,23 @@ +#ifndef USBMASSSTORAGE_H +#define USBMASSSTORAGE_H + +#include +#include "USBComposite.h" +#include "usb_generic.h" +#include "usb_mass_mal.h" + +class USBMassStorage { +private: + bool enabled = false; +public: + void begin(); + void end(); + void loop(); + void clearDrives(void); + bool registerComponent(); + void setDriveData(uint32 driveNumber, uint32 numSectors, MassStorageReader reader, + MassStorageWriter writer = NULL, MassStorageStatuser = NULL, MassStorageInitializer = NULL); +}; + +#endif /* USBMASSSTORAGE_H */ + diff --git a/STM32F1/libraries/USBComposite/USBMultiSerial.cpp b/STM32F1/libraries/USBComposite/USBMultiSerial.cpp new file mode 100644 index 000000000..ab429a106 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBMultiSerial.cpp @@ -0,0 +1,235 @@ +/* Copyright (c) 2011, Peter Barrett and 2019, Alexander Pruss +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "USBComposite.h" + +#include +#include +#include +#include +#include +#include + +#include "usb_composite_serial.h" + +size_t USBSerialPort::write(uint8 ch) { +size_t n = 0; + this->write(&ch, 1); + return n; +} + +size_t USBSerialPort::write(const char *str) { +size_t n = 0; + this->write((const uint8*)str, strlen(str)); + return n; +} + +size_t USBSerialPort::write(const uint8 *buf, uint32 len) +{ + size_t n = 0; + + if (!this->isConnected() || !buf) { + return 0; + } + + uint32 txed = 0; + while (txed < len) { + txed += multi_serial_tx(port, (const uint8*)buf + txed, len - txed); + } + + return n; +} + +int USBSerialPort::available(void) { + return multi_serial_data_available(port); +} + +int USBSerialPort::peek(void) +{ + uint8 b; + if (multi_serial_peek(port, &b, 1)==1) + { + return b; + } + else + { + return -1; + } +} + +void USBSerialPort::flush(void) +{ +/*Roger Clark. Rather slow method. Need to improve this */ + uint8 b; + while(multi_serial_data_available(port)) + { + this->read(&b, 1); + } + return; +} + +uint32 USBSerialPort::read(uint8 * buf, uint32 len) { + uint32 rxed = 0; + while (rxed < len) { + rxed += multi_serial_rx(port, buf + rxed, len - rxed); + } + + return rxed; +} + +/* Blocks forever until 1 byte is received */ +int USBSerialPort::read(void) { + uint8 b; + /* + this->read(&b, 1); + return b; + */ + + if (multi_serial_rx(port, &b, 1)==0) + { + return -1; + } + else + { + return b; + } +} + +uint8 USBSerialPort::pending(void) { + return multi_serial_get_pending(port); +} + +uint8 USBSerialPort::isConnected(void) { + return usb_is_connected(USBLIB) && usb_is_configured(USBLIB) && multi_serial_get_dtr(port); +} + +uint8 USBSerialPort::getDTR(void) { + return multi_serial_get_dtr(port); +} + +uint8 USBSerialPort::getRTS(void) { + return multi_serial_get_rts(port); +} + +#if defined(SERIAL_USB) +enum reset_state_t { + DTR_UNSET, + DTR_HIGH, + DTR_NEGEDGE, + DTR_LOW +}; + +static reset_state_t reset_state = DTR_UNSET; + +void usb_multi_serial_ifaceSetupHook0(unsigned hook, void *requestvp) { + (void)hook; + const uint8 port = 0; + uint8 request = *(uint8*)requestvp; + + // Ignore requests we're not interested in. + if (request != USBHID_CDCACM_SET_CONTROL_LINE_STATE) { + return; + } + + // We need to see a negative edge on DTR before we start looking + // for the in-band magic reset byte sequence. + uint8 dtr = multi_serial_get_dtr(port); + switch (reset_state) { + case DTR_UNSET: + reset_state = dtr ? DTR_HIGH : DTR_LOW; + break; + case DTR_HIGH: + reset_state = dtr ? DTR_HIGH : DTR_NEGEDGE; + break; + case DTR_NEGEDGE: + reset_state = dtr ? DTR_HIGH : DTR_LOW; + break; + case DTR_LOW: + reset_state = dtr ? DTR_HIGH : DTR_LOW; + break; + } + + if ((multi_serial_get_baud(port) == 1200) && (reset_state == DTR_NEGEDGE)) { + iwdg_init(IWDG_PRE_4, 10); + while (1); + } +} + + +#define RESET_DELAY 100000 +static void wait_reset(void) { + delay_us(RESET_DELAY); + nvic_sys_reset(); +} + +#define STACK_TOP 0x20000800 +#define EXC_RETURN 0xFFFFFFF9 +#define DEFAULT_CPSR 0x61000000 +void usb_multi_serial_rxHook0(unsigned hook, void *ignored) { + (void)hook; + (void)ignored; + const uint8 port = 0; + /* FIXME this is mad buggy; we need a new reset sequence. E.g. NAK + * after each RX means you can't reset if any bytes are waiting. */ + if (reset_state == DTR_NEGEDGE) { + reset_state = DTR_LOW; + + if (multi_serial_data_available(port) >= 4) { + // The magic reset sequence is "1EAF". + static const uint8 magic[4] = {'1', 'E', 'A', 'F'}; + + uint8 chkBuf[4]; + + // Peek at the waiting bytes, looking for reset sequence, + // bailing on mismatch. + multi_serial_peek_ex(port, chkBuf, multi_serial_data_available(port) - 4, 4); + for (unsigned i = 0; i < sizeof(magic); i++) { + if (chkBuf[i] != magic[i]) { + return; + } + } + + // Got the magic sequence -> reset, presumably into the bootloader. + // Return address is wait_reset, but we must set the thumb bit. + uintptr_t target = (uintptr_t)wait_reset | 0x1; + asm volatile("mov r0, %[stack_top] \n\t" // Reset stack + "mov sp, r0 \n\t" + "mov r0, #1 \n\t" + "mov r1, %[target_addr] \n\t" + "mov r2, %[cpsr] \n\t" + "push {r2} \n\t" // Fake xPSR + "push {r1} \n\t" // PC target addr + "push {r0} \n\t" // Fake LR + "push {r0} \n\t" // Fake R12 + "push {r0} \n\t" // Fake R3 + "push {r0} \n\t" // Fake R2 + "push {r0} \n\t" // Fake R1 + "push {r0} \n\t" // Fake R0 + "mov lr, %[exc_return] \n\t" + "bx lr" + : + : [stack_top] "r" (STACK_TOP), + [target_addr] "r" (target), + [exc_return] "r" (EXC_RETURN), + [cpsr] "r" (DEFAULT_CPSR) + : "r0", "r1", "r2"); + + /* Can't happen. */ + ASSERT_FAULT(0); + } + } +} +#endif diff --git a/STM32F1/libraries/USBComposite/USBMultiSerial.h b/STM32F1/libraries/USBComposite/USBMultiSerial.h new file mode 100755 index 000000000..134663ada --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBMultiSerial.h @@ -0,0 +1,104 @@ +#ifndef _MULTI_SERIAL_H_ +#define _MULTI_SERIAL_H_ + +#include +#include "usb_multi_serial.h" + +#if defined(SERIAL_USB) +void usb_multi_serial_rxHook0(unsigned, void*); +void usb_multi_serial_ifaceSetupHook0(unsigned, void*); +#endif + +class USBSerialPort : public Stream { +public: + uint32 txPacketSize = USB_MULTI_SERIAL_DEFAULT_TX_SIZE; + uint32 rxPacketSize = USB_MULTI_SERIAL_DEFAULT_RX_SIZE; + uint32 port; + virtual int available(void);// Changed to virtual + + uint32 read(uint8 * buf, uint32 len); + // uint8 read(void); + + // Roger Clark. added functions to support Arduino 1.0 API + virtual int peek(void); + virtual int read(void); + int availableForWrite(void); + virtual void flush(void); + + size_t write(uint8); + size_t write(const char *str); + size_t write(const uint8*, uint32); + + uint8 getRTS(); + uint8 getDTR(); + uint8 isConnected(); + uint8 pending(); + + void setRXPacketSize(uint32 size=USB_MULTI_SERIAL_DEFAULT_RX_SIZE) { + rxPacketSize = size; + } + + void setTXPacketSize(uint32 size=USB_MULTI_SERIAL_DEFAULT_TX_SIZE) { + txPacketSize = size; + } + + void setPort(uint8 _port) { + port = _port; + } + + uint8 getPort(void) { + return port; + } +}; + +templateclass USBMultiSerial { +private: + bool enabled = false; + uint8 buffers[USB_MULTI_SERIAL_BUFFERS_SIZE(numPorts)]; +public: + bool begin() { + if (!enabled) { + USBComposite.clear(); + if (!registerComponent()) + return false; + USBComposite.begin(); + enabled = true; + } + return true; + }; + + void end() { + if (enabled) { + USBComposite.end(); + enabled = false; + } + } + + bool registerComponent() { + return USBComposite.add(&usbMultiSerialPart, this, (USBPartInitializer)&USBMultiSerial::init); + } + + static bool init(USBMultiSerial* me) { + for (uint8 i=0; ibuffers); +#if defined(SERIAL_USB) + multi_serial_set_hooks(0, USBHID_CDCACM_HOOK_RX, usb_multi_serial_rxHook0); + multi_serial_set_hooks(0, USBHID_CDCACM_HOOK_IFACE_SETUP, usb_multi_serial_ifaceSetupHook0); +#endif + return true; + }; + + operator bool() { return USBComposite.isReady(); } + + USBSerialPort ports[numPorts]; + + USBMultiSerial() { + for (uint32 i=0;i +#include "USBComposite.h" + +void USBXBox360Controller::send(void){ + sendData((uint8*)&report, sizeof(report)); +} + +uint16_t USBXBox360Controller::getReportSize(void){ + return sizeof(report); +} + +uint8_t* USBXBox360Controller::getReport(void){ + return (uint8_t*)&report; +} + +void USBXBox360Controller::setRumbleCallback(void (*callback)(uint8 left, uint8 right)) { + x360_set_rumble_callback(controller,callback); +} + +void USBXBox360Controller::setLEDCallback(void (*callback)(uint8 pattern)) { + x360_set_led_callback(controller, callback); +} + +void USBXBox360Controller::stop(void){ + setRumbleCallback(NULL); + setLEDCallback(NULL); +} + +void USBXBox360Controller::safeSendReport() { + if (!manualReport) + send(); +} + +void USBXBox360Controller::button(uint8_t button, bool val){ + uint16_t mask = (1 << (button-1)); + if (val) { + report.buttons |= mask; + } else { + report.buttons &= ~mask; + } + + safeSendReport(); +} + +void USBXBox360Controller::buttons(uint16_t buttons){ + report.buttons = buttons; + + safeSendReport(); +} + +void USBXBox360Controller::X(int16_t val){ + report.x = val; + + safeSendReport(); +} + +void USBXBox360Controller::Y(int16_t val){ + report.y = val; + + safeSendReport(); +} + +void USBXBox360Controller::XRight(int16_t val){ + report.rx = val; + + safeSendReport(); +} + +void USBXBox360Controller::YRight(int16_t val){ + report.ry = val; + + safeSendReport(); +} + +void USBXBox360Controller::position(int16_t x, int16_t y){ + report.x = x; + report.y = y; + + safeSendReport(); +} + +void USBXBox360Controller::positionRight(int16_t x, int16_t y){ + report.rx = x; + report.ry = y; + + safeSendReport(); +} + +void USBXBox360Controller::sliderLeft(uint8_t val){ + report.sliderLeft = val; + + safeSendReport(); +} + +void USBXBox360Controller::sliderRight(uint8_t val){ + report.sliderRight = val; + + safeSendReport(); +} + diff --git a/STM32F1/libraries/USBComposite/USBMultiXBox360.h b/STM32F1/libraries/USBComposite/USBMultiXBox360.h new file mode 100644 index 000000000..317a9e184 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBMultiXBox360.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#ifndef _USBMultiXBox360_H +#define _USBMultiXBox360_H + +#include +#include +#include "USBComposite.h" +#include "USBXBox360W.h" +#include "usb_generic.h" +#include "usb_x360_generic.h" +#include "usb_multi_x360.h" + + +#define XBOX_A 13 +#define XBOX_B 14 +#define XBOX_X 15 +#define XBOX_Y 16 +#define XBOX_DUP 1 +#define XBOX_DDOWN 2 +#define XBOX_DLEFT 3 +#define XBOX_DRIGHT 4 +#define XBOX_START 5 +#define XBOX_BACK 6 +#define XBOX_L3 7 +#define XBOX_R3 8 +#define XBOX_LSHOULDER 9 +#define XBOX_RSHOULDER 10 +#define XBOX_GUIDE 11 + +#endif diff --git a/STM32F1/libraries/USBComposite/USBXBox360.h b/STM32F1/libraries/USBComposite/USBXBox360.h new file mode 100644 index 000000000..13d7506f7 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBXBox360.h @@ -0,0 +1,277 @@ +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#ifndef _USBXBox360_H +#define _USBXBox360_H + +#include +#include +#include "USBComposite.h" +#include "usb_generic.h" +#include "usb_x360_generic.h" +#include "usb_x360w.h" +#include "usb_multi_x360.h" + +typedef struct { + uint8_t header[4]; + uint8_t reportID; + uint8_t length; + uint16_t buttons; + uint8_t sliderLeft; + uint8_t sliderRight; + int16_t x; + int16_t y; + int16_t rx; + int16_t ry; + uint8 unused[11]; +} __packed XBox360WReport_t; + +static_assert(sizeof(XBox360WReport_t)==29, "Wrong endianness/packing!"); + +class USBXBox360Reporter { +protected: + uint32 controller; + bool wait(void); +public: + bool manualReport = false; + void setController(uint32 c) { + controller = c; + } + void setManualReportMode(bool manualReport); + bool getManualReportMode(); + bool sendData(const void* data, uint32 length); + + USBXBox360Reporter(uint32 _controller=0) { + controller = _controller; + } +}; + +class USBXBox360WController : public USBXBox360Reporter { +private: + XBox360WReport_t report = {{0},0,19,0,0,0,0,0,0,0,{0}}; + void safeSendReport(void); + bool connected = false; +public: + bool connect(bool state); + bool isConnected(void) { + return connected; + } + void send(void); + uint8* getReport(void); + uint16_t getReportSize(void); + void stop(void); + void button(uint8_t button, bool val); + void buttons(uint16_t b); + void X(int16_t val); + void Y(int16_t val); + void position(int16_t x, int16_t y); + void positionRight(int16_t x, int16_t y); + void XRight(int16_t val); + void YRight(int16_t val); + void sliderLeft(uint8_t val); + void sliderRight(uint8_t val); + void setLEDCallback(void (*callback)(uint8 pattern)); + void setRumbleCallback(void (*callback)(uint8 left, uint8 right)); + + USBXBox360WController(uint32 _controller=0) : USBXBox360Reporter(_controller) { + } +}; + +templateclass USBXBox360W { +private: + bool enabled = false; + uint8 buffers[USB_X360_BUFFER_SIZE_PER_CONTROLLER * numControllers]; + uint16 vendorId; + uint16 productId; + +public: + static bool init(USBXBox360W* me) { + x360w_initialize_controller_data(numControllers, me->buffers); + USBComposite.setVendorId(me->vendorId); + USBComposite.setProductId(me->productId); + + return true; + }; + + bool registerComponent() { + return USBComposite.add(&usbX360Part, this, (USBPartInitializer)&USBXBox360W::init); + }; + + void begin(void){ + if(!enabled){ + USBComposite.clear(); + registerComponent(); + USBComposite.begin(); + + enabled = true; + } + }; + + void end() { + if (enabled) { + enabled = false; + USBComposite.end(); + } + }; + + USBXBox360WController controllers[numControllers]; + + USBXBox360W(uint16 _vendorId=0x045e, uint16 _productId=0x0719) : vendorId(_vendorId), productId(_productId) { + for (uint8 i=0;iclass USBMultiXBox360 { +private: + bool enabled = false; + uint8 buffers[USB_X360_BUFFER_SIZE_PER_CONTROLLER * numControllers]; + uint16 vendorId; + uint16 productId; + +public: + static bool init(USBMultiXBox360* me) { + usb_multi_x360_initialize_controller_data(numControllers, me->buffers); + USBComposite.setVendorId(me->vendorId); + USBComposite.setProductId(me->productId); + return true; + }; + + bool registerComponent() { + return USBComposite.add(&usbX360Part, this, (USBPartInitializer)&USBMultiXBox360::init); + }; + + void begin(void){ + if(!enabled){ + USBComposite.clear(); + registerComponent(); + USBComposite.begin(); + + enabled = true; + } + }; + + void end() { + if (enabled) { + enabled = false; + USBComposite.end(); + } + }; + + USBXBox360Controller controllers[numControllers]; + + USBMultiXBox360(uint16 _vendorId=0x045e, uint16 _productId=0x028e) : vendorId(_vendorId), productId(_productId) { + for (uint8 i=0;ibuffers); + USBComposite.setVendorId(me->vendorId); + USBComposite.setProductId(me->productId); + return true; + }; + + bool registerComponent() { + return USBComposite.add(&usbX360Part, this, (USBPartInitializer)&USBXBox360::init); + }; + + void begin(void){ + if(!enabled){ + USBComposite.clear(); + registerComponent(); + USBComposite.begin(); + + enabled = true; + } + }; + + void end() { + if (enabled) { + enabled = false; + USBComposite.end(); + } + }; + + USBXBox360(uint16 _vendorId=0x045e, uint16 _productId=0x028e) : USBXBox360Controller(0), vendorId(_vendorId), productId(_productId) { + } +}; + +#define XBOX_A 13 +#define XBOX_B 14 +#define XBOX_X 15 +#define XBOX_Y 16 +#define XBOX_DUP 1 +#define XBOX_DDOWN 2 +#define XBOX_DLEFT 3 +#define XBOX_DRIGHT 4 +#define XBOX_START 5 +#define XBOX_BACK 6 +#define XBOX_L3 7 +#define XBOX_R3 8 +#define XBOX_LSHOULDER 9 +#define XBOX_RSHOULDER 10 +#define XBOX_GUIDE 11 + +#endif diff --git a/STM32F1/libraries/USBComposite/USBXBox360Reporter.cpp b/STM32F1/libraries/USBComposite/USBXBox360Reporter.cpp new file mode 100644 index 000000000..e0751b873 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBXBox360Reporter.cpp @@ -0,0 +1,46 @@ +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include +#include "USBComposite.h" + +bool USBXBox360Reporter::wait() { + uint32_t t=millis(); + while (x360_is_transmitting(controller) != 0 && (millis()-t)<500) ; + return ! x360_is_transmitting(controller); +} + +bool USBXBox360Reporter::sendData(const void* data, uint32 length){ + if (wait()) { + x360_tx(controller, (uint8*)data, length); + + if(wait()) { + /* flush out to avoid having the pc wait for more data */ + x360_tx(controller, NULL, 0); + } + return true; + } + return false; +} + +void USBXBox360Reporter::setManualReportMode(bool mode) { + manualReport = mode; +} + +bool USBXBox360Reporter::getManualReportMode() { + return manualReport; +} + diff --git a/STM32F1/libraries/USBComposite/USBXBox360W.cpp b/STM32F1/libraries/USBComposite/USBXBox360W.cpp new file mode 100644 index 000000000..b5fbb2912 --- /dev/null +++ b/STM32F1/libraries/USBComposite/USBXBox360W.cpp @@ -0,0 +1,139 @@ +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include +#include "USBComposite.h" + +void USBXBox360WController::send(void){ + if (!connected) + connect(true); + report.header[0] = 0x00; + report.header[1] = 0x01; + report.header[2] = 0x00; + report.header[3] = 0xf0; + sendData(&report, sizeof(report)); +} + +uint16_t USBXBox360WController::getReportSize(void){ + return sizeof(report); +} + +uint8_t* USBXBox360WController::getReport(void){ + return (uint8_t*)&report; +} + + +const uint8 startup[] = {0x00,0x0F,0x00,0xF0,0xF0,0xCC,0x42,0xAF,0x3C,0x60,0xAC,0x24,0xFB,0x50,0x00,0x05,0x13,0xE7,0x20,0x1D,0x30,0x03,0x40,0x01,0x50,0x01,0xFF,0xFF,0xFF }; + +bool USBXBox360WController::connect(bool state) { +// delay(250); + report.header[0] = 0x08; + report.header[1] = state ? 0x80 : 0x00; + if (!sendData(&report.header, 2)) + return false; +// delay(250); + if (state && !sendData(startup, 29)) + return false; +// delay(250); + connected = state; + return true; +} + +void USBXBox360WController::setRumbleCallback(void (*callback)(uint8 left, uint8 right)) { + x360_set_rumble_callback(controller,callback); +} + +void USBXBox360WController::setLEDCallback(void (*callback)(uint8 pattern)) { + x360_set_led_callback(controller, callback); +} + +void USBXBox360WController::stop(void){ + setRumbleCallback(NULL); + setLEDCallback(NULL); +} + +void USBXBox360WController::safeSendReport() { + if (!manualReport) + send(); +} + +void USBXBox360WController::button(uint8_t button, bool val){ + uint16_t mask = (1 << (button-1)); + if (val) { + report.buttons |= mask; + } else { + report.buttons &= ~mask; + } + + safeSendReport(); +} + +void USBXBox360WController::buttons(uint16_t buttons){ + report.buttons = buttons; + + safeSendReport(); +} + +void USBXBox360WController::X(int16_t val){ + report.x = val; + + safeSendReport(); +} + +void USBXBox360WController::Y(int16_t val){ + report.y = val; + + safeSendReport(); +} + +void USBXBox360WController::XRight(int16_t val){ + report.rx = val; + + safeSendReport(); +} + +void USBXBox360WController::YRight(int16_t val){ + report.ry = val; + + safeSendReport(); +} + +void USBXBox360WController::position(int16_t x, int16_t y){ + report.x = x; + report.y = y; + + safeSendReport(); +} + +void USBXBox360WController::positionRight(int16_t x, int16_t y){ + report.rx = x; + report.ry = y; + + safeSendReport(); +} + +void USBXBox360WController::sliderLeft(uint8_t val){ + report.sliderLeft = val; + + safeSendReport(); +} + +void USBXBox360WController::sliderRight(uint8_t val){ + report.sliderRight = val; + + safeSendReport(); +} + diff --git a/STM32F1/libraries/USBComposite/examples/BootKeyboard/BootKeyboard.ino b/STM32F1/libraries/USBComposite/examples/BootKeyboard/BootKeyboard.ino new file mode 100644 index 000000000..b8e0f876a --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/BootKeyboard/BootKeyboard.ino @@ -0,0 +1,18 @@ +#include + +USBHID HID; +HIDKeyboard BootKeyboard(HID, 0); + +void setup() +{ + HID.begin(HID_BOOT_KEYBOARD); + BootKeyboard.begin(); // needed just in case you need LED support +} + +void loop() +{ + BootKeyboard.press(KEY_F12); + delay(100); + BootKeyboard.release(KEY_F12); + delay(1000); +} diff --git a/STM32F1/libraries/USBComposite/examples/ConsumerAndKeyboard/ConsumerAndKeyboard.ino b/STM32F1/libraries/USBComposite/examples/ConsumerAndKeyboard/ConsumerAndKeyboard.ino new file mode 100755 index 000000000..327541597 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/ConsumerAndKeyboard/ConsumerAndKeyboard.ino @@ -0,0 +1,28 @@ +#include + +USBHID HID; + +const uint8_t reportDescription[] = { + HID_CONSUMER_REPORT_DESCRIPTOR(), + HID_KEYBOARD_REPORT_DESCRIPTOR() +}; + +HIDConsumer Consumer(HID); +HIDKeyboard Keyboard(HID); + +void setup(){ + HID.begin(reportDescription, sizeof(reportDescription)); +} + +void loop() { + Consumer.press(HIDConsumer::BRIGHTNESS_DOWN); + Consumer.release(); + delay(500); + Consumer.press(HIDConsumer::BRIGHTNESS_DOWN); + Consumer.release(); + delay(500); + Keyboard.press(KEY_RIGHT_ARROW); + Keyboard.release(KEY_RIGHT_ARROW); + delay(500); +} + diff --git a/STM32F1/libraries/USBComposite/examples/MidiPotentiometer/MidiPotentiometer.ino b/STM32F1/libraries/USBComposite/examples/MidiPotentiometer/MidiPotentiometer.ino new file mode 100644 index 000000000..4e2abd047 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/MidiPotentiometer/MidiPotentiometer.ino @@ -0,0 +1,39 @@ +#include + +USBMIDI midi; +const uint8 pot_pin = 6; +const uint8 threshold = 1; + +const unsigned int midi_channel = + 1; // this might show up as channel 1 depending on start index +const unsigned int cc_command = 0; // bank select command + +unsigned int old_value = 0; +unsigned int new_value = 0; + +void setup() { + + // product id taken from library example + USBComposite.setProductId(0x0031); + pinMode(pot_pin, INPUT); + midi.begin(); + delay(1000); +} + +void loop() { + + int temp = analogRead(pot_pin); // a value between 0-4095 + new_value = temp / 32; // convert to a value between 0-127 + + // If difference between new_value and old_value is grater than threshold + if ((new_value > old_value && new_value - old_value > threshold) || + (new_value < old_value && old_value - new_value > threshold)) { + + midi.sendControlChange(midi_channel, cc_command, new_value); + + // Update old_value + old_value = new_value; + } + // Wait 50ms before reading the pin again + delay(50); +} diff --git a/STM32F1/libraries/USBComposite/examples/NintendoSwitch/NintendoSwitch.ino b/STM32F1/libraries/USBComposite/examples/NintendoSwitch/NintendoSwitch.ino new file mode 100755 index 000000000..97b387751 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/NintendoSwitch/NintendoSwitch.ino @@ -0,0 +1,31 @@ +#include + +USBHID HID; +HIDSwitchController controller(HID); + +void setup() { + controller.begin(); + while (!USBComposite); + delay(1000); +} + +void loop() { + controller.X(16); + controller.send(); + delay(300); + controller.X(255-16); + controller.send(); + delay(300); + controller.X(128); + controller.send(); + delay(300); + /* + for (int i=0; i<=0; i++) { + controller.button(i,true); + controller.sendReport(); + delay(100); + controller.button(i,false); + controller.sendReport(); + delay(100); + } */ +} diff --git a/STM32F1/libraries/USBComposite/examples/SignedJoystick/SignedJoystick.ino b/STM32F1/libraries/USBComposite/examples/SignedJoystick/SignedJoystick.ino new file mode 100755 index 000000000..5d5cf0b39 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/SignedJoystick/SignedJoystick.ino @@ -0,0 +1,113 @@ +#include + +#define HID_SIGNED_JOYSTICK_REPORT_DESCRIPTOR(...) \ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ \ + 0x09, 0x04, /* Usage (Joystick) */ \ + 0xA1, 0x01, /* Collection (Application) */ \ + 0x85, MACRO_GET_ARGUMENT_1_WITH_DEFAULT(HID_JOYSTICK_REPORT_ID, ## __VA_ARGS__), /* REPORT_ID */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x25, 0x01, /* Logical Maximum (1) */ \ + 0x75, 0x01, /* Report Size (1) */ \ + 0x95, 0x20, /* Report Count (32) */ \ + 0x05, 0x09, /* Usage Page (Button) */ \ + 0x19, 0x01, /* Usage Minimum (Button #1) */ \ + 0x29, 0x20, /* Usage Maximum (Button #32) */ \ + 0x81, 0x02, /* Input (variable,absolute) */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x25, 0x07, /* Logical Maximum (7) */ \ + 0x35, 0x00, /* Physical Minimum (0) */ \ + 0x46, 0x3B, 0x01, /* Physical Maximum (315) */ \ + 0x75, 0x04, /* Report Size (4) */ \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x65, 0x14, /* Unit (20) */ \ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ \ + 0x09, 0x39, /* Usage (Hat switch) */ \ + 0x81, 0x42, /* Input (variable,absolute,null_state) */ \ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ \ + 0x09, 0x01, /* Usage (Pointer) */ \ + 0xA1, 0x00, /* Collection () */ \ + 0x16, 0x00, 0xFC, /* Logical Minimum (-1024) */ \ + 0x26, 0xFF, 0x03, /* Logical Maximum (1023) */ \ + 0x75, 0x0B, /* Report Size (11) */ \ + 0x95, 0x04, /* Report Count (4) */ \ + 0x09, 0x30, /* Usage (X) */ \ + 0x09, 0x31, /* Usage (Y) */ \ + 0x09, 0x33, /* Usage (Rx) */ \ + 0x09, 0x34, /* Usage (Ry) */ \ + 0x81, 0x02, /* Input (variable,absolute) */ \ + 0xC0, /* End Collection */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x26, 0xFF, 0x03, /* Logical Maximum (1023) */ \ + 0x75, 0x0A, /* Report Size (10) */ \ + 0x95, 0x02, /* Report Count (2) */ \ + 0x09, 0x36, /* Usage (Slider) */ \ + 0x09, 0x36, /* Usage (Slider) */ \ + 0x81, 0x02, /* Input (variable,absolute) */ \ + 0x75, 0x04, /* REPORT_SIZE (4) */ \ + 0x95, 0x01, /* REPORT_COUNT (1) */ \ + 0x81, 0x03, /* OUTPUT (Cnst,Var,Abs) */ \ + MACRO_ARGUMENT_2_TO_END(__VA_ARGS__) \ + 0xC0 + +typedef struct { + uint8_t reportID; + uint32_t buttons; + unsigned hat:4; + int x:11; + int y:11; + int rx:11; + int ry:11; + unsigned sliderLeft:10; + unsigned sliderRight:10; + unsigned unused:4; +} __packed SignedJoystickReport_t; + +class HIDSignedJoystick : public HIDReporter { +public: + SignedJoystickReport_t joyReport; + void begin(void) {}; + void end(void) {}; + HIDSignedJoystick(USBHID& HID, uint8_t reportID=HID_JOYSTICK_REPORT_ID) + : HIDReporter(HID, NULL, (uint8_t*)&joyReport, sizeof(joyReport), reportID) { + joyReport.buttons = 0; + joyReport.hat = 15; + joyReport.x = 0; + joyReport.y = 0; + joyReport.rx = 0; + joyReport.ry = 0; + joyReport.sliderLeft = 0; + joyReport.sliderRight = 0; + } +}; + +USBHID HID; +HIDSignedJoystick joy(HID); + +uint8 signedJoyReportDescriptor[] = { + HID_SIGNED_JOYSTICK_REPORT_DESCRIPTOR() +}; + +void setup() { + HID.setReportDescriptor(signedJoyReportDescriptor, sizeof(signedJoyReportDescriptor)); + HID.registerComponent(); + USBComposite.begin(); + while (!USBComposite); +} + +void loop() { + joy.joyReport.buttons = 1 | 2; + joy.joyReport.x = -1024; + joy.joyReport.y = -1024; + joy.joyReport.rx = -1024; + joy.joyReport.ry = -1024; + joy.sendReport(); + delay(500); + joy.joyReport.buttons = 0; + joy.joyReport.x = 1023; + joy.joyReport.y = 1023; + joy.joyReport.rx = 1023; + joy.joyReport.ry = 1023; + joy.sendReport(); + delay(500); +} + diff --git a/STM32F1/libraries/USBComposite/examples/absmouse/absmouse.ino b/STM32F1/libraries/USBComposite/examples/absmouse/absmouse.ino new file mode 100644 index 000000000..6f68a151c --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/absmouse/absmouse.ino @@ -0,0 +1,26 @@ +#include + +const uint8_t reportDescription[] = { + HID_ABS_MOUSE_REPORT_DESCRIPTOR(HID_MOUSE_REPORT_ID) +}; + +USBHID HID; +HIDAbsMouse mouse(HID); + +void setup(){ + HID.begin(reportDescription, sizeof(reportDescription)); + while (!USBComposite); + mouse.move(0,0); + delay(1000); + mouse.press(MOUSE_LEFT); + mouse.move(500,500); + mouse.release(MOUSE_ALL); + mouse.click(MOUSE_RIGHT); +} + +void loop(){ + mouse.move(0,0); + delay(1000); + mouse.move(16384,16384); + delay(1000); +} diff --git a/STM32F1/libraries/USBComposite/examples/consumer/consumer.ino b/STM32F1/libraries/USBComposite/examples/consumer/consumer.ino new file mode 100644 index 000000000..cd49e7719 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/consumer/consumer.ino @@ -0,0 +1,20 @@ +#include + +USBHID HID; + +const uint8_t reportDescription[] = { + HID_CONSUMER_REPORT_DESCRIPTOR() +}; + +HIDConsumer Consumer(HID); + +void setup(){ + HID.begin(reportDescription, sizeof(reportDescription)); +} + +void loop() { + Consumer.press(HIDConsumer::BRIGHTNESS_DOWN); + Consumer.release(); + delay(500); +} + diff --git a/STM32F1/libraries/USBComposite/examples/digitizer/digitizer.ino b/STM32F1/libraries/USBComposite/examples/digitizer/digitizer.ino new file mode 100755 index 000000000..b427969e7 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/digitizer/digitizer.ino @@ -0,0 +1,20 @@ +#include + +USBHID HID; +HIDDigitizer digitizer(HID); + +void setup(){ + HID.begin(); + while (!USBComposite); + digitizer.move(0,0); + delay(1000); +} + +void loop(){ + digitizer.move(2000,3000); + digitizer.press(DIGITIZER_TOUCH_IN_RANGE); + delay(1000); + digitizer.move(4000,4000); + digitizer.release(DIGITIZER_TOUCH_IN_RANGE); + delay(1000); +} diff --git a/STM32F1/libraries/USBComposite/examples/jigglemouse/jigglemouse.ino b/STM32F1/libraries/USBComposite/examples/jigglemouse/jigglemouse.ino new file mode 100755 index 000000000..13d53020b --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/jigglemouse/jigglemouse.ino @@ -0,0 +1,26 @@ +#include + +#define LED PB12 + +USBHID HID; +HIDMouse Mouse(HID); + +void setup(){ + pinMode(LED,OUTPUT); + digitalWrite(LED,1); + HID.begin(HID_MOUSE); + delay(1000); +} + +void loop(){ + digitalWrite(LED,0); + Mouse.move(4,0); + delay(500); + digitalWrite(LED,1); + delay(30000); + digitalWrite(LED,0); + Mouse.move(-4,0); + delay(500); + digitalWrite(LED,1); + delay(30000); +} diff --git a/STM32F1/libraries/USBComposite/examples/keyboardMouse/keyboardMouse.ino b/STM32F1/libraries/USBComposite/examples/keyboardMouse/keyboardMouse.ino new file mode 100644 index 000000000..0fc429a8a --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/keyboardMouse/keyboardMouse.ino @@ -0,0 +1,41 @@ +#include +/* + * This example types which cardinal direction the mouse will be moved + * and then moves the mouse in that direction. If the mouse doesn't recenter + * at the end, it is probably due to mouse acceleration + */ + +USBHID HID; +HIDKeyboard Keyboard(HID); +HIDMouse Mouse(HID); + +void setup() { + HID.begin(HID_KEYBOARD_MOUSE); + while(!USBComposite); +} + +void loop() { + Keyboard.println("UP"); + Mouse.move(0,-127); + delay(1500); + + Keyboard.println("DOWN"); + Mouse.move(0,127); + Mouse.move(0,127); //Movement cannot be greater than a byte + delay(1500); + + Keyboard.println("LEFT"); + Mouse.move(-127,-127); + delay(1500); + + Keyboard.println("RIGHT"); + Mouse.move(127,0); + Mouse.move(127,0); //Movement cannot be greater than a byte + delay(1500); + + Keyboard.println("CENTER"); + Mouse.move(-127,0); + delay(500); + + delay(5000); +} diff --git a/STM32F1/libraries/USBComposite/examples/keyboardwithleds/keyboardwithleds.ino b/STM32F1/libraries/USBComposite/examples/keyboardwithleds/keyboardwithleds.ino new file mode 100644 index 000000000..5d668b626 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/keyboardwithleds/keyboardwithleds.ino @@ -0,0 +1,17 @@ +#include + +USBHID HID; +HIDKeyboard Keyboard(HID); +USBCompositeSerial CompositeSerial; + +void setup() { + HID.begin(CompositeSerial, HID_KEYBOARD); + while (!USBComposite); + Keyboard.begin(); // needed for LED support +} + +void loop() { + CompositeSerial.println(Keyboard.getLEDs()); +} + + diff --git a/STM32F1/libraries/USBComposite/examples/mass/image.h b/STM32F1/libraries/USBComposite/examples/mass/image.h new file mode 100644 index 000000000..ffa7c13d0 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/mass/image.h @@ -0,0 +1,67 @@ +uint8 image[11776] = { +0xEB,0x3C,0x90,0x6D,0x6B,0x64,0x6F,0x73,0x66,0x73,0x00,0x00,0x02,0x04,0x01,0x00, +0x02,0x10,0x00,0x17,0x00,0xF8,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x29,0xDB,0x32,0x73,0x5A,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x0E,0x1F, +0xBE,0x5B,0x7C,0xAC,0x22,0xC0,0x74,0x0B,0x56,0xB4,0x0E,0xBB,0x07,0x00,0xCD,0x10, +0x5E,0xEB,0xF0,0x32,0xE4,0xCD,0x16,0xCD,0x19,0xEB,0xFE,0x54,0x68,0x69,0x73,0x20, +0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x61,0x20,0x62,0x6F,0x6F,0x74,0x61,0x62,0x6C, +0x65,0x20,0x64,0x69,0x73,0x6B,0x2E,0x20,0x20,0x50,0x6C,0x65,0x61,0x73,0x65,0x20, +0x69,0x6E,0x73,0x65,0x72,0x74,0x20,0x61,0x20,0x62,0x6F,0x6F,0x74,0x61,0x62,0x6C, +0x65,0x20,0x66,0x6C,0x6F,0x70,0x70,0x79,0x20,0x61,0x6E,0x64,0x0D,0x0A,0x70,0x72, +0x65,0x73,0x73,0x20,0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x74, +0x72,0x79,0x20,0x61,0x67,0x61,0x69,0x6E,0x20,0x2E,0x2E,0x2E,0x20,0x0D,0x0A,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xAA, +0xF8,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xF8,0xFF,0xFF, +}; \ No newline at end of file diff --git a/STM32F1/libraries/USBComposite/examples/mass/mass.ino b/STM32F1/libraries/USBComposite/examples/mass/mass.ino new file mode 100644 index 000000000..6862f14cd --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/mass/mass.ino @@ -0,0 +1,70 @@ +#include + +USBMassStorage MassStorage; +USBCompositeSerial CompositeSerial; + +#define PRODUCT_ID 0x29 + +#include "image.h" + +bool write(const uint8_t *writebuff, uint32_t memoryOffset, uint16_t transferLength) { + memcpy(image+SCSI_BLOCK_SIZE*memoryOffset, writebuff, SCSI_BLOCK_SIZE*transferLength); + + return true; +} + +bool read(uint8_t *readbuff, uint32_t memoryOffset, uint16_t transferLength) { + memcpy(readbuff, image+SCSI_BLOCK_SIZE*memoryOffset, SCSI_BLOCK_SIZE*transferLength); + + return true; +} + +char hexNibble(uint8 x) { + return x < 10 ? x + '0' : x + 'A' - 10; +} + +char* format16(uint16 c) { + static char str[6]; + str[5] = 0; + char *p = str+5; + do { + *--p = (c % 10) + '0'; + c /= 10; + } while(c); + return p; +} + +void dumpDrive() { + char hex[7] = "0x11,"; + CompositeSerial.print("uint8 image["); + CompositeSerial.print(format16(sizeof(image))); + CompositeSerial.println("] = {"); + int last; + for (last=sizeof(image)-1;last>=0 && image[last] == 0;last--); + if (last<0) last=0; + + for (int i=0; i<=last; i++) { + if (i && i % 16 == 0) + CompositeSerial.println(""); + hex[2] = hexNibble(image[i]>>4); + hex[3] = hexNibble(image[i]&0xF); + CompositeSerial.print(hex); + } + CompositeSerial.println("\n};\n"); +} + +void setup() { + USBComposite.setProductId(PRODUCT_ID); + MassStorage.setDriveData(0, sizeof(image)/SCSI_BLOCK_SIZE, read, write); + MassStorage.registerComponent(); + CompositeSerial.registerComponent(); + USBComposite.begin(); + delay(2000); +} + +void loop() { + MassStorage.loop(); + if (CompositeSerial.available() && 'd' == CompositeSerial.read()) { + dumpDrive(); + } +} diff --git a/STM32F1/libraries/USBComposite/examples/micadc/micadc.ino b/STM32F1/libraries/USBComposite/examples/micadc/micadc.ino new file mode 100644 index 000000000..8aba2de86 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/micadc/micadc.ino @@ -0,0 +1,61 @@ +#include +#include + +int audio_left_pin = PA0; +int audio_right_pin = PA1; + +uint8 adc_pins[] = {audio_left_pin, audio_right_pin}; + +uint16_t buffer[2]; +uint8 buf[2]; +unsigned long last_audio_read_ms; + +int sample_rate = 24000; + +USBCompositeSerial CompositeSerial; +STM32ADC ADC(ADC1); +USBAUDIO AUDIO; + +void setup() +{ + pinMode(adc_pins[0], INPUT); + pinMode(adc_pins[1], INPUT); + + ADC.calibrate(); + ADC.setSampleRate(ADC_SMPR_1_5); + ADC.setScanMode(); + ADC.setPins(adc_pins, 2); + ADC.setContinuous(); + ADC.setDMA(buffer, 2, (DMA_MINC_MODE | DMA_CIRC_MODE), NULL); + ADC.startConversion(); + + AUDIO.begin(CompositeSerial, MIC_STEREO | AUDIO_CLASS_1, sample_rate); + + last_audio_read_ms = micros(); +} + +void loop() +{ + unsigned long current_micros = micros(); + unsigned long elapsed = current_micros - last_audio_read_ms; + + if (elapsed >= AUDIO.getSamplePeriod()) + { + for (int i = 0; i < 2; i++) + { + /* 255 (uint8 range) / 1279 (ADC range) */ + buf[i] = buffer[i] * 0.2; + } + + while (!AUDIO.write(buf, 2)); + + last_audio_read_ms = current_micros; + } + + /* Echo characters input to serial */ + if (CompositeSerial.available()) + { + char ch = CompositeSerial.read(); + CompositeSerial.println(ch); + } +} \ No newline at end of file diff --git a/STM32F1/libraries/USBComposite/examples/microphone/microphone.ino b/STM32F1/libraries/USBComposite/examples/microphone/microphone.ino new file mode 100644 index 000000000..e7aa9853c --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/microphone/microphone.ino @@ -0,0 +1,33 @@ +#include + +int input_pin = PA0; + +uint8 val; +unsigned long last_audio_read_ms; + +USBAUDIO AUDIO; + +void setup() +{ + pinMode(input_pin, INPUT); + + AUDIO.begin(MIC_MONO); + + last_audio_read_ms = micros(); +} + +void loop() +{ + unsigned long current_micros = micros(); + unsigned long elapsed = current_micros - last_audio_read_ms; + + if (elapsed >= AUDIO.getSamplePeriod()) + { + /* 255 (uint8 range) / 4095 (analogRead range) = ~0.06 */ + val = analogRead(input_pin) * (0.06); + + last_audio_read_ms = current_micros; + + while (!AUDIO.write(&val, 1)); + } +} diff --git a/STM32F1/libraries/USBComposite/examples/micserial/micserial.ino b/STM32F1/libraries/USBComposite/examples/micserial/micserial.ino new file mode 100644 index 000000000..d2785e295 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/micserial/micserial.ino @@ -0,0 +1,46 @@ +#include + +int audio_left_pin = PA0; +int audio_right_pin = PA1; + +uint8 buf[2]; +unsigned long last_audio_read_ms; + +int sample_rate = 24000; + +USBCompositeSerial CompositeSerial; +USBAUDIO AUDIO; + +void setup() +{ + pinMode(audio_left_pin, INPUT); + pinMode(audio_right_pin, INPUT); + + AUDIO.begin(CompositeSerial, MIC_STEREO | AUDIO_CLASS_1, sample_rate); + + last_audio_read_ms = micros(); +} + +void loop() +{ + unsigned long current_micros = micros(); + unsigned long elapsed = current_micros - last_audio_read_ms; + + if (elapsed >= AUDIO.getSamplePeriod()) + { + /* 255 (uint8 range) / 4095 (analogRead range) = ~0.06 */ + buf[1] = analogRead(audio_left_pin) * (0.06); + buf[0] = analogRead(audio_right_pin) * (0.06); + + last_audio_read_ms = current_micros; + + while (!AUDIO.write(buf, 2)); + } + + /* Echo characters input to serial */ + if (CompositeSerial.available()) + { + char ch = CompositeSerial.read(); + CompositeSerial.println(ch); + } +} diff --git a/STM32F1/libraries/USBComposite/examples/midiin/midiin.ino b/STM32F1/libraries/USBComposite/examples/midiin/midiin.ino new file mode 100644 index 000000000..61bb572ac --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/midiin/midiin.ino @@ -0,0 +1,29 @@ +#include + +#define SPEAKER_PIN PA0 + +class myMidi : public USBMIDI { + virtual void handleNoteOff(unsigned int channel, unsigned int note, unsigned int velocity) { + noTone(SPEAKER_PIN); + } + virtual void handleNoteOn(unsigned int channel, unsigned int note, unsigned int velocity) { + tone(SPEAKER_PIN, (midiNoteFrequency_10ths[note]+5)/10); + } + +}; + +myMidi midi; +USBCompositeSerial CompositeSerial; + +void setup() { + USBComposite.setProductId(0x0030); + pinMode(SPEAKER_PIN, OUTPUT); + midi.registerComponent(); + CompositeSerial.registerComponent(); + USBComposite.begin(); +} + +void loop() { + midi.poll(); +} + diff --git a/STM32F1/libraries/USBComposite/examples/midiout/midiout.ino b/STM32F1/libraries/USBComposite/examples/midiout/midiout.ino new file mode 100644 index 000000000..b21fd0ba8 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/midiout/midiout.ino @@ -0,0 +1,20 @@ +#include + +const uint8_t notes[] = {60, 62, 64, 65, 67, 69, 71, 72, 61, 63, 66, 68, 70}; +const int numNotes = sizeof(notes)/sizeof(*notes); + +USBMIDI midi; + +void setup() { + USBComposite.setProductId(0x0031); + midi.begin(); + while (!USBComposite); +} + +void loop() { + for (int i=0;i + +USBMultiSerial<2> ms; + +void setup() { + ms.begin(); + while (!USBComposite); +} + +void loop() { + while(ms.ports[1].available()) { + ms.ports[0].write(ms.ports[1].read()); + } + while(ms.ports[0].available()) { + ms.ports[1].write(ms.ports[0].read()); + } +} diff --git a/STM32F1/libraries/USBComposite/examples/multixbox360/multixbox360.ino b/STM32F1/libraries/USBComposite/examples/multixbox360/multixbox360.ino new file mode 100755 index 000000000..39c1c82f7 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/multixbox360/multixbox360.ino @@ -0,0 +1,34 @@ +#include + +#define LED PC13 + +USBMultiXBox360<2> x360; + +/* + * Sketch uses 19476 bytes (79%) of program storage space. Maximum is 24576 bytes. +Global variables use 4128 bytes (40%) of dynamic memory, leaving 6112 bytes for local variables. Maximum is 10240 bytes. + +19444/4080 + */ + +void rumble(uint8 left, uint8 right) { + digitalWrite(LED, left+right==0); +} + +void setup() { + pinMode(LED, OUTPUT); + x360.registerComponent(); + USBComposite.begin(); + while (!USBComposite); + x360.controllers[0].setRumbleCallback(rumble); +} + +void loop() { + x360.controllers[0].X(-10000); + x360.controllers[1].Y(-10000); + delay(500); + x360.controllers[0].X(10000); + x360.controllers[1].Y(10000); + delay(500); +} + diff --git a/STM32F1/libraries/USBComposite/examples/rawhid/rawhid.ino b/STM32F1/libraries/USBComposite/examples/rawhid/rawhid.ino new file mode 100644 index 000000000..11165b4c6 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/rawhid/rawhid.ino @@ -0,0 +1,26 @@ +#include + +#define TXSIZE 256 +#define RXSIZE 300 + +USBHID HID; +HIDRaw raw(HID); +uint8 buf[RXSIZE]; + +const uint8_t reportDescription[] = { + HID_RAW_REPORT_DESCRIPTOR(TXSIZE,RXSIZE) +}; + +void setup(){ + HID.begin(reportDescription, sizeof(reportDescription)); + while (!USBComposite); + raw.begin(); +} + +void loop() { + if (raw.getOutput(buf)) { + for (int i=0;i +#include +#include "SdFat.h" + +USBMassStorage MassStorage; +USBCompositeSerial CompositeSerial; + +#define LED_PIN PB12 +#define PRODUCT_ID 0x29 + +SdFatEX sd; +const uint32_t speed = SPI_CLOCK_DIV2 ; +const uint8_t SD_CHIP_SELECT = SS; +bool enabled = false; +uint32 cardSize; + +bool write(const uint8_t *writebuff, uint32_t startSector, uint16_t numSectors) { + return sd.card()->writeBlocks(startSector, writebuff, numSectors); +} + +bool read(uint8_t *readbuff, uint32_t startSector, uint16_t numSectors) { + return sd.card()->readBlocks(startSector, readbuff, numSectors); +} + +void setup() { + USBComposite.setProductId(PRODUCT_ID); + pinMode(LED_PIN,OUTPUT); + digitalWrite(LED_PIN,1); +} + +void initReader() { + digitalWrite(LED_PIN,0); + cardSize = sd.card()->cardSize(); + MassStorage.setDriveData(0, cardSize, read, write); + MassStorage.registerComponent(); + CompositeSerial.registerComponent(); + USBComposite.begin(); + while (!USBComposite); + enabled=true; +} + +void loop() { + if (!enabled) { + if (sd.begin(SD_CHIP_SELECT)) { + initReader(); + } + else { + delay(50); + } + } + else { + MassStorage.loop(); + } +} + diff --git a/STM32F1/libraries/USBComposite/examples/simplejoystick/simplejoystick.ino b/STM32F1/libraries/USBComposite/examples/simplejoystick/simplejoystick.ino new file mode 100644 index 000000000..412b3ab80 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/simplejoystick/simplejoystick.ino @@ -0,0 +1,17 @@ +#include + +USBHID HID; +HIDJoystick Joystick(HID); + +void setup() { + HID.begin(HID_JOYSTICK); + while (!USBComposite); +} + +void loop() { + Joystick.X(0); + delay(500); + Joystick.X(1023); + delay(500); +} + diff --git a/STM32F1/libraries/USBComposite/examples/simplekeyboard/simplekeyboard.ino b/STM32F1/libraries/USBComposite/examples/simplekeyboard/simplekeyboard.ino new file mode 100644 index 000000000..6bd309a6e --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/simplekeyboard/simplekeyboard.ino @@ -0,0 +1,16 @@ +#include + +USBHID HID; +HIDKeyboard Keyboard(HID); + +void setup() { + HID.begin(HID_KEYBOARD); + while (!USBComposite); + Keyboard.begin(); // useful to detect host capslock state and LEDs +} + +void loop() { + Keyboard.println("Hello world"); + delay(10000); +} + diff --git a/STM32F1/libraries/USBComposite/examples/softjoystick/send.py b/STM32F1/libraries/USBComposite/examples/softjoystick/send.py new file mode 100644 index 000000000..bf0eb32b8 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/softjoystick/send.py @@ -0,0 +1,60 @@ +from pywinusb import hid +from time import sleep + +REPORT_ID = 20 +HID_REPORT_FEATURE = 3 + +device = hid.HidDeviceFilter(vendor_id = 0x1EAF).get_devices()[0] # , product_id = 0x0024 +print(device) +device.open() + +""" + uint8_t reportID; + uint32_t buttons; + unsigned hat:4; + unsigned x:10; + unsigned y:10; + unsigned rx:10; + unsigned ry:10; + unsigned sliderLeft:10; + unsigned sliderRight:10; +""" + +def toBits(n,bits): + return tuple((n>>i)&1 for i in range(bits)) + +def getByteFromBits(bits,n): + out = 0 + for i in range(8): + out += bits[8*n+i] << i + return out + +def joystickData(reportID=REPORT_ID, buttons=0, hat=15, x=512, y=512, rx=512, ry=512, sliderLeft=512, sliderRight=512): + joyData = ( toBits(reportID,8) + toBits(buttons,32) + toBits(hat,4) + toBits(x,10) + toBits(y,10) + + toBits(rx,10) + toBits(ry,10) + toBits(sliderLeft,10) + toBits(sliderRight,10) ) + out = [getByteFromBits(joyData,n) for n in range(13)] + print(out) + return out + +myReport = None + +for report in device.find_feature_reports(): + if report.report_id == REPORT_ID and report.report_type == "Feature": + myReport = report + break +if myReport is None: + for report in device.find_output_reports(): + if report.report_id == REPORT_ID and report.report_type == "Output": + myReport = report + break + +assert myReport is not None + +while True: + myReport.set_raw_data(joystickData(buttons=7,x=0,y=0)) + + myReport.send() + sleep(0.5) + myReport.set_raw_data(joystickData(buttons=0,x=1023,y=1023)) + myReport.send() + sleep(0.5) diff --git a/STM32F1/libraries/USBComposite/examples/softjoystick/softjoystick.ino b/STM32F1/libraries/USBComposite/examples/softjoystick/softjoystick.ino new file mode 100644 index 000000000..f1dd58710 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/softjoystick/softjoystick.ino @@ -0,0 +1,51 @@ +// This is a silly project: you send a feature +// report from the PC, and it becomes a joystick setting. +// I guess it's not completely useless as it lets you +// get vJoy functionality without special vJoy drivers. + +#include + +#define DATA_SIZE (sizeof(JoystickReport_t)-1) + +USBHID HID; + +class HIDJoystickRawData : public HIDJoystick { + private: + uint8_t featureData[HID_BUFFER_ALLOCATE_SIZE(DATA_SIZE,1)]; + HIDBuffer_t fb { featureData, HID_BUFFER_SIZE(DATA_SIZE,1), HID_JOYSTICK_REPORT_ID }; + USBHID HID; + public: + HIDJoystickRawData(USBHID& _HID, uint8_t reportID=HID_JOYSTICK_REPORT_ID) : HIDJoystick(HID, reportID) {} + + void begin() { + HID.setFeatureBuffers(&fb, 1); + } + + void setRawData(JoystickReport_t* p) { + joyReport = *p; + send(); + } +}; + +HIDJoystickRawData joy(HID); +JoystickReport_t report = {HID_JOYSTICK_REPORT_ID}; + +const uint8_t reportDescription[] = { + HID_JOYSTICK_REPORT_DESCRIPTOR(HID_JOYSTICK_REPORT_ID, + HID_FEATURE_REPORT_DESCRIPTOR(DATA_SIZE)) +}; + +void setup() { + HID.begin(reportDescription, sizeof(reportDescription)); + while (!USBComposite); + joy.begin(); +} + +void loop() { + if (joy.getFeature(1+(uint8_t*)&report)) { + joy.setRawData(&report); + } + + delay(5); +} + diff --git a/STM32F1/libraries/USBComposite/examples/speaker/speaker.ino b/STM32F1/libraries/USBComposite/examples/speaker/speaker.ino new file mode 100644 index 000000000..71fbb27ba --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/speaker/speaker.ino @@ -0,0 +1,48 @@ +#include +#include + +int audio_left_pin = PA0; +int audio_right_pin = PA1; + +uint8 adc_pins[] = {audio_left_pin, audio_right_pin}; + +uint16_t buffer[2]; +uint8 buf[2]; + +USBCompositeSerial CompositeSerial; +USBAUDIO AUDIO; + +unsigned long last_audio_read_ms; + +int sample_rate = 24000; + +void setup() +{ + pinMode(adc_pins[0], OUTPUT); + pinMode(adc_pins[1], OUTPUT); + + AUDIO.begin(CompositeSerial, SPEAKER_STEREO, sample_rate); + + last_audio_read_ms = micros(); +} + +void loop() +{ + unsigned long current_micros = micros(); + if ((current_micros - last_audio_read_ms) >= AUDIO.getSamplePeriod()) + { + while(!AUDIO.read(buf, 2)); + + /* TODO: Find something useful to do with the data. + analogWrite(adc_pins[0], buf[0] - 128); + analogWrite(adc_pins[1], buf[1] - 128); + */ + + CompositeSerial.print("L: "); + CompositeSerial.println(buf[0]); + CompositeSerial.print("R: "); + CompositeSerial.println(buf[1]); + + last_audio_read_ms = current_micros; + } +} diff --git a/STM32F1/libraries/USBComposite/examples/tonegenerator/tonegenerator.ino b/STM32F1/libraries/USBComposite/examples/tonegenerator/tonegenerator.ino new file mode 100644 index 000000000..fae1a5dbe --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/tonegenerator/tonegenerator.ino @@ -0,0 +1,47 @@ +#include + +uint8 val; +uint16 sample_rate = 8000; +int sin_hz = 200; +int step = 50; +unsigned long last_micros; +double theta; +double inc; + +USBAUDIO AUDIO; + +double get_increment_from_hz(int hz) +{ + return (2 * M_PI) / ((1000000.0 / hz) / AUDIO.getSamplePeriod()); +} + +void setup() +{ + theta = 0.0; + + AUDIO.begin(MIC_MONO, sample_rate); + + inc = get_increment_from_hz(sin_hz); + + last_micros = micros(); +} + +void loop() +{ + unsigned long current_micros = micros(); + unsigned long elapsed = current_micros - last_micros; + + if (elapsed >= AUDIO.getSamplePeriod()) + { + theta += inc; + + if (theta > M_PI * 2) + theta -= M_PI * 2; + + val = (uint8) (((sin(theta) + 1.0) / 2.0) * 255); + + while (!AUDIO.write(&val, 1)); + + last_micros = current_micros; + } +} diff --git a/STM32F1/libraries/USBComposite/examples/tonegeneratorserial/tonegeneratorserial.ino b/STM32F1/libraries/USBComposite/examples/tonegeneratorserial/tonegeneratorserial.ino new file mode 100644 index 000000000..a2290bcb7 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/tonegeneratorserial/tonegeneratorserial.ino @@ -0,0 +1,65 @@ +#include + +uint8 val; +uint16 sample_rate = 8000; +int sin_hz = 200; +int step = 50; +unsigned long last_audio_read_ms; +double theta; +double inc; + +USBCompositeSerial CompositeSerial; +USBAUDIO AUDIO; + +double get_increment_from_hz(int hz) +{ + return (2 * M_PI) / ((1000000.0 / hz) / AUDIO.getSamplePeriod()); +} + +void setup() +{ + theta = 0.0; + + AUDIO.begin(CompositeSerial, MIC_MONO, sample_rate); + + inc = get_increment_from_hz(sin_hz); + + last_audio_read_ms = micros(); +} + +void loop() +{ + unsigned long current_micros = micros(); + unsigned long elapsed = current_micros - last_audio_read_ms; + + if (elapsed >= AUDIO.getSamplePeriod()) + { + theta += inc; + + if (theta > M_PI * 2) + theta -= M_PI * 2; + + val = (uint8) (((sin(theta) + 1.0) / 2.0) * 255); + + while (!AUDIO.write(&val, 1)); + + last_audio_read_ms = current_micros; + } + + if (CompositeSerial.available()) + { + char ch = CompositeSerial.read(); + if (ch == '+') + { + sin_hz += step; + inc = get_increment_from_hz(sin_hz); + CompositeSerial.println(inc); + } + else if (ch == '-') + { + sin_hz -= step; + inc = get_increment_from_hz(sin_hz); + CompositeSerial.println(inc); + } + } +} diff --git a/STM32F1/libraries/USBComposite/examples/twojoysticks/twojoysticks.ino b/STM32F1/libraries/USBComposite/examples/twojoysticks/twojoysticks.ino new file mode 100644 index 000000000..7d103a9a1 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/twojoysticks/twojoysticks.ino @@ -0,0 +1,48 @@ +#include + +const uint8_t reportDescription[] = { + HID_MOUSE_REPORT_DESCRIPTOR(), + HID_KEYBOARD_REPORT_DESCRIPTOR(), + HID_JOYSTICK_REPORT_DESCRIPTOR(), + HID_JOYSTICK_REPORT_DESCRIPTOR(HID_JOYSTICK_REPORT_ID+1), +}; + +USBCompositeSerial CompositeSerial; +USBHID HID; +HIDJoystick Joystick(HID); +HIDJoystick Joystick2(HID, HID_JOYSTICK_REPORT_ID+1); + +void setup(){ + HID.begin(CompositeSerial, reportDescription, sizeof(reportDescription)); + while (!USBComposite); + Joystick.setManualReportMode(true); + Joystick2.setManualReportMode(true); +} + +void loop(){ + Joystick.X(0); + Joystick.Y(0); + Joystick.sliderRight(1023); + Joystick.send(); + CompositeSerial.println("J1:0,0,1023"); + delay(400); + Joystick.X(1023); + Joystick.Y(1023); + Joystick.sliderRight(0); + Joystick.send(); + CompositeSerial.println("J1:1023,1023,0"); + delay(400); + Joystick2.X(0); + Joystick2.Y(0); + Joystick2.sliderRight(1023); + Joystick2.send(); + CompositeSerial.println("J2:0,0,1023"); + delay(400); + Joystick2.X(1023); + Joystick2.Y(1023); + Joystick2.sliderRight(0); + Joystick2.send(); + CompositeSerial.println("J2:1023,1023,0"); + delay(400); +} + diff --git a/STM32F1/libraries/USBComposite/examples/x360/x360.ino b/STM32F1/libraries/USBComposite/examples/x360/x360.ino new file mode 100644 index 000000000..93c995ded --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/x360/x360.ino @@ -0,0 +1,17 @@ +#include + +USBXBox360 XBox360; + +void setup() { + XBox360.begin(); + while (!USBComposite); +} + +void loop() { + XBox360.X(-32767); + XBox360.Y(-32767); + delay(1000); + XBox360.X(32767); + XBox360.Y(32767); + delay(1000); +} diff --git a/STM32F1/libraries/USBComposite/examples/xbox360wireless/xbox360wireless.ino b/STM32F1/libraries/USBComposite/examples/xbox360wireless/xbox360wireless.ino new file mode 100755 index 000000000..d73f81a12 --- /dev/null +++ b/STM32F1/libraries/USBComposite/examples/xbox360wireless/xbox360wireless.ino @@ -0,0 +1,38 @@ +#include + +#define LED PC13 + +USBXBox360W<4> x360; + +/* + * Sketch uses 19428 bytes (79%) of program storage space. Maximum is 24576 bytes. + * Global variables use 4144 bytes (40%) of dynamic memory, leaving 6096 bytes for local variables. Maximum is 10240 bytes. + */ + +void rumble(uint8 left, uint8 right) { + digitalWrite(LED, left+right==0); +} + +void setup() { + pinMode(LED, OUTPUT); + digitalWrite(LED, 1); + x360.begin(); + while (!USBComposite); + x360.controllers[0].setRumbleCallback(rumble); + // the next two lines are not necessary as the library will + // autoconnect when data is sent + for(int i=0; i<2 ; i++) x360.controllers[i].connect(true); + for(int i=2; i<4 ; i++) x360.controllers[i].connect(false); + x360.controllers[0].buttons(0); + x360.controllers[1].buttons(0); +} + +void loop() { + x360.controllers[0].X(-10000); + x360.controllers[1].Y(-10000); + delay(500); + x360.controllers[0].X(10000); + x360.controllers[1].Y(10000); + delay(500); +} + diff --git a/STM32F1/libraries/USBComposite/keywords.txt b/STM32F1/libraries/USBComposite/keywords.txt new file mode 100644 index 000000000..e58ead55b --- /dev/null +++ b/STM32F1/libraries/USBComposite/keywords.txt @@ -0,0 +1,93 @@ +####################################### +# Syntax Coloring Map USBComposite +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +USBComposite KEYWORD1 +USBMultiSerial KEYWORD1 +USBHID KEYWORD1 +USBMIDI KEYWORD1 +USBXBox360 KEYWORD1 +USBMultiXBox360 KEYWORD1 +USBMassStorage KEYWORD1 +USBCompositeSerial KEYWORD1 +HIDMouse KEYWORD1 +HIDKeyboard KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +end KEYWORD2 +XRight KEYWORD2 +YRight KEYWORD2 +Yrotate KEYWORD2 +Y KEYWORD2 +Xrotate KEYWORD2 +X KEYWORD2 +sliderLeft KEYWORD2 +sliderRight KEYWORD2 +button KEYWORD2 +hat KEYWORD2 +setManualReportMode KEYWORD2 +getManualReportMode KEYWORD2 +release KEYWORD2 +press KEYWORD2 +releaseAll KEYWORD2 +move KEYWORD2 +send KEYWORD2 +click KEYWORD2 +registerComponent KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +USB_HID_MOUSE LITERAL1 +USB_HID_KEYBOARD LITERAL1 +USB_HID_JOYSTICK LITERAL1 +USB_HID_KEYBOARD_MOUSE LITERAL1 +USB_HID_KEYBOARD_MOUSE_JOYSTICK LITERAL1 +USB_HID_KEYBOARD_JOYSTICK LITERAL1 +KEY_LEFT_CTRL LITERAL1 +KEY_LEFT_SHIFT LITERAL1 +KEY_LEFT_ALT LITERAL1 +KEY_LEFT_GUI LITERAL1 +KEY_RIGHT_CTRL LITERAL1 +KEY_RIGHT_SHIFT LITERAL1 +KEY_RIGHT_ALT LITERAL1 +KEY_RIGHT_GUI LITERAL1 +KEY_UP_ARROW LITERAL1 +KEY_DOWN_ARROW LITERAL1 +KEY_LEFT_ARROW LITERAL1 +KEY_RIGHT_ARROW LITERAL1 +KEY_BACKSPACE LITERAL1 +KEY_TAB LITERAL1 +KEY_RETURN LITERAL1 +KEY_ESC LITERAL1 +KEY_INSERT LITERAL1 +KEY_DELETE LITERAL1 +KEY_PAGE_UP LITERAL1 +KEY_PAGE_DOWN LITERAL1 +KEY_HOME LITERAL1 +KEY_END LITERAL1 +KEY_CAPS_LOCK LITERAL1 +KEY_F1 LITERAL1 +KEY_F2 LITERAL1 +KEY_F3 LITERAL1 +KEY_F4 LITERAL1 +KEY_F5 LITERAL1 +KEY_F6 LITERAL1 +KEY_F7 LITERAL1 +KEY_F8 LITERAL1 +KEY_F9 LITERAL1 +KEY_F10 LITERAL1 +KEY_F11 LITERAL1 +KEY_F12 LITERAL1 +MOUSE_LEFT LITERAL1 +MOUSE_MIDDLE LITERAL1 +MOUSE_RIGHT LITERAL1 +MOUSE_ALL LITERAL1 +HIDConsumer LITERAL1 diff --git a/STM32F1/libraries/USBComposite/library.properties b/STM32F1/libraries/USBComposite/library.properties new file mode 100644 index 000000000..e01f95e67 --- /dev/null +++ b/STM32F1/libraries/USBComposite/library.properties @@ -0,0 +1,10 @@ +name=USBComposite for STM32F1 +version=1.0.8 +author=Various +email=arpruss@gmail.com +sentence=USB HID / MIDI / mass storage / Audio library for STM32F1 +paragraph=USB HID / MIDI / mass storage / Audio library for STM32F1 +url=https://github.com/arpruss/USBHID_stm32f1 +architectures=STM32F1 +maintainer=arpruss@gmail.com +category=Communication \ No newline at end of file diff --git a/STM32F1/libraries/USBComposite/scripts/midi_table.py b/STM32F1/libraries/USBComposite/scripts/midi_table.py new file mode 100644 index 000000000..9e40d3678 --- /dev/null +++ b/STM32F1/libraries/USBComposite/scripts/midi_table.py @@ -0,0 +1,11 @@ +from math import * + +def freq(m): + return 27.5 * 2**((m-21)/12.) + +print("static constexpr uint32 midiNoteFrequency_10ths[128] = {", end='') +for i in range(128): + if not i % 16: + print("\n ",end='') + print("%d, " % int(floor(freq(i)*10 + 0.5)), end='') +print("};") \ No newline at end of file diff --git a/STM32F1/libraries/USBComposite/scripts/send.py b/STM32F1/libraries/USBComposite/scripts/send.py new file mode 100644 index 000000000..c1ec87db9 --- /dev/null +++ b/STM32F1/libraries/USBComposite/scripts/send.py @@ -0,0 +1,26 @@ +from pywinusb import hid +from time import sleep + +SIZE=128 +REPORT_ID=0 + +def sample_handler(data): + print("Raw data: {0}".format(data)) + +device = hid.HidDeviceFilter(vendor_id = 0x1EAF).get_devices()[0] +print(device) +device.open() +device.set_raw_data_handler(sample_handler) + +n = 0 +while True: + print("sending") + out_report=device.find_output_reports()[0] + buffer=[i for i in range(SIZE+1)] + buffer[0]=REPORT_ID # report id + buffer[-1] = n + out_report.set_raw_data(buffer) + if out_report.send(): + n = (n+1)&0xFF + sleep(2) + \ No newline at end of file diff --git a/STM32F1/libraries/USBComposite/scripts/showhids.py b/STM32F1/libraries/USBComposite/scripts/showhids.py new file mode 100644 index 000000000..5b71d819b --- /dev/null +++ b/STM32F1/libraries/USBComposite/scripts/showhids.py @@ -0,0 +1,3 @@ +from pywinusb import hid + +hid.core.show_hids() diff --git a/STM32F1/libraries/USBComposite/usb_audio.c b/STM32F1/libraries/USBComposite/usb_audio.c new file mode 100644 index 000000000..1158b877e --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_audio.c @@ -0,0 +1,655 @@ +/* Copyright (c) 2019, Scott Moreau +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +/* Private headers */ +#include "usb_lib_globals.h" +#include "usb_reg_map.h" +#include "libmaple/usb.h" +#include +#include + +#include "usb_audio.h" + + + +#define CUR 0x01 +#define RANGE 0x02 +#define CLOCK_SOURCE_ID 0x10 +#define AUDIO_INTERFACE_OFFSET 0x00 +#define IO_BUFFER_SIZE 256 +#define IO_BUFFER_SIZE_MASK (IO_BUFFER_SIZE - 1) +//#define AUDIO_INTERFACE_NUMBER (AUDIO_INTERFACE_OFFSET + usbAUDIOPart.startInterface) +#define AUDIO_ISO_EP_ENDPOINT_INFO (&usbAUDIOPart.endpoints[0]) +#define AUDIO_ISO_EP_ADDRESS (usbAUDIOPart.endpoints[0].address) +#define AUDIO_ISO_PMA_BUFFER_SIZE (usbAUDIOPart.endpoints[0].pmaSize / 2) + +/* Tx data */ +static volatile uint8 audioBufferTx[IO_BUFFER_SIZE]; +/* Write index to audioBufferTx */ +static volatile uint32 audio_tx_head = 0; +/* Read index from audioBufferTx */ +static volatile uint32 audio_tx_tail = 0; +/* Rx data */ +static volatile uint8 audioBufferRx[IO_BUFFER_SIZE]; +/* Write index to audioBufferRx */ +static volatile uint32 audio_rx_head = 0; +/* Read index from audioBufferRx */ +static volatile uint32 audio_rx_tail = 0; +static uint8 usbAudioReceiving; + +static volatile int8 transmitting; +static uint8 clock_valid = 1; +static uint16 sample_rate; +static uint8 buffer_size; +static uint8 channels; + +typedef struct { + uint16_t wNumSubRanges; + uint32_t min; + uint32_t max; + uint32_t res; +} __packed srr_data; + +static srr_data sample_rate_range = { + .wNumSubRanges = 0x0001, + .min = 0x00000000, + .max = 0x00000000, + .res = 0x00000000, +}; + +static void audioDataTxCb(void); +static void audioDataRxCb(void); +static void audioUSBReset(void); +static RESULT audioUSBDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength); +static void (*packet_callback)(uint8) = 0; + +/* + * Descriptor + */ + +typedef struct { + audio_interface_association_descriptor AUDIO_IAD; + usb_descriptor_interface AUDIO_Interface; + audio_control_descriptor AUDIO_AC; + input_terminal_descriptor AUDIO_Input; + output_terminal_descriptor AUDIO_Output; + feature_unit_descriptor AUDIO_FU; + audio_streaming_descriptor AUDIO_Alternate0; + audio_streaming_descriptor AUDIO_Alternate1; + audio_stream_audio_class_descriptor AUDIO_AS_AC; + audio_format_type_descriptor AUDIO_Format_Type; + audio_iso_endpoint_descriptor AUDIO_Iso_EP; + audio_iso_ac_endpoint_descriptor AUDIO_Iso_EP_AC; +} __packed audio_part_config; + +typedef struct { + audio_interface_association_descriptor AUDIO_IAD; + usb_descriptor_interface AUDIO_Interface; + audio_control_descriptor_2 AUDIO_AC; + audio_clock_source_descriptor AUDIO_CS; + input_terminal_descriptor_2 AUDIO_Input; + output_terminal_descriptor_2 AUDIO_Output; + feature_unit_descriptor_2 AUDIO_FU; + audio_streaming_descriptor AUDIO_Alternate0; + audio_streaming_descriptor AUDIO_Alternate1; + audio_stream_audio_class_descriptor_2 AUDIO_AS_AC; + audio_format_type_descriptor_2 AUDIO_Format_Type; + audio_iso_endpoint_descriptor_2 AUDIO_Iso_EP; + audio_iso_ac_endpoint_descriptor_2 AUDIO_Iso_EP_AC; +} __packed audio_part_config_2; + +static const audio_part_config audioPartConfigData = { + .AUDIO_IAD = { + .bLength = sizeof(audio_interface_association_descriptor), + .bDescriptorType = USB_INTERFACE_ASSOCIATION_DESCRIPTOR, + .bFirstInterface = 0x00, + .bInterfaceCount = 0x02, + .bFunctionClass = USB_DEVICE_CLASS_AUDIO, + .bFunctionSubClass = AUDIO_SUBCLASS_AUDIOCONTROL, + .bFunctionProtocol = 0x00, + .iFunction = 0x00, + }, /* 8 */ + .AUDIO_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = AUDIO_INTERFACE_OFFSET, /* PATCH */ + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x00, + .bInterfaceClass = USB_DEVICE_CLASS_AUDIO, + .bInterfaceSubClass = AUDIO_SUBCLASS_AUDIOCONTROL, + .bInterfaceProtocol = 0x00, /* Common AT Commands */ + .iInterface = 0x00, + }, /* 9 */ + .AUDIO_AC = { + .bLength = sizeof(audio_control_descriptor), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = 0x01, /* HEADER subtype */ + .bcdADC = 0x0100, /* revision of class specification 1.00 (0x0100) */ + .wTotalLength = 0x0027, /* total size of class specific descriptors (0x0027) */ + .bInCollection = 0x01, /* 1 streaming interface */ + .baInterfaceNr = 0x01, /* AudioStreaming interface 1 belongs to this AC interface */ + }, /* 9 */ + .AUDIO_Input = { + .bLength = sizeof(input_terminal_descriptor), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = 0x02, /* INPUT_TERMINAL subtype */ + .bTerminalID = 0x01, /* ID of this terminal */ + .wTerminalType = 0x0201, /* Generic Microphone (0x0201) - PATCH */ + .bAssocTerminal = 0x00, /* bAssocTerminal: no association */ + .bNrChannels = 0x02, /* dual channel */ + .wChannelConfig = 0x0003, /* Stereo (0x0003) */ + .iChannelNames = 0x00, /* unused */ + .iTerminal = 0x00, /* unused */ + }, /* 12 */ + .AUDIO_Output = { + .bLength = sizeof(output_terminal_descriptor), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = 0x03, /* OUTPUT_TERMINAL subtype */ + .bTerminalID = 0x02, /* ID of this terminal */ + .wTerminalType = 0x0101, /* USB streaming (0x0101) */ + .bAssocTerminal = 0x00, /* unused */ + .bSourceID = 0x01, /* from input terminal */ + .iTerminal = 0x00, /* unused */ + }, /* 9 */ + .AUDIO_FU = { + .bLength = sizeof(feature_unit_descriptor), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT, /* FEATURE_UNIT */ + .bUnitID = 0x03, /* unique ID of this unit within the audio function */ + .bSourceID = 0x01, /* ID of the terminal to which this FU connected */ + .bControlSize = 0x01, /* bmaControls are one byte size */ + .bmaControls0 = 0x00, /* controls for master channel (no controls) */ + .bmaControls1 = 0x00, /* controls for channel 1 (no controls) */ + .iFeature = 0x00, /* string descriptor of this FU, unused */ + }, /* 9 */ + .AUDIO_Alternate0 = { + .bLength = sizeof(audio_streaming_descriptor), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, /* interface */ + .bInterfaceNumber = 0x01, /* interface 1 (index of this interface) - PATCH */ + .bAlternateSetting = 0x00, /* index of this alternate setting */ + .bNumEndpoints = 0x00, /* 0 endpoints */ + .bInterfaceClass = USB_DEVICE_CLASS_AUDIO, /* AUDIO */ + .bInterfaceSubclass = AUDIO_SUBCLASS_AUDIOSTREAMING, /* AUDIO_STREAMING */ + .bInterfaceProtocol = 0x00, /* unused */ + .iInterface = 0x00, /* unused */ + }, /* 9 */ + .AUDIO_Alternate1 = { + .bLength = sizeof(audio_streaming_descriptor), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, /* interface */ + .bInterfaceNumber = 0x01, /* index of this interface - PATCH */ + .bAlternateSetting = 0x01, /* index of this alternate setting */ + .bNumEndpoints = 0x01, /* one endpoint */ + .bInterfaceClass = USB_DEVICE_CLASS_AUDIO, /* AUDIO */ + .bInterfaceSubclass = AUDIO_SUBCLASS_AUDIOSTREAMING, /* AUDIO_STREAMING */ + .bInterfaceProtocol = 0x00, /* unused */ + .iInterface = 0x00, /* unused */ + }, /* 9 */ + .AUDIO_AS_AC = { + .bLength = sizeof(audio_stream_audio_class_descriptor), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = 0x01, /* GENERAL subtype */ + .bTerminalLink = 0x02, /* uint ID of the output terminal */ + .bDelay = 0x01, /* interface delay */ + .wFormatTag = 0x0002, /* PCM8 format (0x0002) */ + }, /* 7 */ + .AUDIO_Format_Type = { + .bLength = sizeof(audio_format_type_descriptor), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = AUDIO_STREAMING_FORMAT_TYPE, /* FORMAT_TYPE subtype */ + .bFormatType = 0x01, /* FORMAT_TYPE_I */ + .bNrChannels = 0x02, /* dual channel - PATCH */ + .bSubFrameSize = 0x01, /* one byte per audio subframe */ + .bBitResolution = 0x08, /* 8 bit per sample */ + .bSamFreqType = 0x01, /* one frequency supported */ + .tSamFreq0 = 0x00, /* Byte 0 - PATCH */ + .tSamFreq1 = 0x00, /* Byte 1 - PATCH */ + .tSamFreq2 = 0x00, /* Byte 2 - PATCH */ + }, /* 11 */ + .AUDIO_Iso_EP = { + .bLength = sizeof(audio_iso_endpoint_descriptor), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, /* endpoint */ + .bEndpointAddress = USB_DESCRIPTOR_ENDPOINT_IN, /* IN endpoint 1 - PATCH */ + .bmAttributes = USB_EP_TYPE_ISO, /* isochronous, not shared */ + .wMaxPacketSize = 0x0040, /* 64 bytes per packet (0x0040) - PATCH */ + .bInterval = 0x01, /* one packet per ms frame */ + .bRefresh = 0x00, /* unused */ + .bSynchAddress = 0x00, /* unused */ + }, /* 9 */ + .AUDIO_Iso_EP_AC = { + .bLength = sizeof(audio_iso_ac_endpoint_descriptor), + .bDescriptorType = AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* class-specific endpoint */ + .bDescriptorSubtype = 0x01, /* GENERAL subtype */ + .bmAttributes = 0x00, /* no sampling control, no pitch control, no packet padding */ + .bLockDelayUnits = 0x00, /* unused */ + .wLockDelay = 0x0000, /* unused (0x0000) */ + } /* 7 */ +}; + +static const audio_part_config_2 audioPartConfigData2 = { + .AUDIO_IAD = { + .bLength = sizeof(audio_interface_association_descriptor), + .bDescriptorType = USB_INTERFACE_ASSOCIATION_DESCRIPTOR, + .bFirstInterface = 0x00, + .bInterfaceCount = 0x02, + .bFunctionClass = USB_DEVICE_CLASS_AUDIO, + .bFunctionSubClass = AUDIO_SUBCLASS_AUDIOCONTROL, + .bFunctionProtocol = 0x20, /* 2.0 AF_VERSION_02_00 */ + .iFunction = 0x00, + }, /* 8 */ + .AUDIO_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = AUDIO_INTERFACE_OFFSET, /* PATCH */ + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x00, + .bInterfaceClass = USB_DEVICE_CLASS_AUDIO, + .bInterfaceSubClass = AUDIO_SUBCLASS_AUDIOCONTROL, + .bInterfaceProtocol = 0x20, /* IP 2.0 IP_VERSION_02_00 */ + .iInterface = 0x00, /* Not Requested */ + }, /* 9 */ + .AUDIO_AC = { + .bLength = sizeof(audio_control_descriptor_2), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = 0x01, /* HEADER subtype */ + .bcdADC = 0x0200, /* 2.0 */ + .bCategory = 0x00, + .wTotalLength = 0x003C, /* total size of class specific descriptors */ + .bmControls = 0x01, /* 1 streaming interface */ + }, /* 9 */ + .AUDIO_CS = { + .bLength = sizeof(audio_clock_source_descriptor), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = 0x0A, /* CLOCK_SOURCE */ + .bClockID = CLOCK_SOURCE_ID, /* CLOCK_SOURCE_ID */ + .bmAttributes = 0x01, /* internal fixed clock */ + .bmControls = 0x05, /* D3..2: Clock Validity Control D1..0: Clock Frequency Control */ + .bAssocTerminal = 0x20, + .iClockSource = 0x00, /* Not requested */ + }, /* 8 */ + .AUDIO_Input = { + .bLength = sizeof(input_terminal_descriptor_2), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = 0x02, /* INPUT_TERMINAL subtype */ + .bTerminalID = 0x20, /* ID of this terminal */ + .wTerminalType = 0x0201, /* Generic Microphone (0x0201) - PATCH */ + .bAssocTerminal = 0x00, /* bAssocTerminal: no association */ + .bCSourceID = CLOCK_SOURCE_ID, /* CLOCK_SOURCE_ID */ + .bNrChannels = 0x01, /* single channel */ + .bmChannelConfig = 0x00000000, /* Mono, no spatial location */ + .iChannelNames = 0x00, + .bmControls = 0x0000, + .iTerminal = 0x00, /* Not requested */ + }, /* 17 */ + .AUDIO_Output = { + .bLength = sizeof(output_terminal_descriptor_2), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = 0x03, /* OUTPUT_TERMINAL subtype */ + .bTerminalID = 0x40, /* ID of this terminal */ + .wTerminalType = 0x0101, /* USB streaming (0x0101) */ + .bAssocTerminal = 0x00, /* unused */ + .bSourceID = 0x30, /* from input terminal */ + .bCSourceID = CLOCK_SOURCE_ID, /* CLOCK_SOURCE_ID */ + .bmControls = 0x0000, + .iTerminal = 0x00, /* unused */ + }, /* 12 */ + .AUDIO_FU = { + .bLength = sizeof(feature_unit_descriptor_2), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT, /* FEATURE_UNIT */ + .bUnitID = 0x30, /* unique ID of this unit within the audio function */ + .bSourceID = 0x20, /* ID of the terminal to which this FU connected */ + .bmaControls0 = 0x00000000, /* controls for master channel (no controls) */ + .bmaControls1 = 0x00000000, /* controls for channel 1 (no controls) */ + .iFeature = 0x00, /* string descriptor of this FU, unused */ + }, /* 14 */ + .AUDIO_Alternate0 = { + .bLength = sizeof(audio_streaming_descriptor), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, /* interface */ + .bInterfaceNumber = 0x01, /* interface 1 (index of this interface) - PATCH */ + .bAlternateSetting = 0x00, /* index of this alternate setting */ + .bNumEndpoints = 0x00, /* 0 endpoints */ + .bInterfaceClass = USB_DEVICE_CLASS_AUDIO, /* AUDIO */ + .bInterfaceSubclass = AUDIO_SUBCLASS_AUDIOSTREAMING, /* AUDIO_STREAMING */ + .bInterfaceProtocol = 0x20, /* IP 2.0 */ + .iInterface = 0x00, + }, /* 9 */ + .AUDIO_Alternate1 = { + .bLength = sizeof(audio_streaming_descriptor), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, /* interface */ + .bInterfaceNumber = 0x01, /* index of this interface - PATCH */ + .bAlternateSetting = 0x01, /* index of this alternate setting */ + .bNumEndpoints = 0x01, /* one endpoint */ + .bInterfaceClass = USB_DEVICE_CLASS_AUDIO, /* AUDIO */ + .bInterfaceSubclass = AUDIO_SUBCLASS_AUDIOSTREAMING, /* AUDIO_STREAMING */ + .bInterfaceProtocol = 0x20, /* IP 2.0 */ + .iInterface = 0x00, + }, /* 9 */ + .AUDIO_AS_AC = { + .bLength = sizeof(audio_stream_audio_class_descriptor_2), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = 0x01, /* GENERAL subtype */ + .bTerminalLink = 0x40, /* uint ID of the output terminal */ + .bmControls = 0x00, /* interface delay */ + .bFormatType = 0x01, /* FORMAT_TYPE_I */ + .bmFormats = 0x00000002, /* PCM8 */ + .bNrChannels = 0x02, + .bmChannelConfig = 0x00000003, + .iChannelNames = 0x00, /* None */ + }, /* 16 */ + .AUDIO_Format_Type = { + .bLength = sizeof(audio_format_type_descriptor_2), + .bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* class-specific interface */ + .bDescriptorSubtype = AUDIO_STREAMING_FORMAT_TYPE, /* FORMAT_TYPE subtype */ + .bFormatType = 0x01, /* FORMAT_TYPE_I */ + .bSubSlotSize = 0x01, /* single channel */ + .bBitResolution = 0x08, /* one byte per audio subframe */ + }, /* 6 */ + .AUDIO_Iso_EP = { + .bLength = sizeof(audio_iso_endpoint_descriptor_2), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, /* endpoint */ + .bEndpointAddress = USB_DESCRIPTOR_ENDPOINT_IN, /* IN endpoint 1 - PATCH */ + .bmAttributes = USB_EP_TYPE_ISO, /* isochronous - PATCH */ + .wMaxPacketSize = 0x0040, /* 64 bytes per packet (0x0040) - PATCH */ + .bInterval = 0x01, /* one packet per ms frame */ + }, /* 7 */ + .AUDIO_Iso_EP_AC = { + .bLength = sizeof(audio_iso_ac_endpoint_descriptor_2), + .bDescriptorType = AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* class-specific endpoint */ + .bDescriptorSubtype = 0x01, /* GENERAL subtype */ + .bmAttributes = 0x00, /* MaxPacketsOnly = FALSE */ + .bmControls = 0x00, + .bLockDelayUnits = 0x00, + .wLockDelay = 0x0000, + } /* 8 */ +}; + +static USBEndpointInfo audioEndpointIN[1] = { + { + .callback = audioDataTxCb, + .pmaSize = AUDIO_MAX_EP_BUFFER_SIZE, + .type = USB_GENERIC_ENDPOINT_TYPE_ISO, + .tx = 1, + .exclusive = 1, // TODO: check if needed? + .doubleBuffer = 1 + } +}; + +static USBEndpointInfo audioEndpointOUT[1] = { + { + .callback = audioDataRxCb, + .pmaSize = AUDIO_MAX_EP_BUFFER_SIZE, + .type = USB_GENERIC_ENDPOINT_TYPE_ISO, + .tx = 0, + .exclusive = 1, // TODO: check if needed? + .doubleBuffer = 1 + } +}; + +void usb_audio_setEPSize(uint32_t size) { + if (size == 0 || size > buffer_size) + size = buffer_size; + + /* only IN is double buffered */ + if (usbAUDIOPart.endpoints == audioEndpointIN) + size *= 2; + + usbAUDIOPart.endpoints[0].pmaSize = size; +} + +#define OUT_BYTE(s,v) out[(uint8*)&(s.v)-(uint8*)&s] +#define OUT_16(s,v) *(uint16_t*)&OUT_BYTE(s,v) +#define OUT_32(s,v) *(uint32_t*)&OUT_BYTE(s,v) + +static void getAUDIOPartDescriptor(uint8* out) { + memcpy(out, &audioPartConfigData, sizeof(audio_part_config)); + /* patch to reflect where the part goes in the descriptor */ + OUT_BYTE(audioPartConfigData, AUDIO_Interface.bInterfaceNumber) += usbAUDIOPart.startInterface; + if (usbAUDIOPart.endpoints == audioEndpointOUT) { + OUT_16(audioPartConfigData, AUDIO_Input.wTerminalType) = 0x0301 /* Generic Speaker */; + OUT_BYTE(audioPartConfigData, AUDIO_Iso_EP.bEndpointAddress) = USB_DESCRIPTOR_ENDPOINT_OUT; + } + OUT_BYTE(audioPartConfigData, AUDIO_Alternate0.bInterfaceNumber) += usbAUDIOPart.startInterface; + OUT_BYTE(audioPartConfigData, AUDIO_Alternate1.bInterfaceNumber) += usbAUDIOPart.startInterface; + OUT_BYTE(audioPartConfigData, AUDIO_Iso_EP.bEndpointAddress) += AUDIO_ISO_EP_ADDRESS; + OUT_BYTE(audioPartConfigData, AUDIO_Format_Type.bNrChannels) = channels; + OUT_BYTE(audioPartConfigData, AUDIO_Format_Type.tSamFreq0) = AUDIO_SAMPLE_FREQ_0(sample_rate); + OUT_BYTE(audioPartConfigData, AUDIO_Format_Type.tSamFreq1) = AUDIO_SAMPLE_FREQ_1(sample_rate); + OUT_BYTE(audioPartConfigData, AUDIO_Format_Type.tSamFreq2) = AUDIO_SAMPLE_FREQ_2(sample_rate); + OUT_BYTE(audioPartConfigData, AUDIO_Iso_EP.bmAttributes) |= 0x0C; /* synchronous */ + /* Used in conjunction with other attributes for bandwidth allocation calculation */ + OUT_16(audioPartConfigData, AUDIO_Iso_EP.wMaxPacketSize) = buffer_size; +} + +static void getAUDIOPartDescriptor2(uint8* out) { + memcpy(out, &audioPartConfigData2, sizeof(audio_part_config_2)); + /* patch to reflect where the part goes in the descriptor */ + OUT_BYTE(audioPartConfigData2, AUDIO_Interface.bInterfaceNumber) += usbAUDIOPart.startInterface; + if (usbAUDIOPart.endpoints == audioEndpointOUT) { + OUT_16(audioPartConfigData2, AUDIO_Input.wTerminalType) = 0x0301 /* Generic Speaker */; + OUT_BYTE(audioPartConfigData2, AUDIO_Iso_EP.bEndpointAddress) = USB_DESCRIPTOR_ENDPOINT_OUT; + } + OUT_BYTE(audioPartConfigData2, AUDIO_Input.bNrChannels) = channels; + if (channels == 2) + OUT_32(audioPartConfigData2, AUDIO_Input.bmChannelConfig) = 0x00000003; /* Front Left, Front Right */ + OUT_BYTE(audioPartConfigData2, AUDIO_Alternate0.bInterfaceNumber) += usbAUDIOPart.startInterface; + OUT_BYTE(audioPartConfigData2, AUDIO_Alternate1.bInterfaceNumber) += usbAUDIOPart.startInterface; + OUT_BYTE(audioPartConfigData2, AUDIO_Iso_EP.bEndpointAddress) += AUDIO_ISO_EP_ADDRESS; + OUT_BYTE(audioPartConfigData2, AUDIO_AS_AC.bNrChannels) = channels; + OUT_BYTE(audioPartConfigData2, AUDIO_Iso_EP.bmAttributes) |= 0x0C; /* synchronous */ + /* Used in conjunction with other attributes for bandwidth allocation calculation */ + OUT_16(audioPartConfigData2, AUDIO_Iso_EP.wMaxPacketSize) = buffer_size; +} + +USBCompositePart usbAUDIOPart = { + .numInterfaces = 2, + .numEndpoints = 1, + .usbInit = NULL, + .usbReset = audioUSBReset, + .usbDataSetup = audioUSBDataSetup, + .usbNoDataSetup = NULL, + .usbClearFeature = NULL, + .usbSetConfiguration = NULL +}; + + +uint8 usb_audio_init(uint16 type, uint16 rate) +{ + channels = 1; + + if ((type & 0xFF) == MIC_MONO) { + usbAUDIOPart.endpoints = audioEndpointIN; + } else if ((type & 0xFF) == MIC_STEREO) { + usbAUDIOPart.endpoints = audioEndpointIN; + channels = 2; + } else if ((type & 0xFF) == SPEAKER_MONO) { + usbAUDIOPart.endpoints = audioEndpointOUT; + } else if ((type & 0xFF) == SPEAKER_STEREO) { + usbAUDIOPart.endpoints = audioEndpointOUT; + channels = 2; + } + if ((type & 0xFF00) == AUDIO_CLASS_2) { + usbAUDIOPart.descriptorSize = sizeof(audio_part_config_2); + usbAUDIOPart.getPartDescriptor = getAUDIOPartDescriptor2; + } else if (((type & 0xFF00) == AUDIO_CLASS_1) || !(type & 0xFF00)) { + usbAUDIOPart.descriptorSize = sizeof(audio_part_config); + usbAUDIOPart.getPartDescriptor = getAUDIOPartDescriptor; + } else { + return 0; + } + + buffer_size = (rate / 1000) * channels; + + sample_rate = rate; + + sample_rate_range.wNumSubRanges = 0x0001; + sample_rate_range.min = sample_rate; + sample_rate_range.max = sample_rate; + sample_rate_range.res = 0x00000000; + + return buffer_size; +} + +void audio_set_packet_callback(void (*callback)(uint8)) { + packet_callback = callback; +} + +/* This function is non-blocking. + * + * It copies data from a user buffer into the USB peripheral TX + * buffer, and returns the number of bytes copied. */ +uint32 usb_audio_write_tx_data(const uint8* buf, uint32 len) +{ + if (len == 0) + return 0; /* no data to send */ + + while(transmitting >= 0); + + uint32 head = audio_tx_head; /* load volatile variable */ + uint32 tx_unsent = (head - audio_tx_tail) & IO_BUFFER_SIZE_MASK; + + /* We can only put bytes in the buffer if there is place */ + if (len > (IO_BUFFER_SIZE - tx_unsent - 1) ) { + len = (IO_BUFFER_SIZE - tx_unsent - 1); + } + + if (len == 0) + return 0; /* buffer full */ + + /* copy data from user buffer to USB Tx buffer */ + uint16 i; + for (i = 0; i < len; i++) { + audioBufferTx[head] = buf[i]; + head = (head + 1) & IO_BUFFER_SIZE_MASK; + } + audio_tx_head = head; /* store volatile variable */ + + return len; +} + +/* Non-blocking byte lookahead. + * + * Looks at unread bytes without marking them as read. */ +uint32 audio_rx_peek(uint8* buf, uint32 len) +{ + unsigned i; + uint32 tail = audio_rx_tail; + uint32 rx_unread = (audio_rx_head - tail) & IO_BUFFER_SIZE_MASK; + + if (len > rx_unread) + len = rx_unread; + + for (i = 0; i < len; i++) { + buf[i] = audioBufferRx[tail]; + tail = (tail + 1) & IO_BUFFER_SIZE_MASK; + } + + return len; +} + +/* Non-blocking byte receive. + * + * Copies up to len bytes from our private data buffer (*NOT* the PMA) + * into buf and deq's the FIFO. */ +uint32 usb_audio_read_rx_data(uint8* buf, uint32 len) +{ + while(usbAudioReceiving); + + /* Copy bytes to buffer. */ + uint32 n_copied = audio_rx_peek(buf, len); + + /* Mark bytes as read. */ + uint16 tail = audio_rx_tail; /* load volatile variable */ + tail = (tail + n_copied) & IO_BUFFER_SIZE_MASK; + audio_rx_tail = tail; /* store volatile variable */ + + return n_copied; +} + +/* Since we're USB FS, this function called once per millisecond */ +static void audioDataTxCb(void) +{ + transmitting = 1; + usb_generic_send_from_circular_buffer_double_buffered(AUDIO_ISO_EP_ENDPOINT_INFO, audioBufferTx, IO_BUFFER_SIZE, buffer_size, &audio_tx_tail); + transmitting = -1; + + if (packet_callback) + packet_callback(buffer_size); +} + +static void audioDataRxCb(void) +{ + usbAudioReceiving = 1; + uint32 ep_rx_size = usb_generic_read_to_circular_buffer(usbAUDIOPart.endpoints+0, audioBufferRx, + IO_BUFFER_SIZE, &audio_rx_head); + usbAudioReceiving = 0; + + if (packet_callback) + packet_callback(ep_rx_size); +} + +static void audioUSBReset(void) { + /* Reset the RX/TX state */ + audio_tx_head = 0; + audio_tx_tail = 0; + audio_rx_head = 0; + audio_rx_tail = 0; + usbAudioReceiving = 0; + transmitting = -1; + + if (usbAUDIOPart.endpoints == audioEndpointIN) { + /* Setup IN endpoint */ + usb_generic_enable_tx(AUDIO_ISO_EP_ENDPOINT_INFO); + } else if (usbAUDIOPart.endpoints == audioEndpointOUT) { + /* Setup OUT endpoint */ + usb_generic_enable_rx(AUDIO_ISO_EP_ENDPOINT_INFO); + } +} + +#pragma GCC diagnostic ignored "-Wunused-parameter" +static RESULT audioUSBDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength) { + switch (requestType) { + case 0x21: + usb_generic_control_rx_setup(NULL, wLength, NULL); + return USB_SUCCESS; + + case 0xA1: + if ((wIndex >> 8) == CLOCK_SOURCE_ID) { + switch(request) { + case CUR: + switch(wLength) { + case 1: + usb_generic_control_tx_setup(&clock_valid, 1, NULL); + return USB_SUCCESS; + case 2: + usb_generic_control_tx_setup(&sample_rate, 2, NULL); + return USB_SUCCESS; + case 4: + usb_generic_control_tx_setup(&sample_rate_range.min, 4, NULL); + return USB_SUCCESS; + } + break; + case RANGE: + usb_generic_control_tx_setup(&sample_rate_range, sizeof(sample_rate_range), NULL); + return USB_SUCCESS; + } + } + usb_generic_control_tx_setup(NULL, wLength, NULL); + return USB_SUCCESS; + } + + return USB_UNSUPPORT; +} + diff --git a/STM32F1/libraries/USBComposite/usb_audio.h b/STM32F1/libraries/USBComposite/usb_audio.h new file mode 100644 index 000000000..1729629b5 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_audio.h @@ -0,0 +1,320 @@ +/* Copyright (c) 2019, Scott Moreau +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#ifndef __USB_AUDIO_H +#define __USB_AUDIO_H + +#include +#include +#include "usb_generic.h" + +#define AUDIO_SAMPLE_FREQ_0(frq) (uint8_t)((frq >> 16)) +#define AUDIO_SAMPLE_FREQ_1(frq) (uint8_t)((frq >> 8)) +#define AUDIO_SAMPLE_FREQ_2(frq) (uint8_t)(frq) + +#define MAX_AUDIO_BUFFERS 8 +#define AUDIO_BUFFER_SIZE(n,reportID) ((n)+((reportID)!=0)) +#define AUDIO_BUFFER_ALLOCATE_SIZE(n,reportID) ((AUDIO_BUFFER_SIZE((n),(reportID))+1)/2*2) + +#define AUDIO_BUFFER_MODE_NO_WAIT 1 +#define AUDIO_BUFFER_MODE_OUTPUT 2 + +#define AUDIO_BUFFER_EMPTY 0 +#define AUDIO_BUFFER_UNREAD 1 +#define AUDIO_BUFFER_READ 2 + +#define AUDIO_ENDPOINT_TX 0 +#define USB_AUDIO_TX_ENDP (audioEndpoints[AUDIO_ENDPOINT_TX].address) +#define USB_AUDIO_TX_ADDR (audioEndpoints[AUDIO_ENDPOINT_TX].pmaAddress) + +/* Descriptor constants */ + +#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR 0x0B +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01 +#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 +#define AUDIO_STREAMING_FORMAT_TYPE 0x02 + +#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24 +#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25 + +#define AUDIO_CONTROL_FEATURE_UNIT 0x06 + +#define AUDIO_FORMAT_TYPE_I 0x01 + +#define AUDIO_MAX_EP_BUFFER_SIZE 128 + +#define AUDIO_CLASS_1 0x0100 +#define AUDIO_CLASS_2 0x1000 +#define MIC_MONO 0x01 +#define MIC_STEREO 0x02 +#define SPEAKER_MONO 0x03 +#define SPEAKER_STEREO 0x04 + +extern USBCompositePart usbAUDIOPart; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Standard Interface Association Descriptor */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +} __packed audio_interface_association_descriptor; + +/* Interface Header Audio Class Descriptor v1 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdADC; + uint16_t wTotalLength; + uint8_t bInCollection; + uint8_t baInterfaceNr; +} __packed audio_control_descriptor; + +/* Interface Header Audio Class Descriptor v2 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdADC; + uint8_t bCategory; + uint16_t wTotalLength; + uint8_t bmControls; +} __packed audio_control_descriptor_2; + +/* Clock Source Descriptor */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bClockID; + uint8_t bmAttributes; + uint8_t bmControls; + uint8_t bAssocTerminal; + uint8_t iClockSource; +} __packed audio_clock_source_descriptor; + +/* Input Terminal Audio Class Descriptor v1 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bNrChannels; + uint16_t wChannelConfig; + uint8_t iChannelNames; + uint8_t iTerminal; +} __packed input_terminal_descriptor; + +/* Input Terminal Audio Class Descriptor v2 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bCSourceID; + uint8_t bNrChannels; + uint32_t bmChannelConfig; + uint8_t iChannelNames; + uint16_t bmControls; + uint8_t iTerminal; +} __packed input_terminal_descriptor_2; + +/* Output Terminal Audio Class Descriptor v1 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bSourceID; + uint8_t iTerminal; +} __packed output_terminal_descriptor; + +/* Output Terminal Audio Class Descriptor v2 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bSourceID; + uint8_t bCSourceID; + uint16_t bmControls; + uint8_t iTerminal; +} __packed output_terminal_descriptor_2; + +/* Feature Unit Audio Class Descriptor v1 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bUnitID; + uint8_t bSourceID; + uint8_t bControlSize; + uint8_t bmaControls0; + uint8_t bmaControls1; + uint8_t iFeature; +} __packed feature_unit_descriptor; + +/* Feature Unit Audio Class Descriptor v2 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bUnitID; + uint8_t bSourceID; + uint32_t bmaControls0; + uint32_t bmaControls1; + uint8_t iFeature; +} __packed feature_unit_descriptor_2; + +/* Alternate Audio Interface Descriptor */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubclass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} __packed audio_streaming_descriptor; + +/* Audio Stream Audio Class Descriptor v1 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalLink; + uint8_t bDelay; + uint16_t wFormatTag; +} __packed audio_stream_audio_class_descriptor; + +/* Audio Stream Audio Class Descriptor v2 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalLink; + uint8_t bmControls; + uint8_t bFormatType; + uint32_t bmFormats; + uint8_t bNrChannels; + uint32_t bmChannelConfig; + uint8_t iChannelNames; +} __packed audio_stream_audio_class_descriptor_2; + +/* Format Type Audio Descriptor v1 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bFormatType; + uint8_t bNrChannels; + uint8_t bSubFrameSize; + uint8_t bBitResolution; + uint8_t bSamFreqType; + uint8_t tSamFreq2; + uint8_t tSamFreq1; + uint8_t tSamFreq0; +} __packed audio_format_type_descriptor; + +/* Format Type Audio Descriptor v2 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bFormatType; + uint8_t bSubSlotSize; + uint8_t bBitResolution; +} __packed audio_format_type_descriptor_2; + +/* Isochronous Endpoint Descriptor v1 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; + uint8_t bRefresh; + uint8_t bSynchAddress; +} __packed audio_iso_endpoint_descriptor; + +/* Isochronous Endpoint Descriptor v2 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __packed audio_iso_endpoint_descriptor_2; + +/* Isochronous Endpoint Audio Class Descriptor v1 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmAttributes; + uint8_t bLockDelayUnits; + uint16_t wLockDelay; +} __packed audio_iso_ac_endpoint_descriptor; + +/* Isochronous Endpoint Audio Class Descriptor v2 */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmAttributes; + uint8_t bmControls; + uint8_t bLockDelayUnits; + uint16_t wLockDelay; +} __packed audio_iso_ac_endpoint_descriptor_2; + + + /* + * AUDIO interface + */ + +uint32 usb_audio_write_tx_data(const uint8* buf, uint32 len); +uint32 usb_audio_read_rx_data(uint8* buf, uint32 len); +uint8 usb_audio_init(uint16 type, uint16 rate); +void usb_audio_setEPSize(uint32_t size); +void audio_set_packet_callback(void (*callback)(uint8)); + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_AUDIO_H */ diff --git a/STM32F1/libraries/USBComposite/usb_composite_serial.c b/STM32F1/libraries/USBComposite/usb_composite_serial.c new file mode 100644 index 000000000..9f679bcfd --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_composite_serial.c @@ -0,0 +1,543 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/usb/stm32f1/usb_hid.c + * @brief USB HID (human interface device) support + * + * FIXME: this works on the STM32F1 USB peripherals, and probably no + * place else. Nonportable bits really need to be factored out, and + * the result made cleaner. + */ + +#include "usb_composite_serial.h" +#include "usb_generic.h" +#include +#include +#include +//#include + +/* Private headers */ +#include "usb_lib_globals.h" +#include "usb_reg_map.h" + +#define CDCACM_ENDPOINT_TX 0 +#define CDCACM_ENDPOINT_MANAGEMENT 1 +#define CDCACM_ENDPOINT_RX 2 + +#define USB_CDCACM_MANAGEMENT_ENDP (serialEndpoints[CDCACM_ENDPOINT_MANAGEMENT].address) +#define USB_CDCACM_TX_ENDP (serialEndpoints[CDCACM_ENDPOINT_TX].address) +#define USB_CDCACM_RX_ENDP (serialEndpoints[CDCACM_ENDPOINT_RX].address) +#define USB_CDCACM_MANAGEMENT_ENDPOINT_INFO (&serialEndpoints[CDCACM_ENDPOINT_MANAGEMENT]) +#define USB_CDCACM_TX_ENDPOINT_INFO (&serialEndpoints[CDCACM_ENDPOINT_TX]) +#define USB_CDCACM_RX_ENDPOINT_INFO (&serialEndpoints[CDCACM_ENDPOINT_RX]) + +/* usb_lib headers */ +#include "usb_type.h" +#include "usb_core.h" +#include "usb_def.h" + +static void serialUSBReset(void); +static RESULT serialUSBDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength); +static RESULT serialUSBNoDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex); +static void vcomDataTxCb(void); +static void vcomDataRxCb(void); + +#define NUM_SERIAL_ENDPOINTS 3 +#define CCI_INTERFACE_OFFSET 0x00 +#define DCI_INTERFACE_OFFSET 0x01 +//#define SERIAL_MANAGEMENT_INTERFACE_NUMBER (CCI_INTERFACE_OFFSET+usbSerialPart.startInterface) + +/* + * Descriptors + */ + +static volatile int8 transmitting; +static uint32_t txEPSize = 64; +static uint32_t rxEPSize = 64; + +typedef struct { + //CDCACM + IADescriptor IAD; + usb_descriptor_interface CCI_Interface; + CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader; + CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_CallManagement; + CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_ACM; + CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union; + usb_descriptor_endpoint ManagementEndpoint; + usb_descriptor_interface DCI_Interface; + usb_descriptor_endpoint DataOutEndpoint; + usb_descriptor_endpoint DataInEndpoint; +} __packed serial_part_config; + + +static const serial_part_config serialPartConfigData = { + .IAD = { + .bLength = 0x08, + .bDescriptorType = 0x0B, + .bFirstInterface = CCI_INTERFACE_OFFSET, // PATCH + .bInterfaceCount = 0x02, + .bFunctionClass = 0x02, + .bFunctionSubClass = 0x02, + .bFunctionProtocol = 0x01, + .iFunction = 0x02, + }, + .CCI_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = CCI_INTERFACE_OFFSET, // PATCH + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x01, + .bInterfaceClass = USB_INTERFACE_CLASS_CDC, + .bInterfaceSubClass = USB_INTERFACE_SUBCLASS_CDC_ACM, + .bInterfaceProtocol = 0x01, /* Common AT Commands */ + .iInterface = 0x00, + }, + + .CDC_Functional_IntHeader = { + .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2), + .bDescriptorType = 0x24, + .SubType = 0x00, + .Data = {0x01, 0x10}, + }, + + .CDC_Functional_CallManagement = { + .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2), + .bDescriptorType = 0x24, + .SubType = 0x01, + .Data = {0x03, DCI_INTERFACE_OFFSET}, // PATCH + }, + + .CDC_Functional_ACM = { + .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(1), + .bDescriptorType = 0x24, + .SubType = 0x02, + .Data = {0x06}, + }, + + .CDC_Functional_Union = { + .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2), + .bDescriptorType = 0x24, + .SubType = 0x06, + .Data = {CCI_INTERFACE_OFFSET, DCI_INTERFACE_OFFSET}, // PATCH, PATCH + }, + + .ManagementEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | + 0), // PATCH: CDCACM_ENDPOINT_MANAGEMENT + .bmAttributes = USB_EP_TYPE_INTERRUPT, + .wMaxPacketSize = USBHID_CDCACM_MANAGEMENT_EPSIZE, + .bInterval = 0xFF, + }, + + .DCI_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = DCI_INTERFACE_OFFSET, // PATCH + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x02, + .bInterfaceClass = USB_INTERFACE_CLASS_DIC, + .bInterfaceSubClass = 0x00, /* None */ + .bInterfaceProtocol = 0x00, /* None */ + .iInterface = 0x00, + }, + + .DataOutEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT | + 0), // patch: CDCACM_ENDPOINT_RX + .bmAttributes = USB_EP_TYPE_BULK, + .wMaxPacketSize = 64, // patch + .bInterval = 0x00, + }, + + .DataInEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | 0), // PATCH: CDCACM_ENDPOINT_TX + .bmAttributes = USB_EP_TYPE_BULK, + .wMaxPacketSize = 64, // patch + .bInterval = 0x00, + } +}; + +#define OUT_BYTE(s,v) out[(uint8*)&(s.v)-(uint8*)&s] +#define OUT_16(s,v) *(uint16_t*)&OUT_BYTE(s,v) // OK on Cortex which can handle unaligned writes + +static USBEndpointInfo serialEndpoints[3] = { + { + .callback = vcomDataTxCb, + .pmaSize = 64, // patch + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 1, + }, + { + .callback = NULL, + .pmaSize = USBHID_CDCACM_MANAGEMENT_EPSIZE, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 1, + }, + { + .callback = vcomDataRxCb, + .pmaSize = 64, // patch + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 0, + }, +}; + +static void getSerialPartDescriptor(uint8* out) { + memcpy(out, &serialPartConfigData, sizeof(serial_part_config)); + + // patch to reflect where the part goes in the descriptor + OUT_BYTE(serialPartConfigData, ManagementEndpoint.bEndpointAddress) += USB_CDCACM_MANAGEMENT_ENDP; + OUT_BYTE(serialPartConfigData, DataOutEndpoint.bEndpointAddress) += USB_CDCACM_RX_ENDP; + OUT_BYTE(serialPartConfigData, DataInEndpoint.bEndpointAddress) += USB_CDCACM_TX_ENDP; + + OUT_BYTE(serialPartConfigData, IAD.bFirstInterface) += usbSerialPart.startInterface; + OUT_BYTE(serialPartConfigData, CCI_Interface.bInterfaceNumber) += usbSerialPart.startInterface; + OUT_BYTE(serialPartConfigData, DCI_Interface.bInterfaceNumber) += usbSerialPart.startInterface; + OUT_BYTE(serialPartConfigData, CDC_Functional_CallManagement.Data[1]) += usbSerialPart.startInterface; + OUT_BYTE(serialPartConfigData, CDC_Functional_Union.Data[0]) += usbSerialPart.startInterface; + OUT_BYTE(serialPartConfigData, CDC_Functional_Union.Data[1]) += usbSerialPart.startInterface; + + OUT_16(serialPartConfigData, DataOutEndpoint.wMaxPacketSize) = rxEPSize; + OUT_16(serialPartConfigData, DataInEndpoint.wMaxPacketSize) = txEPSize; +} + +void composite_cdcacm_setTXEPSize(uint32_t size) { + if (size == 0) + size = 64; + serialEndpoints[0].pmaSize = size; + txEPSize = size; +} + +void composite_cdcacm_setRXEPSize(uint32_t size) { + if (size == 0) + size = 64; + size = usb_generic_roundUpToPowerOf2(size); + serialEndpoints[2].pmaSize = size; + rxEPSize = size; +} + +USBCompositePart usbSerialPart = { + .numInterfaces = 2, + .numEndpoints = sizeof(serialEndpoints)/sizeof(*serialEndpoints), + .descriptorSize = sizeof(serial_part_config), + .getPartDescriptor = getSerialPartDescriptor, + .usbInit = NULL, + .usbReset = serialUSBReset, + .usbDataSetup = serialUSBDataSetup, + .usbNoDataSetup = serialUSBNoDataSetup, + .endpoints = serialEndpoints +}; + +#define CDC_SERIAL_RX_BUFFER_SIZE 256 // must be power of 2 +#define CDC_SERIAL_RX_BUFFER_SIZE_MASK (CDC_SERIAL_RX_BUFFER_SIZE-1) + +/* Received data */ +static volatile uint8 vcomBufferRx[CDC_SERIAL_RX_BUFFER_SIZE]; +/* Write index to vcomBufferRx */ +static volatile uint32 vcom_rx_head; +/* Read index from vcomBufferRx */ +static volatile uint32 vcom_rx_tail; + +#define CDC_SERIAL_TX_BUFFER_SIZE 256 // must be power of 2 +#define CDC_SERIAL_TX_BUFFER_SIZE_MASK (CDC_SERIAL_TX_BUFFER_SIZE-1) +// Tx data +static volatile uint8 vcomBufferTx[CDC_SERIAL_TX_BUFFER_SIZE]; +// Write index to vcomBufferTx +static volatile uint32 vcom_tx_head; +// Read index from vcomBufferTx +static volatile uint32 vcom_tx_tail; + + + +/* Other state (line coding, DTR/RTS) */ + +static volatile composite_cdcacm_line_coding line_coding = { + /* This default is 115200 baud, 8N1. */ + .dwDTERate = 115200, + .bCharFormat = USBHID_CDCACM_STOP_BITS_1, + .bParityType = USBHID_CDCACM_PARITY_NONE, + .bDataBits = 8, +}; + +/* DTR in bit 0, RTS in bit 1. */ +static volatile uint8 line_dtr_rts = 0; + + +static void (*rx_hook)(unsigned, void*) = 0; +static void (*iface_setup_hook)(unsigned, void*) = 0; + +void composite_cdcacm_set_hooks(unsigned hook_flags, void (*hook)(unsigned, void*)) { + if (hook_flags & USBHID_CDCACM_HOOK_RX) { + rx_hook = hook; + } + if (hook_flags & USBHID_CDCACM_HOOK_IFACE_SETUP) { + iface_setup_hook = hook; + } +} + +/* This function is non-blocking. + * + * It copies data from a user buffer into the USB peripheral TX + * buffer, and returns the number of bytes copied. */ +uint32 composite_cdcacm_tx(const uint8* buf, uint32 len) +{ + if (len==0) return 0; // no data to send + + uint32 head = vcom_tx_head; // load volatile variable + uint32 tx_unsent = (head - vcom_tx_tail) & CDC_SERIAL_TX_BUFFER_SIZE_MASK; + + // We can only put bytes in the buffer if there is place + if (len > (CDC_SERIAL_TX_BUFFER_SIZE-tx_unsent-1) ) { + len = (CDC_SERIAL_TX_BUFFER_SIZE-tx_unsent-1); + } + if (len==0) return 0; // buffer full + + uint16 i; + // copy data from user buffer to USB Tx buffer + for (i=0; i= 0); + + if (transmitting < 0) { + vcomDataTxCb(); // initiate data transmission + } + + return len; +} + + + +uint32 composite_cdcacm_data_available(void) { + return (vcom_rx_head - vcom_rx_tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; +} + +uint16 composite_cdcacm_get_pending(void) { + return (vcom_tx_head - vcom_tx_tail) & CDC_SERIAL_TX_BUFFER_SIZE_MASK; +} + +/* Non-blocking byte receive. + * + * Copies up to len bytes from our private data buffer (*NOT* the PMA) + * into buf and deq's the FIFO. */ +uint32 composite_cdcacm_rx(uint8* buf, uint32 len) +{ + /* Copy bytes to buffer. */ + uint32 n_copied = composite_cdcacm_peek(buf, len); + + /* Mark bytes as read. */ + uint16 tail = vcom_rx_tail; // load volatile variable + tail = (tail + n_copied) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + vcom_rx_tail = tail; // store volatile variable + + uint32 rx_unread = (vcom_rx_head - tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + // If buffer was emptied to a pre-set value, re-enable the RX endpoint + if ( rx_unread <= 64 ) { // experimental value, gives the best performance + usb_generic_enable_rx(USB_CDCACM_RX_ENDPOINT_INFO); + } + return n_copied; +} + +/* Non-blocking byte lookahead. + * + * Looks at unread bytes without marking them as read. */ +uint32 composite_cdcacm_peek(uint8* buf, uint32 len) +{ + unsigned i; + uint32 tail = vcom_rx_tail; + uint32 rx_unread = (vcom_rx_head-tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + + if (len > rx_unread) { + len = rx_unread; + } + + for (i = 0; i < len; i++) { + buf[i] = vcomBufferRx[tail]; + tail = (tail + 1) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + } + + return len; +} + +uint32 composite_cdcacm_peek_ex(uint8* buf, uint32 offset, uint32 len) +{ + unsigned i; + uint32 tail = (vcom_rx_tail + offset) & CDC_SERIAL_RX_BUFFER_SIZE_MASK ; + uint32 rx_unread = (vcom_rx_head-tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + + if (len + offset > rx_unread) { + len = rx_unread - offset; + } + + for (i = 0; i < len; i++) { + buf[i] = vcomBufferRx[tail]; + tail = (tail + 1) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + } + + return len; +} + +/* Roger Clark. Added. for Arduino 1.0 API support of Serial.peek() */ +int composite_cdcacm_peek_char() +{ + if (composite_cdcacm_data_available() == 0) + { + return -1; + } + + return vcomBufferRx[vcom_rx_tail]; +} + +uint8 composite_cdcacm_get_dtr() { + return ((line_dtr_rts & USBHID_CDCACM_CONTROL_LINE_DTR) != 0); +} + +uint8 composite_cdcacm_get_rts() { + return ((line_dtr_rts & USBHID_CDCACM_CONTROL_LINE_RTS) != 0); +} + +void composite_cdcacm_get_line_coding(composite_cdcacm_line_coding *ret) { + ret->dwDTERate = line_coding.dwDTERate; + ret->bCharFormat = line_coding.bCharFormat; + ret->bParityType = line_coding.bParityType; + ret->bDataBits = line_coding.bDataBits; +} + +int composite_cdcacm_get_baud(void) { + return line_coding.dwDTERate; +} + +int composite_cdcacm_get_stop_bits(void) { + return line_coding.bCharFormat; +} + +int composite_cdcacm_get_parity(void) { + return line_coding.bParityType; +} + +int composite_cdcacm_get_n_data_bits(void) { + return line_coding.bDataBits; +} + +/* + * Callbacks + */ +static void vcomDataTxCb(void) +{ + usb_generic_send_from_circular_buffer(USB_CDCACM_TX_ENDPOINT_INFO, + vcomBufferTx, CDC_SERIAL_TX_BUFFER_SIZE, vcom_tx_head, &vcom_tx_tail, &transmitting); +} + + +static void vcomDataRxCb(void) +{ + uint32 head = vcom_rx_head; + usb_generic_read_to_circular_buffer(USB_CDCACM_RX_ENDPOINT_INFO, + vcomBufferRx, CDC_SERIAL_RX_BUFFER_SIZE, &head); + vcom_rx_head = head; // store volatile variable + + uint32 rx_unread = (head - vcom_rx_tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + // only enable further Rx if there is enough room to receive one more packet + if ( rx_unread < (CDC_SERIAL_RX_BUFFER_SIZE-rxEPSize) ) { + usb_generic_enable_rx(USB_CDCACM_RX_ENDPOINT_INFO); + } + + if (rx_hook) { + rx_hook(USBHID_CDCACM_HOOK_RX, 0); + } +} + +static void serialUSBReset(void) { + //VCOM + vcom_rx_head = 0; + vcom_rx_tail = 0; + vcom_tx_head = 0; + vcom_tx_tail = 0; + transmitting = -1; +} + +#pragma GCC diagnostic ignored "-Wunused-parameter" +static RESULT serialUSBDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength) { + RESULT ret = USB_UNSUPPORT; + + if ((requestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT) && interface == CCI_INTERFACE_OFFSET) { + switch (request) { + case USBHID_CDCACM_GET_LINE_CODING: + usb_generic_control_tx_setup(&line_coding, sizeof(line_coding), NULL); + ret = USB_SUCCESS; + break; + case USBHID_CDCACM_SET_LINE_CODING: + usb_generic_control_rx_setup(&line_coding, sizeof(line_coding), NULL); + ret = USB_SUCCESS; + break; + default: + break; + } + /* Call the user hook. */ + if (iface_setup_hook) { + uint8 req_copy = request; + iface_setup_hook(USBHID_CDCACM_HOOK_IFACE_SETUP, &req_copy); + } + } + + return ret; +} + +static RESULT serialUSBNoDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex) { + RESULT ret = USB_UNSUPPORT; + + if ((requestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT) && interface == CCI_INTERFACE_OFFSET) { + switch(request) { + case USBHID_CDCACM_SET_COMM_FEATURE: + /* We support set comm. feature, but don't handle it. */ + ret = USB_SUCCESS; + break; + case USBHID_CDCACM_SET_CONTROL_LINE_STATE: + /* Track changes to DTR and RTS. */ + line_dtr_rts = (wValue0 & + (USBHID_CDCACM_CONTROL_LINE_DTR | + USBHID_CDCACM_CONTROL_LINE_RTS)); + ret = USB_SUCCESS; + break; + } + /* Call the user hook. */ + if (iface_setup_hook) { + uint8 req_copy = request; + iface_setup_hook(USBHID_CDCACM_HOOK_IFACE_SETUP, &req_copy); + } + } + return ret; +} + diff --git a/STM32F1/libraries/USBComposite/usb_composite_serial.h b/STM32F1/libraries/USBComposite/usb_composite_serial.h new file mode 100644 index 000000000..e049ab368 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_composite_serial.h @@ -0,0 +1,153 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/include/libmaple/usb_device.h + * @brief USB Composite with CDC ACM and HID support + * + * IMPORTANT: this API is unstable, and may change without notice. + */ + +#ifndef _USB_SERIAL_H_ +#define _USB_SERIAL_H_ + +#include +#include +#include "usb_generic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern USBCompositePart usbSerialPart; + +/* + * CDC ACM Requests + */ + +#define USBHID_CDCACM_SET_LINE_CODING 0x20 +#define USBHID_CDCACM_GET_LINE_CODING 0x21 +#define USBHID_CDCACM_SET_COMM_FEATURE 0x02 +#define USBHID_CDCACM_SET_CONTROL_LINE_STATE 0x22 +#define USBHID_CDCACM_CONTROL_LINE_DTR (0x01) +#define USBHID_CDCACM_CONTROL_LINE_RTS (0x02) + +#define USBHID_CDCACM_MANAGEMENT_EPSIZE 0x10 +//#define USBHID_CDCACM_RX_EPSIZE 0x40 +//#define USBHID_CDCACM_TX_EPSIZE 0x40 +/* + * Descriptors, etc. + */ + + + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +} IADescriptor; + +#define CDC_FUNCTIONAL_DESCRIPTOR_SIZE(DataSize) (3 + DataSize) +#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \ + struct { \ + uint8 bLength; \ + uint8 bDescriptorType; \ + uint8 SubType; \ + uint8 Data[DataSize]; \ + } __packed + +#define USB_DEVICE_CLASS_CDC 0x02 +#define USB_DEVICE_SUBCLASS_CDC 0x00 +#define USB_INTERFACE_CLASS_CDC 0x02 +#define USB_INTERFACE_SUBCLASS_CDC_ACM 0x02 +#define USB_INTERFACE_CLASS_DIC 0x0A + +/* + * CDC ACM interface + */ + +uint32 composite_cdcacm_tx(const uint8* buf, uint32 len); +uint32 composite_cdcacm_rx(uint8* buf, uint32 len); +uint32 composite_cdcacm_peek(uint8* buf, uint32 len); +uint32 composite_cdcacm_peek_ex(uint8* buf, uint32 offset, uint32 len); +void composite_cdcacm_setTXEPSize(uint32_t size); +void composite_cdcacm_setRXEPSize(uint32_t size); + +uint32 composite_cdcacm_data_available(void); /* in RX buffer */ +uint16 composite_cdcacm_get_pending(void); + +uint8 composite_cdcacm_get_dtr(void); +uint8 composite_cdcacm_get_rts(void); + +typedef struct composite_cdcacm_line_coding { + uint32 dwDTERate; /* Baud rate */ + +#define USBHID_CDCACM_STOP_BITS_1 0 +#define USBHID_CDCACM_STOP_BITS_1_5 1 +#define USBHID_CDCACM_STOP_BITS_2 2 + uint8 bCharFormat; /* Stop bits */ + +#define USBHID_CDCACM_PARITY_NONE 0 +#define USBHID_CDCACM_PARITY_ODD 1 +#define USBHID_CDCACM_PARITY_EVEN 2 +#define USBHID_CDCACM_PARITY_MARK 3 +#define USBHID_CDCACM_PARITY_SPACE 4 + uint8 bParityType; /* Parity type */ + + uint8 bDataBits; /* Data bits: 5, 6, 7, 8, or 16 */ +} __packed composite_cdcacm_line_coding; + +/* Retrieve a copy of the current line coding structure. */ +void composite_cdcacm_get_line_coding(composite_cdcacm_line_coding*); + +/* Line coding conveniences. */ +int composite_cdcacm_get_baud(void); /* dwDTERate */ +int composite_cdcacm_get_stop_bits(void); /* bCharFormat */ +int composite_cdcacm_get_parity(void); /* bParityType */ +int composite_cdcacm_get_n_data_bits(void); /* bDataBits */ + +/* + * Hack: hooks for bootloader reset signalling + */ + +#define USBHID_CDCACM_HOOK_RX 0x1 +#define USBHID_CDCACM_HOOK_IFACE_SETUP 0x2 + +void composite_cdcacm_set_hooks(unsigned hook_flags, void (*hook)(unsigned, void*)); + +#define composite_cdcacm_remove_hooks(hook_flags) composite_cdcacm_remove_hooks(hook_flags, 0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/STM32F1/libraries/USBComposite/usb_generic.c b/STM32F1/libraries/USBComposite/usb_generic.c new file mode 100644 index 000000000..96b617c9c --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_generic.c @@ -0,0 +1,917 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/usb/stm32f1/usb_hid.c + * @brief USB HID (human interface device) support + * + * FIXME: this works on the STM32F1 USB peripherals, and probably no + * place else. Nonportable bits really need to be factored out, and + * the result made cleaner. + */ + +//#define MATCHING_ENDPOINT_RANGES // make RX and TX endpoints fall in the same range for each part + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + + + +/* usb_lib headers */ +#include "usb_type.h" +#include "usb_core.h" +#include "usb_def.h" + +#include "usb_generic.h" + +const char DEFAULT_PRODUCT[] = "Maple"; +const char DEFAULT_MANUFACTURER[] = "LeafLabs"; + +static uint8* usbGetConfigDescriptor(uint16 length); +static void usbInit(void); +static void usbReset(void); +static void usbClearFeature(void); +static void usbSetConfiguration(void); +static RESULT usbDataSetup(uint8 request); +static RESULT usbNoDataSetup(uint8 request); +static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting); +static uint8* usbGetStringDescriptor(uint16 length); +static uint8* usbGetConfigDescriptor(uint16 length); +static uint8* usbGetDeviceDescriptor(uint16 length); +static void usbSetConfiguration(void); +static void usbSetDeviceAddress(void); +static uint32 disconnect_delay = 500; // in microseconds + +static struct usb_chunk* control_tx_chunk_list = NULL; +static uint8 control_tx_chunk_buffer[USB_EP0_BUFFER_SIZE]; + +static volatile uint8* control_tx_buffer = NULL; +static uint16 control_tx_length = 0; +static volatile uint8* control_tx_done = NULL; +static volatile uint8* control_rx_buffer = NULL; +static uint16 control_rx_length = 0; +static volatile uint8* control_rx_done = NULL; + +uint16 epTypes[4] = { + USB_EP_EP_TYPE_BULK, + USB_EP_EP_TYPE_CONTROL, + USB_EP_EP_TYPE_ISO, + USB_EP_EP_TYPE_INTERRUPT +}; + +#define LEAFLABS_ID_VENDOR 0x1EAF +#define MAPLE_ID_PRODUCT 0x0024 // was 0x0024 +#define USB_DEVICE_CLASS 0x00 +#define USB_DEVICE_SUBCLASS 0x00 +#define DEVICE_PROTOCOL 0x01 +//#define REQUEST_TYPE 0b01100000u +#define REQUEST_RECIPIENT 0b00011111u + +static usb_descriptor_device usbGenericDescriptor_Device = + { + .bLength = sizeof(usb_descriptor_device), + .bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = USB_DEVICE_CLASS, + .bDeviceSubClass = USB_DEVICE_SUBCLASS, + .bDeviceProtocol = DEVICE_PROTOCOL, + .bMaxPacketSize0 = 0x40, + .idVendor = LEAFLABS_ID_VENDOR, + .idProduct = MAPLE_ID_PRODUCT, + .bcdDevice = 0x0200, + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x00, + .bNumConfigurations = 0x01, +}; + +typedef struct { + usb_descriptor_config_header Config_Header; + uint8 descriptorData[MAX_USB_DESCRIPTOR_DATA_SIZE]; +} __packed usb_descriptor_config; + +static usb_descriptor_config usbConfig; + +#define MAX_POWER (100 >> 1) + +static const usb_descriptor_config_header Base_Header = { + .bLength = sizeof(usb_descriptor_config_header), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 0, + .bConfigurationValue = 0x01, + .iConfiguration = 0x00, + .bmAttributes = (USB_CONFIG_ATTR_BUSPOWERED | + USB_CONFIG_ATTR_SELF_POWERED), + .bMaxPower = MAX_POWER, +}; + +static ONE_DESCRIPTOR Device_Descriptor = { + (uint8*)&usbGenericDescriptor_Device, + sizeof(usb_descriptor_device) +}; + +static ONE_DESCRIPTOR Config_Descriptor = { + (uint8*)&usbConfig, + 0 +}; + +static DEVICE my_Device_Table = { + .Total_Endpoint = 0, + .Total_Configuration = 1 +}; + +/* Unicode language identifier: 0x0409 is US English */ +static const usb_descriptor_string usb_LangID = { + .bLength = USB_DESCRIPTOR_STRING_LEN(1), + .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING, + .bString = {0x09, 0x04}, +}; + +static USB_DESCRIPTOR_STRING(USB_DESCRIPTOR_STRING_LEN(USB_MAX_STRING_DESCRIPTOR_LENGTH)) string_descriptor_buffer = { + .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING +}; + +static ONE_DESCRIPTOR generic_string_descriptor = { + (uint8*)&string_descriptor_buffer, 0 +}; + +#define MAX_PACKET_SIZE 0x40 /* 64B, maximum for USB FS Devices */ +static const DEVICE_PROP my_Device_Property = { + .Init = usbInit, + .Reset = usbReset, + .Process_Status_IN = NOP_Process, + .Process_Status_OUT = NOP_Process, + .Class_Data_Setup = usbDataSetup, + .Class_NoData_Setup = usbNoDataSetup, + .Class_Get_Interface_Setting = usbGetInterfaceSetting, + .GetDeviceDescriptor = usbGetDeviceDescriptor, + .GetConfigDescriptor = usbGetConfigDescriptor, + .GetStringDescriptor = usbGetStringDescriptor, + .RxEP_buffer = NULL, + .MaxPacketSize = MAX_PACKET_SIZE +}; + +static const USER_STANDARD_REQUESTS my_User_Standard_Requests = { + .User_GetConfiguration = NOP_Process, + .User_SetConfiguration = usbSetConfiguration, + .User_GetInterface = NOP_Process, + .User_SetInterface = NOP_Process, + .User_GetStatus = NOP_Process, + .User_ClearFeature = usbClearFeature, + .User_SetEndPointFeature = NOP_Process, + .User_SetDeviceFeature = NOP_Process, + .User_SetDeviceAddress = usbSetDeviceAddress +}; + +static uint8 numStringDescriptors = 3; + + +#define MAX_STRING_DESCRIPTORS 4 +static ONE_DESCRIPTOR String_Descriptor[MAX_STRING_DESCRIPTORS] = { + {(uint8*)&usb_LangID, USB_DESCRIPTOR_STRING_LEN(1)}, + {(uint8*)DEFAULT_MANUFACTURER, 0}, // a 0 in the length field indicates that we synthesize this from an asciiz string + {(uint8*)DEFAULT_PRODUCT, 0}, + {NULL, 0}, +}; + +static USBCompositePart** parts; +static uint32 numParts; +static DEVICE saved_Device_Table; +static DEVICE_PROP saved_Device_Property; +static USER_STANDARD_REQUESTS saved_User_Standard_Requests; + +static void (*ep_int_in[7])(void); +static void (*ep_int_out[7])(void); + +static uint8 minimum_address; + +static uint8 acceptable_endpoint_number(unsigned partNum, unsigned endpointNum, uint8 address) { + USBEndpointInfo* ep = &(parts[partNum]->endpoints[endpointNum]); + for (unsigned i = 0 ; i <= partNum ; i++) + for(unsigned j = 0 ; (i < partNum && j < parts[partNum]->numEndpoints) || (i == partNum && j < endpointNum) ; j++) { + USBEndpointInfo* ep1 = &(parts[i]->endpoints[j]); + if (ep1->address != address) + continue; + if (ep1->tx == ep->tx || ep->exclusive || ep1->exclusive || ep1->type != ep->type || ep1->doubleBuffer != ep->doubleBuffer) + return 0; + } + return 1; +} + +static int8 allocate_endpoint_address(unsigned partNum, unsigned endpointNum) { + for (uint8 address = minimum_address ; address < 8 ; address++) + if (acceptable_endpoint_number(partNum, endpointNum, address)) + return address; + return -1; +} + +uint8 usb_generic_set_parts(USBCompositePart** _parts, unsigned _numParts) { + parts = _parts; + numParts = _numParts; + unsigned numInterfaces = 0; + minimum_address = 1; + uint8 maxAddress = 0; + + uint16 usbDescriptorSize = 0; + uint16 pmaOffset = USB_EP0_RX_BUFFER_ADDRESS + USB_EP0_BUFFER_SIZE; + + for (unsigned i = 0 ; i < 7 ; i++) { + ep_int_in[i] = NOP_Process; + ep_int_out[i] = NOP_Process; + } + + usbDescriptorSize = 0; + for (unsigned i = 0 ; i < _numParts ; i++ ) { + USBCompositePart* part = parts[i]; + part->startInterface = numInterfaces; + numInterfaces += part->numInterfaces; + if (usbDescriptorSize + part->descriptorSize > MAX_USB_DESCRIPTOR_DATA_SIZE) { + return 0; + } + USBEndpointInfo* ep = part->endpoints; + for (unsigned j = 0 ; j < part->numEndpoints ; j++) { + if (ep[j].align) + minimum_address = maxAddress + 1; + int8 address = allocate_endpoint_address(i, j); + if (address < 0) + return 0; + + ep[j].pma = usb_pma_ptr(pmaOffset); + uint32 size = ep[j].pmaSize; + // rx has special length alignment issues + if (ep[j].doubleBuffer) { + if (size <= 124 || ep[j].tx) { + size = (size+3)/4*4; + } + else { + size = (size+63)/64*64; + } + } + else { + if (size <= 62 || ep[j].tx) { + size = (size+1)/2*2; + } + else { + size = (size+31)/32*32; + } + } + pmaOffset += size; + if (pmaOffset > PMA_MEMORY_SIZE) + return 0; + if (ep[j].callback == NULL) + ep[j].callback = NOP_Process; + ep[j].address = address; + if (ep[j].tx) { + ep_int_in[address-1] = ep[j].callback; + } + else { + ep_int_out[address-1] = ep[j].callback; + } + if (maxAddress < address) + maxAddress = address; + } + part->getPartDescriptor(usbConfig.descriptorData + usbDescriptorSize); + usbDescriptorSize += part->descriptorSize; +#ifdef MATCHING_ENDPOINT_RANGES + minimum_address = maxAddress + 1; +#endif + } + + usbConfig.Config_Header = Base_Header; + usbConfig.Config_Header.bNumInterfaces = numInterfaces; + usbConfig.Config_Header.wTotalLength = usbDescriptorSize + sizeof(Base_Header); + Config_Descriptor.Descriptor_Size = usbConfig.Config_Header.wTotalLength; + + my_Device_Table.Total_Endpoint = maxAddress + 1; + + return 1; +} + +void usb_generic_set_info(uint16 idVendor, uint16 idProduct, const char* iManufacturer, const char* iProduct, const char* iSerialNumber) { + if (idVendor != 0) + usbGenericDescriptor_Device.idVendor = idVendor; + else + usbGenericDescriptor_Device.idVendor = LEAFLABS_ID_VENDOR; + + if (idProduct != 0) + usbGenericDescriptor_Device.idProduct = idProduct; + else + usbGenericDescriptor_Device.idProduct = MAPLE_ID_PRODUCT; + + if (iManufacturer == NULL) { + iManufacturer = DEFAULT_MANUFACTURER; + } + + String_Descriptor[1].Descriptor = (uint8*)iManufacturer; + String_Descriptor[1].Descriptor_Size = 0; + + if (iProduct == NULL) { + iProduct = DEFAULT_PRODUCT; + } + + String_Descriptor[2].Descriptor = (uint8*)iProduct; + String_Descriptor[2].Descriptor_Size = 0; + + if (iSerialNumber == NULL) { + numStringDescriptors = 3; + usbGenericDescriptor_Device.iSerialNumber = 0; + } + else { + String_Descriptor[3].Descriptor = (uint8*)iSerialNumber; + String_Descriptor[3].Descriptor_Size = 0; + numStringDescriptors = 4; + usbGenericDescriptor_Device.iSerialNumber = 3; + } +} + +void usb_generic_enable(void) { + /* Present ourselves to the host. Writing 0 to "disc" pin must + * pull USB_DP pin up while leaving USB_DM pulled down by the + * transceiver. See USB 2.0 spec, section 7.1.7.3. */ + +#ifdef GENERIC_BOOTLOADER + //Reset the USB interface on generic boards - developed by Victor PV + gpio_set_mode(GPIOA, 12, GPIO_OUTPUT_PP); + gpio_write_bit(GPIOA, 12, 0); + + delay_us(disconnect_delay); + gpio_set_mode(GPIOA, 12, GPIO_INPUT_FLOATING); +#endif + + if (BOARD_USB_DISC_DEV != NULL) { + gpio_set_mode(BOARD_USB_DISC_DEV, (uint8)(uint32)BOARD_USB_DISC_BIT, GPIO_OUTPUT_PP); + gpio_write_bit(BOARD_USB_DISC_DEV, (uint8)(uint32)BOARD_USB_DISC_BIT, 0); + } + + saved_Device_Table = Device_Table; + saved_Device_Property = Device_Property; + saved_User_Standard_Requests = User_Standard_Requests; + Device_Table = my_Device_Table; + Device_Property = my_Device_Property; + User_Standard_Requests = my_User_Standard_Requests; + + /* Initialize the USB peripheral. */ + usb_init_usblib(USBLIB, ep_int_in, ep_int_out); +} + +void usb_generic_set_disconnect_delay(uint32 delay) { + disconnect_delay = delay; +} + +static void usbInit(void) { + pInformation->Current_Configuration = 0; + + USB_BASE->CNTR = USB_CNTR_FRES; + + USBLIB->irq_mask = 0; + USB_BASE->CNTR = USBLIB->irq_mask; + USB_BASE->ISTR = 0; + USBLIB->irq_mask = USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + USB_BASE->CNTR = USBLIB->irq_mask; + + USB_BASE->ISTR = 0; + USBLIB->irq_mask = USB_ISR_MSK; + USB_BASE->CNTR = USBLIB->irq_mask; + + usb_generic_enable_interrupts_ep0(); + + for (unsigned i = 0 ; i < numParts ; i++) + if(parts[i]->usbInit != NULL) + parts[i]->usbInit(); + + USBLIB->state = USB_UNCONNECTED; +} + +#define BTABLE_ADDRESS 0x00 + +static inline uint16 pma_ptr_to_offset(uint32* p) { + return (uint16)(((uint32*)p-(uint32*)USB_PMA_BASE) * 2); +} + +static void usbReset(void) { + pInformation->Current_Configuration = 0; + + /* current feature is current bmAttributes */ + pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED | + USB_CONFIG_ATTR_SELF_POWERED); + + USB_BASE->BTABLE = BTABLE_ADDRESS; + + /* setup control endpoint 0 */ + usb_set_ep_type(USB_EP0, USB_EP_EP_TYPE_CONTROL); + usb_set_ep_tx_stat(USB_EP0, USB_EP_STAT_TX_STALL); + usb_set_ep_rx_addr(USB_EP0, USB_EP0_RX_BUFFER_ADDRESS); + usb_set_ep_tx_addr(USB_EP0, USB_EP0_TX_BUFFER_ADDRESS); + usb_clear_status_out(USB_EP0); + + usb_set_ep_rx_count(USB_EP0, USB_EP0_BUFFER_SIZE); + usb_set_ep_rx_stat(USB_EP0, USB_EP_STAT_RX_VALID); + + for (unsigned i = 1 ; i < 8 ; i++) { + usb_set_ep_rx_stat(i, USB_EP_STAT_RX_DISABLED); + usb_clear_ep_dtog_rx(i); + usb_set_ep_tx_stat(i, USB_EP_STAT_TX_DISABLED); + usb_clear_ep_dtog_tx(i); + } + + for (unsigned i = 0 ; i < numParts ; i++) { + for (unsigned j = 0 ; j < parts[i]->numEndpoints ; j++) { + USBEndpointInfo* e = &(parts[i]->endpoints[j]); + uint8 address = e->address; + usb_set_ep_type(address, epTypes[e->type]); + usb_set_ep_kind(address, e->doubleBuffer ? USB_EP_EP_KIND_DBL_BUF : 0); + uint16 pmaOffset = pma_ptr_to_offset(e->pma); + if (e->tx) { + usb_set_ep_tx_addr(address, pmaOffset); + usb_set_ep_tx_stat(address, USB_EP_STAT_TX_NAK); + if (e->doubleBuffer) { + usb_set_ep_tx_buf0_addr(address, pmaOffset); + usb_set_ep_tx_buf1_addr(address, pmaOffset+e->pmaSize/2); + usb_set_ep_tx_buf0_count(address, e->pmaSize/2); + usb_set_ep_tx_buf1_count(address, e->pmaSize/2); + } + } + else { + usb_set_ep_rx_addr(address, pmaOffset); + if (! e->doubleBuffer) { + usb_set_ep_rx_count(address, e->pmaSize); + } + usb_set_ep_rx_stat(address, USB_EP_STAT_RX_VALID); + } + } + if (parts[i]->usbReset != NULL) + parts[i]->usbReset(); + } + + control_rx_length = 0; + control_tx_length = 0; + + USBLIB->state = USB_ATTACHED; + SetDeviceAddress(0); + +} + +static void usb_power_down(void) { + USB_BASE->CNTR = USB_CNTR_FRES; + USB_BASE->ISTR = 0; + USB_BASE->CNTR = USB_CNTR_FRES + USB_CNTR_PDWN; +} + +void usb_generic_disable(void) { + /* Turn off the interrupt and signal disconnect (see e.g. USB 2.0 + * spec, section 7.1.7.3). */ + usb_generic_disable_interrupts_ep0(); + + if (BOARD_USB_DISC_DEV != NULL) { + gpio_write_bit(BOARD_USB_DISC_DEV, (uint8)(uint32)BOARD_USB_DISC_BIT, 1); + } + + usb_power_down(); + + Device_Table = saved_Device_Table; + Device_Property = saved_Device_Property; + User_Standard_Requests = saved_User_Standard_Requests; + + for (uint32 i=0; i < numParts; i++) + if (parts[i]->clear) + parts[i]->clear(); +} + +static uint8* control_data_tx(uint16 length) { + unsigned wOffset = pInformation->Ctrl_Info.Usb_wOffset; + + if (length == 0) { + pInformation->Ctrl_Info.Usb_wLength = control_tx_length - wOffset; + return NULL; + } + + if (control_tx_done && pInformation->USBwLengths.w <= wOffset + pInformation->Ctrl_Info.PacketSize) { + *control_tx_done = USB_CONTROL_DONE; // this may be a bit premature, but it's our best try + } + + if (control_tx_buffer == NULL) + return NULL; + else + return (uint8*)control_tx_buffer + wOffset; +} + +void usb_generic_control_tx_setup(volatile void* buffer, uint16 length, volatile uint8* done) { + control_tx_buffer = buffer; + control_tx_length = length; + control_tx_done = done; + pInformation->Ctrl_Info.CopyData = control_data_tx; + pInformation->Ctrl_Info.Usb_wOffset = 0; + control_data_tx(0); +} + +uint32 usb_generic_chunks_length(struct usb_chunk* chunk) { + uint32 l=0; + + while (chunk != NULL) { + l += chunk->dataLength; + chunk = chunk->next; + } + + return l; +} + +static uint8* control_data_chunk_tx(uint16 length) { + unsigned wOffset = pInformation->Ctrl_Info.Usb_wOffset; + + if (length == 0) { + pInformation->Ctrl_Info.Usb_wLength = usb_generic_chunks_length(control_tx_chunk_list) - wOffset; + + return NULL; + } + + if (control_tx_chunk_list == NULL) { + return NULL; + } + else { + uint32 chunks_offset = 0; + uint32 buf_offset = 0; + + for (struct usb_chunk* chunk = control_tx_chunk_list ; chunk != NULL && chunks_offset < wOffset + length ; chunk = chunk->next ) { + uint32 len = chunk->dataLength; + + if (len == 0) + continue; + + if (wOffset < chunks_offset + len) { + /* need to copy some data from this chunk */ + uint32 start; + if (wOffset <= chunks_offset) { + start = 0; + } + else { + start = wOffset - chunks_offset; + } + + uint32 to_copy; + if (wOffset + length <= chunks_offset + len) { + to_copy = wOffset + length - chunks_offset - start; + } + else { + to_copy = len - start; + } + + memcpy(control_tx_chunk_buffer + buf_offset, chunk->data + start, to_copy); + buf_offset += to_copy; + } + + chunks_offset += len; + } + + return (uint8*)control_tx_chunk_buffer; + } +} + +void usb_generic_control_tx_chunk_setup(struct usb_chunk* chunk) { + control_tx_chunk_list = chunk; + pInformation->Ctrl_Info.CopyData = control_data_chunk_tx; + pInformation->Ctrl_Info.Usb_wOffset = 0; + control_data_chunk_tx(0); +} + +static uint8* control_data_rx(uint16 length) { + unsigned wOffset = pInformation->Ctrl_Info.Usb_wOffset; + + if (length ==0) { + uint16 len = pInformation->USBwLengths.w; + if (len > control_rx_length) + len = control_rx_length; + + if (wOffset < len) { + pInformation->Ctrl_Info.Usb_wLength = len - wOffset; + } + else { + pInformation->Ctrl_Info.Usb_wLength = 0; + } + + return NULL; + } + + if (control_rx_done && pInformation->USBwLengths.w <= wOffset + pInformation->Ctrl_Info.PacketSize) { + *control_rx_done = USB_CONTROL_DONE; // this may be a bit premature, but it's our best try + } + + if (control_rx_buffer == NULL) + return NULL; + else + return (uint8*)control_rx_buffer + wOffset; +} + +void usb_generic_control_rx_setup(volatile void* buffer, uint16 length, volatile uint8* done) { + control_rx_buffer = buffer; + control_rx_length = length; + control_rx_done = done; + pInformation->Ctrl_Info.CopyData = control_data_rx; + pInformation->Ctrl_Info.Usb_wOffset = 0; + control_data_rx(0); +} + +void usb_generic_control_descriptor_tx(ONE_DESCRIPTOR* d) { + usb_generic_control_tx_setup(d->Descriptor, d->Descriptor_Size, NULL); +} + +static RESULT usbDataSetup(uint8 request) { + if ((Type_Recipient & REQUEST_RECIPIENT) == INTERFACE_RECIPIENT) { + uint8 interface = pInformation->USBwIndex0; + for (unsigned i = 0 ; i < numParts ; i++) { + USBCompositePart* p = parts[i]; + if (p->usbDataSetup && p->startInterface <= interface && interface < p->startInterface + p->numInterfaces) { + // uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength + return parts[i]->usbDataSetup(request, interface - p->startInterface, pInformation->USBbmRequestType, pInformation->USBwValue0, + pInformation->USBwValue1, pInformation->USBwIndex, pInformation->USBwLength); + } + } + } + + return USB_UNSUPPORT; + +} + +static RESULT usbNoDataSetup(uint8 request) { + if ((Type_Recipient & REQUEST_RECIPIENT) == INTERFACE_RECIPIENT) { + uint8 interface = pInformation->USBwIndex0; + + for (unsigned i = 0 ; i < numParts ; i++) { + USBCompositePart* p = parts[i]; + // uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength + if (p->usbNoDataSetup && p->startInterface <= interface && interface < p->startInterface + p->numInterfaces) + return parts[i]->usbNoDataSetup(request, interface - p->startInterface, pInformation->USBbmRequestType, pInformation->USBwValue0, + pInformation->USBwValue1, pInformation->USBwIndex); + } + } + + return USB_UNSUPPORT; +} + +static void usbSetConfiguration(void) { + if (pInformation->Current_Configuration != 0) { + USBLIB->state = USB_CONFIGURED; + } + for (unsigned i = 0 ; i < numParts ; i++) { + if (parts[i]->usbSetConfiguration != NULL) + parts[i]->usbSetConfiguration(); + } +} + +static void usbClearFeature(void) { + for (unsigned i = 0 ; i < numParts ; i++) { + if (parts[i]->usbClearFeature != NULL) + parts[i]->usbClearFeature(); + } +} + +static void usbSetDeviceAddress(void) { + USBLIB->state = USB_ADDRESSED; +} + +static uint8* usbGetDeviceDescriptor(uint16 length) { + return Standard_GetDescriptorData(length, &Device_Descriptor); +} + +static uint8* usbGetConfigDescriptor(uint16 length) { + return Standard_GetDescriptorData(length, &Config_Descriptor); +} + +static uint8* usbGetStringDescriptor(uint16 length) { + uint8 wValue0 = pInformation->USBwValue0; + + if (wValue0 >= numStringDescriptors) { + return NULL; + } + + ONE_DESCRIPTOR* d = &String_Descriptor[wValue0]; + if (d->Descriptor_Size != 0) { + return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]); + } + else { + const char* s = (char*)d->Descriptor; + + uint32 i = 0; + + while(*s && i < USB_MAX_STRING_DESCRIPTOR_LENGTH) { + string_descriptor_buffer.bString[i] = (uint8)*s; + s++; + i++; + } + + string_descriptor_buffer.bLength = USB_DESCRIPTOR_STRING_LEN(i); + generic_string_descriptor.Descriptor_Size = string_descriptor_buffer.bLength; + if (length > string_descriptor_buffer.bLength) + length = string_descriptor_buffer.bLength; + return Standard_GetDescriptorData(length, &generic_string_descriptor); + } +} + + +static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) { + if (alt_setting > 1) { + return USB_UNSUPPORT; + } else if (interface >= usbConfig.Config_Header.bNumInterfaces) { + return USB_UNSUPPORT; + } + + return USB_SUCCESS; +} + +void usb_copy_to_pma_ptr(volatile const uint8 *buf, uint16 len, uint32* dst) { + uint16 n = len >> 1; + uint16 i; + for (i = 0; i < n; i++) { + *(uint16*)dst = (uint16)(*buf) | *(buf + 1) << 8; + buf += 2; + dst++; + } + if (len & 1) { + *dst = *buf; + } +} + +void usb_copy_from_pma_ptr(volatile uint8 *buf, uint16 len, uint32* src) { + uint16 *dst = (uint16*)buf; + uint16 n = len >> 1; + uint16 i; + for (i = 0; i < n; i++) { + *dst++ = *src++; + } + if (len & 1) { + *dst = *src & 0xFF; + } +} + +// return bytes read +uint32 usb_generic_read_to_circular_buffer(USBEndpointInfo* ep, volatile uint8* buf, uint32 circularBufferSize, volatile uint32* headP) { + uint32 head = *headP; + uint32 ep_rx_size = usb_get_ep_rx_count(ep->address); + /* This copy won't overwrite unread bytes as long as there is + * enough room in the USB Rx buffer for next packet */ + volatile uint32 *src = ep->pma; + + for (uint32 i = 0; i < ep_rx_size; i++) { + uint16 tmp = *src++; + buf[head] = (uint8)tmp; + head = (head + 1) % circularBufferSize; + i++; + if (i >= ep_rx_size) { + break; + } + buf[head] = (uint8)(tmp>>8); + head = (head + 1) % circularBufferSize; + } + + *headP = head; + + return ep_rx_size; +} + +// returns number of bytes read +// buf should be uint16-aligned +uint32 usb_generic_read_to_buffer(USBEndpointInfo* ep, volatile uint8* buf, uint32 bufferSize) { + uint32 ep_rx_size = usb_get_ep_rx_count(ep->address); + if (ep_rx_size > bufferSize) + ep_rx_size = bufferSize; + usb_copy_from_pma_ptr(buf, ep_rx_size, ep->pma); + return ep_rx_size; +} + +uint32 usb_generic_send_from_buffer(USBEndpointInfo* ep, volatile uint8* buf, uint32 amount) { + if (amount > ep->pmaSize) + amount = ep->pmaSize; + + usb_copy_to_pma_ptr(buf, amount, ep->pma); + usb_set_ep_tx_count(ep->address, amount); + usb_generic_enable_tx(ep); + + return amount; +} + +// transmitting = 1 when transmitting, 0 when done but not flushed, negative when done and flushed +uint32 usb_generic_send_from_circular_buffer(USBEndpointInfo* ep, volatile uint8* buf, uint32 circularBufferSize, uint32 head, volatile uint32* tailP, volatile int8* transmittingP) { + uint32 tail = *tailP; + int32 amount = (head - tail) % circularBufferSize; + if (amount < 0) { + // wish we could count on % returning a non-negative answer + amount += circularBufferSize; + } + + if (amount==0) { + if (*transmittingP <= 0) { + *transmittingP = -1; + return 0; // it was already flushed, keep Tx endpoint disabled + } + *transmittingP = 0; + goto flush; // no more data to send + } + + *transmittingP = 1; + + if (amount > ep->pmaSize) { + amount = ep->pmaSize; + } + + // copy the bytes from USB Tx buffer to PMA buffer + uint32 *dst = ep->pma; + + for (int32 i = 0; i < amount; i++) { + uint16 low = buf[tail]; + tail = (tail + 1) % circularBufferSize; + i++; + if (i >= amount) { + *dst = low; + break; + } + *dst++ = ((uint16)buf[tail] << 8) | low; + tail = (tail + 1) % circularBufferSize; + } + + *tailP = tail; /* store volatile variable */ + +flush: + // enable Tx endpoint + usb_set_ep_tx_count(ep->address, amount); + usb_generic_enable_tx(ep); + + return amount; +} + + +uint32 usb_generic_send_from_circular_buffer_double_buffered(USBEndpointInfo* ep, volatile uint8* buf, uint32 circularBufferSize, uint32 amount, volatile uint32* tailP) { + uint32 tail = *tailP; /* load volatile variable */ + + uint32 dtog_tx = usb_get_ep_dtog_tx(ep->address); + + /* copy the bytes from USB Tx buffer to PMA buffer */ + uint32 *dst; + if (dtog_tx) + dst = PMA_PTR_BUF1(ep); + else + dst = PMA_PTR_BUF0(ep); + + if (amount > ep->pmaSize / 2) + amount = ep->pmaSize / 2; + + for (uint32 i = 0; i < amount; i++) { + uint16 low = buf[tail]; + tail = (tail + 1) % circularBufferSize; + i++; + if (i >= amount) { + *dst = low; + break; + } + *dst++ = ((uint16)buf[tail] << 8) | low; + tail = (tail + 1) % circularBufferSize; + } + + *tailP = tail; /* store volatile variable */ + + if (dtog_tx) + usb_set_ep_tx_buf1_count(ep->address, amount); + else + usb_set_ep_tx_buf0_count(ep->address, amount); + + return amount; +} + + +uint16_t usb_generic_roundUpToPowerOf2(uint16_t x) { + uint16_t xx; + for (xx = 1 ; xx < x && xx != 0; xx *= 2) ; + if (xx == 0) + return x; + else + return xx; +} diff --git a/STM32F1/libraries/USBComposite/usb_generic.h b/STM32F1/libraries/USBComposite/usb_generic.h new file mode 100644 index 000000000..ef2639f3c --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_generic.h @@ -0,0 +1,153 @@ +#ifndef _USB_GENERIC_H +#define _USB_GENERIC_H +#include +typedef unsigned short u16; +typedef unsigned char u8; + +#include +#include +#include +#include "usb_lib_globals.h" +#include "usb_reg_map.h" + +#define USB_CONTROL_DONE 1 + +#define PMA_MEMORY_SIZE 512 +#define MAX_USB_DESCRIPTOR_DATA_SIZE 200 +#define USB_MAX_STRING_DESCRIPTOR_LENGTH 36 + +#define USB_EP0_BUFFER_SIZE 0x40 +#define USB_EP0_TX_BUFFER_ADDRESS 0x40 +#define USB_EP0_RX_BUFFER_ADDRESS (USB_EP0_TX_BUFFER_ADDRESS+USB_EP0_BUFFER_SIZE) + +#ifdef __cplusplus +extern "C" { +#endif + +enum USB_ENDPOINT_TYPES { + USB_GENERIC_ENDPOINT_TYPE_BULK = 0, + USB_GENERIC_ENDPOINT_TYPE_CONTROL, + USB_GENERIC_ENDPOINT_TYPE_ISO, + USB_GENERIC_ENDPOINT_TYPE_INTERRUPT +}; + +extern const usb_descriptor_string usb_generic_default_iManufacturer; +extern const usb_descriptor_string usb_generic_default_iProduct; + +typedef struct USBEndpointInfo { + void (*callback)(void); + void* pma; + uint16 pmaSize; + uint8 address; + uint8 type:2; + uint8 doubleBuffer:1; + uint8 tx:1; // 1 if TX, 0 if RX + uint8 exclusive:1; // 1 if cannot use the same endpoint number for both rx and tx + uint8 align:1; // 1 if next endpoint of the opposite type shares the same endpoint number as this +} USBEndpointInfo; + +typedef struct USBCompositePart { + uint8 numInterfaces; + uint8 numEndpoints; + uint8 startInterface; + uint16 descriptorSize; + void (*getPartDescriptor)(uint8* out); + void (*usbInit)(void); + void (*usbReset)(void); + void (*usbSetConfiguration)(void); + void (*usbClearFeature)(void); + void (*clear)(void); + RESULT (*usbDataSetup)(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength ); + RESULT (*usbNoDataSetup)(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex); + USBEndpointInfo* endpoints; +} USBCompositePart; + +struct usb_chunk { + uint32 dataLength; + const uint8* data; + struct usb_chunk* next; +} __packed; + +uint32 usb_generic_chunks_length(struct usb_chunk* chunk); + +static inline void usb_generic_enable_rx(USBEndpointInfo* ep) { + usb_set_ep_rx_stat(ep->address, USB_EP_STAT_RX_VALID); +} + +static inline void usb_generic_enable_tx(USBEndpointInfo* ep) { + usb_set_ep_tx_stat(ep->address, USB_EP_STAT_TX_VALID); +} + +static inline void usb_generic_stall_rx(USBEndpointInfo* ep) { + usb_set_ep_rx_stat(ep->address, USB_EP_STAT_RX_STALL); +} + +static inline void usb_generic_stall_tx(USBEndpointInfo* ep) { + usb_set_ep_tx_stat(ep->address, USB_EP_STAT_TX_STALL); +} + +static inline void usb_generic_disable_rx(USBEndpointInfo* ep) { + usb_set_ep_rx_stat(ep->address, USB_EP_STAT_RX_DISABLED); +} + +static inline void usb_generic_pause_rx(USBEndpointInfo* ep) { + usb_set_ep_rx_stat(ep->address, USB_EP_STAT_RX_NAK); +} + +static inline void usb_generic_disable_tx(USBEndpointInfo* ep) { + usb_set_ep_tx_stat(ep->address, USB_EP_STAT_TX_DISABLED); +} + +static inline void usb_generic_enable_rx_ep0(void) { + usb_set_ep_rx_stat(USB_EP0, USB_EP_STAT_RX_VALID); +} + +static inline void usb_generic_pause_rx_ep0(void) { + usb_set_ep_rx_stat(USB_EP0, USB_EP_STAT_RX_NAK); +} + +static inline void usb_generic_disable_interrupts_ep0(void) { + nvic_irq_disable(NVIC_USB_LP_CAN_RX0); +} + +static inline void usb_generic_enable_interrupts_ep0(void) { + nvic_irq_enable(NVIC_USB_LP_CAN_RX0); +} + +static inline void usb_generic_prepare_tx(USBEndpointInfo* ep, uint32 length) { + usb_set_ep_tx_count(ep->address, length); +} + +static inline void usb_generic_set_tx(USBEndpointInfo* ep, uint32 length) { + usb_set_ep_tx_count(ep->address, length); + usb_generic_enable_tx(ep); +} + +// for double buffering +#define PMA_PTR_BUF1(ep) ((void*)((uint8*)(ep)->pma+(ep)->pmaSize)) +#define PMA_PTR_BUF0(ep) ((ep)->pma) + +uint32 usb_generic_send_from_circular_buffer_double_buffered(USBEndpointInfo* ep, volatile uint8* buf, uint32 circularBufferSize, uint32 amount, volatile uint32* tailP); +void usb_generic_set_disconnect_delay(uint32 delay); +void usb_generic_set_info(uint16 idVendor, uint16 idProduct, const char* iManufacturer, const char* iProduct, const char* iSerialNumber); +uint8 usb_generic_set_parts(USBCompositePart** _parts, unsigned _numParts); +void usb_generic_control_rx_setup(volatile void* buffer, uint16 length, volatile uint8* done); +void usb_generic_control_tx_setup(volatile void* buffer, uint16 length, volatile uint8* done); +void usb_generic_control_tx_chunk_setup(struct usb_chunk* chunk); +void usb_generic_control_descriptor_tx(ONE_DESCRIPTOR* d); +void usb_generic_disable(void); +void usb_generic_enable(void); +void usb_copy_from_pma_ptr(volatile uint8 *buf, uint16 len, uint32* pma); +void usb_copy_to_pma_ptr(volatile const uint8 *buf, uint16 len, uint32* pma); +uint32 usb_generic_read_to_circular_buffer(USBEndpointInfo* ep, volatile uint8* buf, uint32 bufferSize, volatile uint32* headP); +#define USB_GENERIC_UNLIMITED_BUFFER 0xFFFFFFFFul +uint32 usb_generic_read_to_buffer(USBEndpointInfo* ep, volatile uint8* buf, uint32 bufferSize); +uint32 usb_generic_send_from_circular_buffer(USBEndpointInfo* ep, volatile uint8* buf, uint32 bufferSize, uint32 head, volatile uint32* tailP, volatile int8* transmittingP); +uint32 usb_generic_send_from_buffer(USBEndpointInfo* ep, volatile uint8* buf, uint32 amount); +uint16_t usb_generic_roundUpToPowerOf2(uint16_t x); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/STM32F1/libraries/USBComposite/usb_hid.c b/STM32F1/libraries/USBComposite/usb_hid.c new file mode 100644 index 000000000..b73a71c83 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_hid.c @@ -0,0 +1,519 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/usb/stm32f1/usb_hid.c + * @brief USB HID (human interface device) support + * + * FIXME: this works on the STM32F1 USB peripherals, and probably no + * place else. Nonportable bits really need to be factored out, and + * the result made cleaner. + */ + +#include "usb_generic.h" +#include "usb_hid.h" +#include + +uint16 GetEPTxAddr(uint8 /*bEpNum*/); + +/* usb_lib headers */ +#include "usb_type.h" +#include "usb_core.h" +#include "usb_def.h" + + +#include +#include + +static uint8 numEndpoints = 1; +static uint8 IdleValue = 1; +static uint8 ProtocolValue = 0; +static uint32 txEPSize = 64; +static uint32 rxEPSize = 64; +static uint8 txInterval = 0x0A; +static uint8 rxInterval = 0x0A; +static volatile int8 transmitting; +static struct usb_chunk* reportDescriptorChunks = NULL; + +static void hidDataTxCb(void); +static void hidDataRxCb(void); +static void hidUSBReset(void); +static void usb_hid_clear(void); +static RESULT hidUSBDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength); +static RESULT hidUSBNoDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex); + +static USBHIDOutputEndpointReceiver rxReceiver = NULL; +static void* rxReceiverExtra = NULL; +static volatile HIDBuffer_t hidBuffers[MAX_HID_BUFFERS] = {{ 0 }}; +static volatile uint8* hidBufferRx = NULL; + +#define HID_INTERFACE_OFFSET 0x00 +#define HID_INTERFACE_NUMBER (HID_INTERFACE_OFFSET+usbHIDPart.startInterface) + +/* + * Descriptors + */ + + +#define HID_ENDPOINT_TX 0 +#define USB_HID_TX_ENDPOINT_INFO (&hidEndpoints[HID_ENDPOINT_TX]) +#define USB_HID_TX_ENDP (hidEndpoints[HID_ENDPOINT_TX].address) + +#define HID_ENDPOINT_RX 1 +#define USB_HID_RX_ENDPOINT_INFO (&hidEndpoints[HID_ENDPOINT_RX]) +#define USB_HID_RX_ENDP (hidEndpoints[HID_ENDPOINT_RX].address) + +typedef struct { + //HID + usb_descriptor_interface HID_Interface; + HIDDescriptor HID_Descriptor; + usb_descriptor_endpoint HIDDataInEndpoint; + usb_descriptor_endpoint HIDDataOutEndpoint; +} __packed hid_part_config; + +static const hid_part_config hidPartConfigData = { + .HID_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = HID_INTERFACE_OFFSET, // PATCH + .bAlternateSetting = 0x00, + .bNumEndpoints = 1, // PATCH + .bInterfaceClass = USB_INTERFACE_CLASS_HID, + .bInterfaceSubClass = USB_INTERFACE_SUBCLASS_HID, + .bInterfaceProtocol = 0x00, /* Common AT Commands */ + .iInterface = 0x00, + }, + .HID_Descriptor = { + .len = 9,//sizeof(HIDDescDescriptor), + .dtype = HID_DESCRIPTOR_TYPE, + .versionL = 0x10, + .versionH = 0x01, + .country = 0x00, + .numDesc = 0x01, + .desctype = REPORT_DESCRIPTOR,//0x22, + .descLenL = 0x00, //PATCH + .descLenH = 0x00, //PATCH + }, + .HIDDataInEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = USB_DESCRIPTOR_ENDPOINT_IN | 0, // PATCH: USB_HID_TX_ENDP + .bmAttributes = USB_EP_TYPE_INTERRUPT, + .wMaxPacketSize = 64, //PATCH + .bInterval = 0x0A, //PATCH + }, + .HIDDataOutEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = USB_DESCRIPTOR_ENDPOINT_OUT | 0, // PATCH: USB_HID_RX_ENDP + .bmAttributes = USB_EP_TYPE_INTERRUPT, + .wMaxPacketSize = 64, //PATCH + .bInterval = 0x0A, //PATCH + }, +}; + +#define SIZE_hidPartConfigData_ONE_ENDPOINT (sizeof(hidPartConfigData)-sizeof(hidPartConfigData.HIDDataOutEndpoint)) +#define SIZE_hidPartConfigData_TWO_ENDPOINTS (sizeof(hidPartConfigData)) + +static ONE_DESCRIPTOR HID_Hid_Descriptor = { + (uint8*)&hidPartConfigData.HID_Descriptor, + sizeof(hidPartConfigData.HID_Descriptor) +}; + +void usb_hid_setTXInterval(uint8_t t) { + txInterval = t; +} + +void usb_hid_setRXInterval(uint8_t t) { + rxInterval = t; +} + +static USBEndpointInfo hidEndpoints[2] = { + { + .callback = hidDataTxCb, + .pmaSize = 64, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 1, + }, + { + .callback = hidDataRxCb, + .pmaSize = 64, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 0, + } +}; + +void usb_hid_setTXEPSize(uint32_t size) { + if (size == 0 || size > 64) + size = 64; + hidEndpoints[0].pmaSize = size; + txEPSize = size; +} + +#define OUT_BYTE(s,v) out[(uint8*)&(s.v)-(uint8*)&s] +#define OUT_16(s,v) *(uint16_t*)&OUT_BYTE(s,v) // OK on Cortex which can handle unaligned writes + +static void getHIDPartDescriptor(uint8* out) { + memcpy(out, &hidPartConfigData, numEndpoints > 1 ? SIZE_hidPartConfigData_TWO_ENDPOINTS : SIZE_hidPartConfigData_ONE_ENDPOINT); + // patch to reflect where the part goes in the descriptor + OUT_BYTE(hidPartConfigData, HID_Interface.bInterfaceNumber) += usbHIDPart.startInterface; + OUT_BYTE(hidPartConfigData, HID_Interface.bNumEndpoints) = numEndpoints; + OUT_BYTE(hidPartConfigData, HIDDataInEndpoint.bEndpointAddress) += USB_HID_TX_ENDP; + uint16 size = usb_generic_chunks_length(reportDescriptorChunks); + OUT_BYTE(hidPartConfigData, HID_Descriptor.descLenL) = (uint8)size; + OUT_BYTE(hidPartConfigData, HID_Descriptor.descLenH) = (uint8)(size>>8); + OUT_16(hidPartConfigData, HIDDataInEndpoint.wMaxPacketSize) = txEPSize; + OUT_BYTE(hidPartConfigData, HIDDataInEndpoint.bInterval) = txInterval; + if (numEndpoints > 1) { + OUT_BYTE(hidPartConfigData, HIDDataOutEndpoint.bEndpointAddress) += USB_HID_RX_ENDP; + OUT_BYTE(hidPartConfigData, HIDDataOutEndpoint.bInterval) = rxInterval; + OUT_16(hidPartConfigData, HIDDataOutEndpoint.wMaxPacketSize) = rxEPSize; + } +} + +USBCompositePart usbHIDPart = { + .numInterfaces = 1, + .numEndpoints = sizeof(hidEndpoints)/sizeof(*hidEndpoints), + .descriptorSize = SIZE_hidPartConfigData_ONE_ENDPOINT, + .getPartDescriptor = getHIDPartDescriptor, + .usbInit = NULL, + .usbReset = hidUSBReset, + .usbDataSetup = hidUSBDataSetup, + .usbNoDataSetup = hidUSBNoDataSetup, + .usbClearFeature = NULL, + .usbSetConfiguration = NULL, + .clear = usb_hid_clear, + .endpoints = hidEndpoints +}; + +void usb_hid_setDedicatedRXEndpoint(void* buffer, uint16_t size, USBHIDOutputEndpointReceiver receiver, void* extra) { + if (buffer != NULL) { + numEndpoints = 2; + usbHIDPart.descriptorSize = SIZE_hidPartConfigData_TWO_ENDPOINTS; + hidEndpoints[1].pmaSize = size; + rxEPSize = size; + hidBufferRx = buffer; + rxReceiver = receiver; + rxReceiverExtra = extra; + } + else { + numEndpoints = 1; + usbHIDPart.descriptorSize = SIZE_hidPartConfigData_ONE_ENDPOINT; + hidBufferRx = NULL; + rxReceiver = NULL; + rxReceiverExtra = NULL; + } +} + + +#define HID_TX_BUFFER_SIZE 256 // must be power of 2 +#define HID_TX_BUFFER_SIZE_MASK (HID_TX_BUFFER_SIZE-1) +// Tx data +static volatile uint8 hidBufferTx[HID_TX_BUFFER_SIZE]; +// Write index to hidBufferTx +static volatile uint32 hid_tx_head = 0; +// Read index from hidBufferTx +static volatile uint32 hid_tx_tail = 0; + +void usb_hid_set_report_descriptor(struct usb_chunk* chunks) { + reportDescriptorChunks = chunks; +} + + +static volatile HIDBuffer_t* usb_hid_find_buffer(uint8 type, uint8 reportID) { + uint8 typeTest = type == HID_REPORT_TYPE_OUTPUT ? HID_BUFFER_MODE_OUTPUT : 0; + for (int i=0; ibuffer+delta, data, buffer->bufferSize-delta); + if (reportID) + buffer->buffer[0] = reportID; + buffer->state = HID_BUFFER_READ; + usb_generic_enable_rx_ep0(); + return; + } +} + +static uint8 have_unread_data_in_hid_buffer() { + for (int i=0;ireportID == reportID && buffer->state != HID_BUFFER_EMPTY && !(poll && buffer->state == HID_BUFFER_READ)) { + unsigned delta = reportID != 0; + + if (out != NULL) + memcpy(out, (uint8*)buffer->buffer+delta, buffer->bufferSize-delta); + + if (poll) { + buffer->state = HID_BUFFER_READ; + } + + ret = buffer->bufferSize-delta; + } + + if (! have_unread_data_in_hid_buffer() ) { + usb_generic_enable_rx_ep0(); + } + + usb_generic_enable_interrupts_ep0(); + + return ret; +} + +void usb_hid_clear_buffers(uint8 type) { + uint8 typeTest = type == HID_REPORT_TYPE_OUTPUT ? HID_BUFFER_MODE_OUTPUT : 0; + for (int i=0; imode |= HID_BUFFER_MODE_OUTPUT; + else + buf->mode &= ~HID_BUFFER_MODE_OUTPUT; + memset((void*)buf->buffer, 0, buf->bufferSize); + buf->buffer[0] = buf->reportID; + + volatile HIDBuffer_t* buffer = usb_hid_find_buffer(type, buf->reportID); + + if (buffer != NULL) { + *buffer = *buf; + return 1; + } + else { + for (int i=0; i (HID_TX_BUFFER_SIZE-tx_unsent-1) ) { + len = (HID_TX_BUFFER_SIZE-tx_unsent-1); + } + if (len==0) return 0; // buffer full + + uint16 i; + // copy data from user buffer to USB Tx buffer + for (i=0; i= 0); + + if (transmitting<0) { + hidDataTxCb(); // initiate data transmission + } + + return len; +} + + + +uint32 usb_hid_get_pending(void) { + return (hid_tx_head - hid_tx_tail) & HID_TX_BUFFER_SIZE_MASK; +} + + +static void hidDataTxCb(void) +{ + usb_generic_send_from_circular_buffer(USB_HID_TX_ENDPOINT_INFO, + hidBufferTx, HID_TX_BUFFER_SIZE, hid_tx_head, &hid_tx_tail, &transmitting); +} + +static void hidDataRxCb(void) +{ + USBEndpointInfo* ep = USB_HID_RX_ENDPOINT_INFO; + + if (hidBufferRx != NULL) { + uint32 didRead = usb_generic_read_to_buffer(ep, hidBufferRx, rxEPSize); + + if (didRead > 0) { + if (rxReceiver != NULL) + rxReceiver(rxReceiverExtra, hidBufferRx, didRead); + } + } + + usb_generic_enable_rx(ep); +} + + + +static void hidUSBReset(void) { + /* Reset the RX/TX state */ + hid_tx_head = 0; + hid_tx_tail = 0; + transmitting = -1; +} + +#pragma GCC diagnostic ignored "-Wunused-parameter" +static RESULT hidUSBDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength) { + (void)interface; // only one interface + + if ((requestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { + switch (request) { + case SET_REPORT: + if (wValue1 == HID_REPORT_TYPE_FEATURE || wValue1 == HID_REPORT_TYPE_OUTPUT) { + volatile HIDBuffer_t* buffer = usb_hid_find_buffer(wValue1, wValue0); + + if (buffer == NULL) { + return USB_UNSUPPORT; + } + + if (0 == (buffer->mode & HID_BUFFER_MODE_NO_WAIT) && buffer->state == HID_BUFFER_UNREAD) { + return USB_NOT_READY; + } + else + { + buffer->state = HID_BUFFER_EMPTY; + usb_generic_control_rx_setup(buffer->buffer, buffer->bufferSize, &(buffer->state)); + } + return USB_SUCCESS; + } + break; + case GET_REPORT: + if (wValue1 == HID_REPORT_TYPE_FEATURE) { + volatile HIDBuffer_t* buffer = usb_hid_find_buffer(HID_REPORT_TYPE_FEATURE, wValue0); + + if (buffer == NULL || buffer->state == HID_BUFFER_EMPTY) { + return USB_UNSUPPORT; // TODO: maybe UNREADY on empty + } + + usb_generic_control_tx_setup(buffer->buffer, buffer->bufferSize, NULL); + return USB_SUCCESS; + } + default: + break; + } + } + + if((requestType & (REQUEST_TYPE | RECIPIENT)) == (STANDARD_REQUEST | INTERFACE_RECIPIENT)){ + switch (request){ + case GET_DESCRIPTOR: + if (wValue1 == REPORT_DESCRIPTOR) { + usb_generic_control_tx_chunk_setup(reportDescriptorChunks); + return USB_SUCCESS; + } + else if (wValue1 == HID_DESCRIPTOR_TYPE){ + usb_generic_control_descriptor_tx(&HID_Hid_Descriptor); + return USB_SUCCESS; + } + + break; + case GET_PROTOCOL: + usb_generic_control_tx_setup(&ProtocolValue, 1, NULL); + return USB_SUCCESS; + + case GET_IDLE: + usb_generic_control_tx_setup(&IdleValue, 1, NULL); + return USB_SUCCESS; + } + } + + return USB_UNSUPPORT; +} + + +static RESULT hidUSBNoDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex) { + (void)interface; // only one interface + + if ((requestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { + switch(request) { + case SET_PROTOCOL: + ProtocolValue = wValue0; + return USB_SUCCESS; + case SET_IDLE: + IdleValue = wValue0; + return USB_SUCCESS; + } + } + return USB_UNSUPPORT; +} + diff --git a/STM32F1/libraries/USBComposite/usb_hid.h b/STM32F1/libraries/USBComposite/usb_hid.h new file mode 100644 index 000000000..9dac06788 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_hid.h @@ -0,0 +1,150 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/include/libmaple/usb_device.h + * @brief USB Composite with CDC ACM and HID support + * + * IMPORTANT: this API is unstable, and may change without notice. + */ + +#ifndef _USB_HID_H_ +#define _USB_HID_H_ + +#include +#include +#include "usb_generic.h" + +#define MAX_HID_BUFFERS 8 +#define HID_BUFFER_SIZE(n,reportID) ((n)+((reportID)!=0)) +#define HID_BUFFER_ALLOCATE_SIZE(n,reportID) ((HID_BUFFER_SIZE((n),(reportID))+1)/2*2) + +#define HID_BUFFER_MODE_NO_WAIT 1 +#define HID_BUFFER_MODE_OUTPUT 2 + +#define HID_BUFFER_EMPTY 0 +#define HID_BUFFER_UNREAD USB_CONTROL_DONE +#define HID_BUFFER_READ 2 + +extern USBCompositePart usbHIDPart; + +typedef void (*USBHIDOutputEndpointReceiver)(void* extra, volatile void* buffer, uint16_t size); + +typedef struct HIDBuffer_t { + volatile uint8_t* buffer; // use HID_BUFFER_ALLOCATE_SIZE() to calculate amount of memory to allocate + uint16_t bufferSize; // this should match HID_BUFFER_SIZE + uint8_t reportID; + uint8_t mode; + uint8_t state; // HID_BUFFER_EMPTY, etc. +#ifdef __cplusplus + inline HIDBuffer_t(volatile uint8_t* _buffer=NULL, uint16_t _bufferSize=0, uint8_t _reportID=0, uint8_t _mode=0) { + reportID = _reportID; + buffer = _buffer; + bufferSize = _bufferSize; + mode = _mode; + } +#endif +} HIDBuffer_t; + +#ifdef __cplusplus +extern "C" { +#endif + +void usb_hid_set_report_descriptor(struct usb_chunk* chunks); +void usb_hid_clear_buffers(uint8_t type); +uint8_t usb_hid_add_buffer(uint8_t type, volatile HIDBuffer_t* buf); +void usb_hid_set_buffers(uint8_t type, volatile HIDBuffer_t* featureBuffers, int count); +uint16_t usb_hid_get_data(uint8_t type, uint8_t reportID, uint8_t* out, uint8_t poll); +void usb_hid_set_feature(uint8_t reportID, uint8_t* data); +void usb_hid_setTXEPSize(uint32_t size); +uint32 usb_hid_get_pending(void); +void usb_hid_setDedicatedRXEndpoint(void* buffer, uint16_t size, USBHIDOutputEndpointReceiver receiver, void* extra); +void usb_hid_setTXInterval(uint8_t t); +void usb_hid_setRXInterval(uint8_t t); + +/* + * HID Requests + */ + +typedef enum _HID_REQUESTS +{ + + GET_REPORT = 1, + GET_IDLE, + GET_PROTOCOL, + + SET_REPORT = 9, + SET_IDLE, + SET_PROTOCOL + +} HID_REQUESTS; + +#define HID_REPORT_TYPE_INPUT 0x01 +#define HID_REPORT_TYPE_OUTPUT 0x02 +#define HID_REPORT_TYPE_FEATURE 0x03 + + +/* + * HID Descriptors, etc. + */ + +#define HID_ENDPOINT_INT 1 + +#define HID_DESCRIPTOR_TYPE 0x21 +#define REPORT_DESCRIPTOR 0x22 + + +typedef struct +{ + uint8_t len; // 9 + uint8_t dtype; // 0x21 + uint8_t versionL; // 0x101 + uint8_t versionH; // 0x101 + uint8_t country; + uint8_t numDesc; + uint8_t desctype; // 0x22 report + uint8_t descLenL; + uint8_t descLenH; +} HIDDescriptor; + + +#define USB_INTERFACE_CLASS_HID 0x03 +#define USB_INTERFACE_SUBCLASS_HID 0x01 + + /* + * HID interface + */ + +uint32 usb_hid_tx(const uint8* buf, uint32 len); +uint32 usb_hid_tx_mod(const uint8* buf, uint32 len); +uint32 usb_hid_data_available(void); /* in RX buffer */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/STM32F1/libraries/USBComposite/usb_mass.c b/STM32F1/libraries/USBComposite/usb_mass.c new file mode 100644 index 000000000..7c39e602c --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_mass.c @@ -0,0 +1,438 @@ +#include + +#include "usb_generic.h" +#include "usb_mass.h" +#include "usb_scsi.h" +#include "usb_mass_internal.h" + +#include +#include + +/* Private headers */ +#include "usb_lib_globals.h" +#include "usb_reg_map.h" +#include "usb_regs.h" + +/* usb_lib headers */ +#include "usb_type.h" +#include "usb_core.h" +#include "usb_def.h" + +static void usb_mass_bot_cbw_decode(); + +static void usb_mass_set_configuration(); +static void usb_mass_clear_feature(); +static RESULT usb_mass_data_setup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength); +static RESULT usb_mass_no_data_setup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex); +static void usb_mass_reset(); +static uint8_t* usb_mass_get_max_lun(uint16_t Length); +static void usb_mass_in(void); +static void usb_mass_out(void); +uint32_t usb_mass_sil_write(uint8_t* pBufferPointer, uint32_t wBufferSize); +uint32_t usb_mass_sil_read(uint8_t* pBufferPointer); + +//#define MASS_INTERFACE_OFFSET 0x00 +//#define MASS_INTERFACE_NUMBER (MASS_INTERFACE_OFFSET+usbMassPart.startInterface) + +#define LUN_DATA_LENGTH 1 + +static uint32_t maxLun = 0; +static uint32_t deviceState = DEVICE_STATE_UNCONNECTED; +uint8_t usb_mass_botState = BOT_STATE_IDLE; +BulkOnlyCBW usb_mass_CBW; +BulkOnlyCSW usb_mass_CSW; +uint8_t usb_mass_bulkDataBuff[MAX_BULK_PACKET_SIZE]; +uint16_t usb_mass_dataLength; +static uint8_t inRequestPending; +static uint8_t outRequestPending; + +typedef struct mass_descriptor_config { +// usb_descriptor_config_header Config_Header; + usb_descriptor_interface MASS_Interface; + usb_descriptor_endpoint DataInEndpoint; + usb_descriptor_endpoint DataOutEndpoint; +} __packed mass_descriptor_config; + + +#define MAX_POWER (500 >> 1) +const mass_descriptor_config usbMassConfigDescriptor = { + /*.Config_Header = + { + .bLength = sizeof (usb_descriptor_config_header), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION, + .wTotalLength = sizeof (usb_descriptor_config), + .bNumInterfaces = 0x01, + .bConfigurationValue = 0x01, + .iConfiguration = 0x00, + .bmAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELF_POWERED), + .bMaxPower = MAX_POWER, + }, */ + + .MASS_Interface = + { + .bLength = sizeof (usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = 0x00, // PATCH + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x02, + .bInterfaceClass = 8, // mass storage + .bInterfaceSubClass = 6, // SCSI + .bInterfaceProtocol = 0x50, // Bulk-Only + .iInterface = 0, + }, + + .DataInEndpoint = + { + .bLength = sizeof (usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | 0), // PATCH: USB_MASS_TX_ENDP + .bmAttributes = USB_EP_TYPE_BULK, + .wMaxPacketSize = MAX_BULK_PACKET_SIZE, + .bInterval = 0, + }, + + .DataOutEndpoint = + { + .bLength = sizeof (usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT | 0), // PATCH: USB_MASS_RX_ENDP + .bmAttributes = USB_EP_TYPE_BULK, + .wMaxPacketSize = MAX_BULK_PACKET_SIZE, + .bInterval = 1, + } +}; + +USBEndpointInfo usbMassEndpoints[2] = { + { + .callback = usb_mass_in, + .pmaSize = MAX_BULK_PACKET_SIZE, + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 1, + }, + { + .callback = usb_mass_out, + .pmaSize = MAX_BULK_PACKET_SIZE, + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 0, + }, +}; + +#define OUT_BYTE(s,v) out[(uint8*)&(s.v)-(uint8*)&s] + +static void getMassPartDescriptor(uint8* out) { + memcpy(out, &usbMassConfigDescriptor, sizeof(mass_descriptor_config)); + // patch to reflect where the part goes in the descriptor + OUT_BYTE(usbMassConfigDescriptor, MASS_Interface.bInterfaceNumber) += usbMassPart.startInterface; + OUT_BYTE(usbMassConfigDescriptor, DataInEndpoint.bEndpointAddress) += USB_MASS_TX_ENDP; + OUT_BYTE(usbMassConfigDescriptor, DataOutEndpoint.bEndpointAddress) += USB_MASS_RX_ENDP; +} + + + +USBCompositePart usbMassPart = { + .numInterfaces = 1, + .numEndpoints = sizeof(usbMassEndpoints)/sizeof(*usbMassEndpoints), + .descriptorSize = sizeof(mass_descriptor_config), + .getPartDescriptor = getMassPartDescriptor, + .usbInit = NULL, + .usbReset = usb_mass_reset, + .usbDataSetup = usb_mass_data_setup, + .usbNoDataSetup = usb_mass_no_data_setup, + .usbClearFeature = usb_mass_clear_feature, + .usbSetConfiguration = usb_mass_set_configuration, + .endpoints = usbMassEndpoints +}; + +static void usb_mass_reset(void) { + usb_mass_mal_init(0); + + pInformation->Current_Configuration = 0; // TODO: remove? + + /* current feature is current bmAttributes */ + pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELF_POWERED); // usbMassConfigDescriptor.Config_Header.bmAttributes; // TODO: remove? + + deviceState = DEVICE_STATE_ATTACHED; + usb_mass_CBW.dSignature = BOT_CBW_SIGNATURE; + usb_mass_botState = BOT_STATE_IDLE; +} + +static void usb_mass_set_configuration(void) { + if (pInformation->Current_Configuration != 0) { + deviceState = USB_CONFIGURED; + usb_mass_botState = BOT_STATE_IDLE; + } +} + +static void usb_mass_clear_feature(void) { + /* when the host send a usb_mass_CBW with invalid signature or invalid length the two + Endpoints (IN & OUT) shall stall until receiving a Mass Storage Reset */ + if (usb_mass_CBW.dSignature != BOT_CBW_SIGNATURE) { + usb_mass_bot_abort(BOT_DIR_BOTH); + } +} + +#pragma GCC diagnostic ignored "-Wunused-parameter" +static RESULT usb_mass_data_setup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength) { + (void)interface; // only one interface + uint8_t * (*copy_routine)(uint16_t); + + copy_routine = NULL; + if ((requestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT) && request == REQUEST_GET_MAX_LUN && wValue0 == 0 && wValue1 == 0 && wLength == 0x01) { + copy_routine = usb_mass_get_max_lun; + } else { + return USB_UNSUPPORT; + } + + if (copy_routine == NULL) { + return USB_UNSUPPORT; + } + + pInformation->Ctrl_Info.CopyData = copy_routine; + pInformation->Ctrl_Info.Usb_wOffset = 0; + (*copy_routine)(0); + + return USB_SUCCESS; +} + +static uint8_t* usb_mass_get_max_lun(uint16_t length) { + if (length == 0) { + pInformation->Ctrl_Info.Usb_wLength = LUN_DATA_LENGTH; + return 0; + } else { + return ((uint8_t*) (&maxLun)); + } +} + +static RESULT usb_mass_no_data_setup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex) { + if ((requestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT) && request == REQUEST_MASS_STORAGE_RESET && wValue0 == 0 && wValue1 == 0) { + + /*initialize the usb_mass_CBW signature to enable the clear feature*/ + usb_mass_CBW.dSignature = BOT_CBW_SIGNATURE; + usb_mass_botState = BOT_STATE_IDLE; + + return USB_SUCCESS; + } + return USB_UNSUPPORT; +} + + +void usb_mass_loop() { + if (inRequestPending) { + inRequestPending = 0; + + switch (usb_mass_botState) { + case BOT_STATE_CSW_Send: + case BOT_STATE_ERROR: + usb_mass_botState = BOT_STATE_IDLE; + usb_generic_enable_rx(USB_MASS_RX_ENDPOINT_INFO); /* enable the Endpoint to receive the next cmd*/ + break; + case BOT_STATE_DATA_IN: + switch (usb_mass_CBW.CB[0]) { + case SCSI_READ10: + scsi_read10_cmd(usb_mass_CBW.bLUN, SCSI_lba, SCSI_blkLen); + break; + } + break; + case BOT_STATE_DATA_IN_LAST: + usb_mass_bot_set_csw(BOT_CSW_CMD_PASSED, BOT_SEND_CSW_ENABLE); + SetEPRxStatus(USB_MASS_RX_ENDP, USB_EP_ST_RX_VAL); + break; + + default: + break; + } + } + + if (outRequestPending) { + outRequestPending = 0; + + uint8_t CMD; + CMD = usb_mass_CBW.CB[0]; + + switch (usb_mass_botState) { + case BOT_STATE_IDLE: + usb_mass_bot_cbw_decode(); + break; + case BOT_STATE_DATA_OUT: + if (CMD == SCSI_WRITE10) { + scsi_write10_cmd(usb_mass_CBW.bLUN, SCSI_lba, SCSI_blkLen); + break; + } + usb_mass_bot_abort(BOT_DIR_OUT); + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_INVALID_FIELED_IN_COMMAND); + usb_mass_bot_set_csw(BOT_CSW_PHASE_ERROR, BOT_SEND_CSW_DISABLE); + break; + default: + usb_mass_bot_abort(BOT_DIR_BOTH); + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_INVALID_FIELED_IN_COMMAND); + usb_mass_bot_set_csw(BOT_CSW_PHASE_ERROR, BOT_SEND_CSW_DISABLE); + break; + } + } +} + +/* + * IN + */ +static void usb_mass_in(void) { + inRequestPending = 1; +} + +/* + * OUT + */ +static void usb_mass_out(void) { + usb_mass_dataLength = usb_mass_sil_read(usb_mass_bulkDataBuff); + outRequestPending = 1; +} + +static void usb_mass_bot_cbw_decode() { + uint32_t counter; + + for (counter = 0; counter < usb_mass_dataLength; counter++) { + *((uint8_t *) & usb_mass_CBW + counter) = usb_mass_bulkDataBuff[counter]; + } + usb_mass_CSW.dTag = usb_mass_CBW.dTag; + usb_mass_CSW.dDataResidue = usb_mass_CBW.dDataLength; + if (usb_mass_dataLength != BOT_CBW_PACKET_LENGTH) { + usb_mass_bot_abort(BOT_DIR_BOTH); + /* reset the usb_mass_CBW.dSignature to disable the clear feature until receiving a Mass storage reset*/ + usb_mass_CBW.dSignature = 0; + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_PARAMETER_LIST_LENGTH_ERROR); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_DISABLE); + return; + } + + if ((usb_mass_CBW.CB[0] == SCSI_READ10) || (usb_mass_CBW.CB[0] == SCSI_WRITE10)) { + /* Calculate Logical Block Address */ + SCSI_lba = (usb_mass_CBW.CB[2] << 24) | (usb_mass_CBW.CB[3] << 16) | (usb_mass_CBW.CB[4] << 8) | usb_mass_CBW.CB[5]; + /* Calculate the Number of Blocks to transfer */ + SCSI_blkLen = (usb_mass_CBW.CB[7] << 8) | usb_mass_CBW.CB[8]; + } + + if (usb_mass_CBW.dSignature == BOT_CBW_SIGNATURE) { + /* Valid usb_mass_CBW */ + if ((usb_mass_CBW.bLUN > maxLun) || (usb_mass_CBW.bCBLength < 1) || (usb_mass_CBW.bCBLength > 16)) { + usb_mass_bot_abort(BOT_DIR_BOTH); + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_INVALID_FIELED_IN_COMMAND); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_DISABLE); + } else { + switch (usb_mass_CBW.CB[0]) { + case SCSI_REQUEST_SENSE: + scsi_request_sense_cmd(usb_mass_CBW.bLUN); + break; + case SCSI_INQUIRY: + scsi_inquiry_cmd(usb_mass_CBW.bLUN); + break; + case SCSI_START_STOP_UNIT: + scsi_start_stop_unit_cmd(usb_mass_CBW.bLUN); + break; + case SCSI_ALLOW_MEDIUM_REMOVAL: + scsi_start_stop_unit_cmd(usb_mass_CBW.bLUN); + break; + case SCSI_MODE_SENSE6: + scsi_mode_sense6_cmd(usb_mass_CBW.bLUN); + break; + case SCSI_MODE_SENSE10: + scsi_mode_sense10_cmd(usb_mass_CBW.bLUN); + break; + case SCSI_READ_FORMAT_CAPACITIES: + scsi_read_format_capacity_cmd(usb_mass_CBW.bLUN); + break; + case SCSI_READ_CAPACITY10: + scsi_read_capacity10_cmd(usb_mass_CBW.bLUN); + break; + case SCSI_TEST_UNIT_READY: + scsi_test_unit_ready_cmd(usb_mass_CBW.bLUN); + break; + case SCSI_READ10: + scsi_read10_cmd(usb_mass_CBW.bLUN, SCSI_lba, SCSI_blkLen); + break; + case SCSI_WRITE10: + scsi_write10_cmd(usb_mass_CBW.bLUN, SCSI_lba, SCSI_blkLen); + break; + case SCSI_VERIFY10: + scsi_verify10_cmd(usb_mass_CBW.bLUN); + break; + case SCSI_FORMAT_UNIT: + scsi_format_cmd(usb_mass_CBW.bLUN); + break; + + case SCSI_MODE_SELECT10: + case SCSI_MODE_SELECT6: + case SCSI_SEND_DIAGNOSTIC: + case SCSI_READ6: + case SCSI_READ12: + case SCSI_READ16: + case SCSI_READ_CAPACITY16: + case SCSI_WRITE6: + case SCSI_WRITE12: + case SCSI_VERIFY12: + case SCSI_VERIFY16: + case SCSI_WRITE16: + scsi_invalid_cmd(usb_mass_CBW.bLUN); + break; + + default: + { + usb_mass_bot_abort(BOT_DIR_BOTH); + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_INVALID_COMMAND); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_DISABLE); + } + } + } + } else { + /* Invalid usb_mass_CBW */ + usb_mass_bot_abort(BOT_DIR_BOTH); + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_INVALID_COMMAND); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_DISABLE); + } +} + +void usb_mass_bot_abort(uint8_t direction) { + switch (direction) { + case BOT_DIR_IN: + usb_generic_stall_tx(USB_MASS_TX_ENDPOINT_INFO); + break; + case BOT_DIR_OUT: + usb_generic_stall_rx(USB_MASS_RX_ENDPOINT_INFO); + break; + case BOT_DIR_BOTH: + usb_generic_stall_rx(USB_MASS_RX_ENDPOINT_INFO); + usb_generic_stall_tx(USB_MASS_TX_ENDPOINT_INFO); + break; + default: + break; + } +} + +void usb_mass_transfer_data_request(uint8_t* dataPointer, uint16_t dataLen) { + usb_mass_sil_write(dataPointer, dataLen); + + usb_mass_botState = BOT_STATE_DATA_IN_LAST; + usb_mass_CSW.dDataResidue -= dataLen; + usb_mass_CSW.bStatus = BOT_CSW_CMD_PASSED; +} + +void usb_mass_bot_set_csw(uint8_t status, uint8_t sendPermission) { + usb_mass_CSW.dSignature = BOT_CSW_SIGNATURE; + usb_mass_CSW.bStatus = status; + + if (sendPermission) { + usb_mass_botState = BOT_STATE_CSW_Send; + usb_mass_sil_write(((uint8_t *) & usb_mass_CSW), BOT_CSW_DATA_LENGTH); + } + else { + usb_mass_botState = BOT_STATE_ERROR; + } +} + +uint32_t usb_mass_sil_write(uint8_t* pBufferPointer, uint32_t wBufferSize) { + usb_generic_send_from_buffer(USB_MASS_TX_ENDPOINT_INFO, pBufferPointer, wBufferSize); + + return 0; +} + +uint32_t usb_mass_sil_read(uint8_t* pBufferPointer) { + return usb_generic_read_to_buffer(USB_MASS_RX_ENDPOINT_INFO, pBufferPointer, USB_GENERIC_UNLIMITED_BUFFER); +} diff --git a/STM32F1/libraries/USBComposite/usb_mass.h b/STM32F1/libraries/USBComposite/usb_mass.h new file mode 100644 index 000000000..93e1b6d68 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_mass.h @@ -0,0 +1,119 @@ + +#ifndef _LIBMAPLE_USB_MASS_H_ +#define _LIBMAPLE_USB_MASS_H_ + +#include +#include +#include +#include +#include "usb_generic.h" +#include "usb_mass_mal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define N_STRING_DESCRIPTORS 4 + +// 512 needs to be divisible by the following two values +#define MAX_PACKET_SIZE 64 /* 64B, maximum for USB FS Devices */ +#define MAX_BULK_PACKET_SIZE 64 /* 64B, max bulk Can't use 512 because the internal buffers for USB is only 512B */ +#if 512/MAX_PACKET_SIZE*MAX_PACKET_SIZE != 512 +# error MAX_PACKET_SIZE must divide 512 +#endif +#if 512/MAX_BULK_PACKET_SIZE*MAX_BULK_PACKET_SIZE != 512 +# error MAX_BULK_PACKET_SIZE must divide 512 +#endif + + + /* MASS Storage Requests */ +#define REQUEST_GET_MAX_LUN 0xFE +#define REQUEST_MASS_STORAGE_RESET 0xFF + + /* USB device state */ + typedef enum _DEVICE_STATE { + DEVICE_STATE_UNCONNECTED, + DEVICE_STATE_ATTACHED, + DEVICE_STATE_POWERED, + DEVICE_STATE_SUSPENDED, + DEVICE_STATE_ADDRESSED, + DEVICE_STATE_CONFIGURED + } DEVICE_STATE; + +#define BOT_DIR_IN 0 +#define BOT_DIR_OUT 1 +#define BOT_DIR_BOTH 2 + + /*****************************************************************************/ + /*********************** Bulk-Only Transfer State machine ********************/ + /*****************************************************************************/ +#define BOT_STATE_IDLE 0 /* Idle state */ +#define BOT_STATE_DATA_OUT 1 /* Data Out state */ +#define BOT_STATE_DATA_IN 2 /* Data In state */ +#define BOT_STATE_DATA_IN_LAST 3 /* Last Data In Last */ +#define BOT_STATE_CSW_Send 4 /* Command Status Wrapper */ +#define BOT_STATE_ERROR 5 /* error state */ + +#define BOT_CBW_SIGNATURE 0x43425355 +#define BOT_CSW_SIGNATURE 0x53425355 +#define BOT_CBW_PACKET_LENGTH 31 + +#define BOT_CSW_DATA_LENGTH 0x000D + + /* CSW Status Definitions */ +#define BOT_CSW_CMD_PASSED 0x00 +#define BOT_CSW_CMD_FAILED 0x01 +#define BOT_CSW_PHASE_ERROR 0x02 + +#define BOT_SEND_CSW_DISABLE 0 +#define BOT_SEND_CSW_ENABLE 1 + +#define USB_EP1_IN 0x81 + + /* Bulk-only Command Block Wrapper */ + typedef struct _BulkOnlyCBW { + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataLength; + uint8_t bmFlags; + uint8_t bLUN; + uint8_t bCBLength; + uint8_t CB[16]; + } BulkOnlyCBW; + + /* Bulk-only Command Status Wrapper */ + typedef struct _BulkOnlyCSW { + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataResidue; + uint8_t bStatus; + } BulkOnlyCSW; + + typedef struct _usb_descriptor_config { + usb_descriptor_config_header Config_Header; + usb_descriptor_interface MASS_Interface; + usb_descriptor_endpoint DataInEndpoint; + usb_descriptor_endpoint DataOutEndpoint; + } __packed usb_descriptor_config; + + void usb_mass_enable(gpio_dev *disc_dev, uint8 disc_bit); + void usb_mass_disable(gpio_dev *disc_dev, uint8 disc_bit); + void usb_mass_loop(); + + void usb_mass_bot_set_csw(uint8_t cswStatus, uint8_t sendPermission); + void usb_mass_transfer_data_request(uint8_t* dataPointer, uint16_t dataLen); + void usb_mass_bot_abort(uint8_t direction); + + extern USBCompositePart usbMassPart; + +extern uint8_t usb_mass_botState; +extern BulkOnlyCBW usb_mass_CBW; +extern BulkOnlyCSW usb_mass_CSW; +extern uint8_t usb_mass_bulkDataBuff[MAX_BULK_PACKET_SIZE]; +extern uint16_t usb_mass_dataLength; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/STM32F1/libraries/USBComposite/usb_mass_internal.h b/STM32F1/libraries/USBComposite/usb_mass_internal.h new file mode 100644 index 000000000..5903827ba --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_mass_internal.h @@ -0,0 +1,14 @@ +#ifndef _USB_MASS_INTERNAL_H_ +#define _USB_MASS_INTERNAL_H_ + +extern USBEndpointInfo usbMassEndpoints[]; + +#define MASS_ENDPOINT_TX 0 +#define MASS_ENDPOINT_RX 1 +#define USB_MASS_RX_ENDPOINT_INFO (&usbMassEndpoints[MASS_ENDPOINT_RX]) +#define USB_MASS_TX_ENDPOINT_INFO (&usbMassEndpoints[MASS_ENDPOINT_TX]) +#define USB_MASS_RX_ENDP (usbMassEndpoints[MASS_ENDPOINT_RX].address) +#define USB_MASS_TX_ENDP (usbMassEndpoints[MASS_ENDPOINT_TX].address) +#define USB_MASS_RX_PMA_PTR (usbMassEndpoints[MASS_ENDPOINT_RX].pma) +#define USB_MASS_TX_PMA_PTR (usbMassEndpoints[MASS_ENDPOINT_TX].pma) +#endif \ No newline at end of file diff --git a/STM32F1/libraries/USBComposite/usb_mass_mal.c b/STM32F1/libraries/USBComposite/usb_mass_mal.c new file mode 100644 index 000000000..cd84f8bef --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_mass_mal.c @@ -0,0 +1,42 @@ +#include +#include "usb_mass_mal.h" + + +#define USB_MASS_MAL_FAIL 1 +#define USB_MASS_MAL_SUCCESS 0 + +MassStorageDriveInfo usb_mass_drives[USB_MASS_MAX_DRIVES] = { { 0 } }; + +uint16_t usb_mass_mal_init(uint8_t lun) { + if (lun >= USB_MASS_MAX_DRIVES || (usb_mass_drives[lun].init != NULL && ! usb_mass_drives[lun].init())) + return USB_MASS_MAL_FAIL; + else + return USB_MASS_MAL_SUCCESS; +} + +void usb_mass_mal_format(uint8_t lun) { + if (lun < USB_MASS_MAX_DRIVES && usb_mass_drives[lun].format != NULL) + usb_mass_drives[lun].format(); +} + +uint16_t usb_mass_mal_get_status(uint8_t lun) { + if (lun >= USB_MASS_MAX_DRIVES || (usb_mass_drives[lun].status != NULL && ! usb_mass_drives[lun].status())) + return USB_MASS_MAL_FAIL; + else + return USB_MASS_MAL_SUCCESS; +} + +uint16_t usb_mass_mal_read_memory(uint8_t lun, uint8_t *readbuff, uint32_t startSector, uint16_t numSectors) { + if (lun >= USB_MASS_MAX_DRIVES || ! usb_mass_drives[lun].read(readbuff, startSector, numSectors)) + return USB_MASS_MAL_FAIL; + else + return USB_MASS_MAL_SUCCESS; +} + +uint16_t usb_mass_mal_write_memory(uint8_t lun, uint8_t *writebuff, uint32_t startSector, uint16_t numSectors) { + if (lun >= USB_MASS_MAX_DRIVES || usb_mass_drives[lun].write == NULL + || ! usb_mass_drives[lun].write(writebuff, startSector, numSectors)) + return USB_MASS_MAL_FAIL; + else + return USB_MASS_MAL_SUCCESS; +} diff --git a/STM32F1/libraries/USBComposite/usb_mass_mal.h b/STM32F1/libraries/USBComposite/usb_mass_mal.h new file mode 100644 index 000000000..241f8269c --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_mass_mal.h @@ -0,0 +1,41 @@ +#ifndef __USB_MASS_MAL_H +#define __USB_MASS_MAL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCSI_BLOCK_SIZE 512 + +#define USB_MASS_MAX_DRIVES 2 + +typedef bool (*MassStorageWriter)(const uint8_t *writebuff, uint32_t startSector, uint16_t numSectors); +typedef bool (*MassStorageReader)(uint8_t *readbuff, uint32_t startSector, uint16_t numSectors); +typedef bool (*MassStorageStatuser)(void); +typedef bool (*MassStorageInitializer)(void); +typedef bool (*MassStorageFormatter)(void); + +typedef struct { + uint32_t blockCount; + MassStorageReader read; + MassStorageWriter write; + MassStorageStatuser status; + MassStorageInitializer init; + MassStorageFormatter format; +} MassStorageDriveInfo; + +extern MassStorageDriveInfo usb_mass_drives[USB_MASS_MAX_DRIVES]; +uint16_t usb_mass_mal_init(uint8_t lun); +uint16_t usb_mass_mal_get_status(uint8_t lun); +uint16_t usb_mass_mal_read_memory(uint8_t lun, uint8_t *readbuff, uint32_t startSector, uint16_t numSectors); +uint16_t usb_mass_mal_write_memory(uint8_t lun, uint8_t *writebuff, uint32_t startSector, uint16_t numSectors); +void usb_mass_mal_format(uint8_t lun); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/STM32F1/libraries/USBComposite/usb_midi_device.c b/STM32F1/libraries/USBComposite/usb_midi_device.c new file mode 100644 index 000000000..7bb3ce843 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_midi_device.c @@ -0,0 +1,522 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * Copyright (c) 2013 Magnus Lundin. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/usb/stm32f1/usb_midi_device.c + * @brief USB MIDI. + * + * FIXME: this works on the STM32F1 USB peripherals, and probably no + * place else. Nonportable bits really need to be factored out, and + * the result made cleaner. + */ + +#include + +#include "usb_generic.h" +#include "usb_midi_device.h" +#include +#include + +#include +#include + +/* Private headers */ +#include "usb_lib_globals.h" +#include "usb_reg_map.h" + +/* usb_lib headers */ +#include "usb_type.h" +#include "usb_core.h" +#include "usb_def.h" + +static void midiDataTxCb(void); +static void midiDataRxCb(void); + +static void usbMIDIReset(void); + +#define MIDI_ENDPOINT_RX 0 +#define MIDI_ENDPOINT_TX 1 +#define USB_MIDI_RX_ENDP (midiEndpoints[MIDI_ENDPOINT_RX].address) +#define USB_MIDI_TX_ENDP (midiEndpoints[MIDI_ENDPOINT_TX].address) +#define USB_MIDI_RX_ENDPOINT_INFO (&midiEndpoints[MIDI_ENDPOINT_RX]) +#define USB_MIDI_TX_ENDPOINT_INFO (&midiEndpoints[MIDI_ENDPOINT_TX]) +#define USB_MIDI_RX_PMA_PTR (midiEndpoints[MIDI_ENDPOINT_RX].pma) +#define USB_MIDI_TX_PMA_PTR (midiEndpoints[MIDI_ENDPOINT_TX].pma) + +/* + * Descriptors + */ + +typedef struct { +// usb_descriptor_config_header Config_Header; + /* Control Interface */ + usb_descriptor_interface AC_Interface; + AC_CS_INTERFACE_DESCRIPTOR(1) AC_CS_Interface; + /* Control Interface */ + usb_descriptor_interface MS_Interface; + MS_CS_INTERFACE_DESCRIPTOR MS_CS_Interface; + MIDI_IN_JACK_DESCRIPTOR MIDI_IN_JACK_1; + MIDI_IN_JACK_DESCRIPTOR MIDI_IN_JACK_2; + MIDI_OUT_JACK_DESCRIPTOR(1) MIDI_OUT_JACK_3; + MIDI_OUT_JACK_DESCRIPTOR(1) MIDI_OUT_JACK_4; + usb_descriptor_endpoint DataOutEndpoint; + MS_CS_BULK_ENDPOINT_DESCRIPTOR(1) MS_CS_DataOutEndpoint; + usb_descriptor_endpoint DataInEndpoint; + MS_CS_BULK_ENDPOINT_DESCRIPTOR(1) MS_CS_DataInEndpoint; +} __packed usb_descriptor_config; + +static const usb_descriptor_config usbMIDIDescriptor_Config = { + /* .Config_Header = { + .bLength = sizeof(usb_descriptor_config_header), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION, + .wTotalLength = sizeof(usb_descriptor_config), + .bNumInterfaces = 0x02, + .bConfigurationValue = 0x01, + .iConfiguration = 0x00, + .bmAttributes = (USB_CONFIG_ATTR_BUSPOWERED | + USB_CONFIG_ATTR_SELF_POWERED), + .bMaxPower = MAX_POWER, + }, */ + + .AC_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = 0x00, // PATCH + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x00, + .bInterfaceClass = USB_INTERFACE_CLASS_AUDIO, + .bInterfaceSubClass = USB_INTERFACE_AUDIOCONTROL, + .bInterfaceProtocol = 0x00, + .iInterface = 0x00, + }, + + .AC_CS_Interface = { + .bLength = AC_CS_INTERFACE_DESCRIPTOR_SIZE(1), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE, + .SubType = 0x01, + .bcdADC = 0x0100, + .wTotalLength = AC_CS_INTERFACE_DESCRIPTOR_SIZE(1), + .bInCollection = 0x01, + .baInterfaceNr = {0x01}, + }, + + .MS_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = 0x01, // PATCH + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x02, + .bInterfaceClass = USB_INTERFACE_CLASS_AUDIO, + .bInterfaceSubClass = USB_INTERFACE_MIDISTREAMING, + .bInterfaceProtocol = 0x00, + .iInterface = 0, // was 0x04 + }, + + .MS_CS_Interface = { + .bLength = sizeof(MS_CS_INTERFACE_DESCRIPTOR), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE, + .SubType = 0x01, + .bcdADC = 0x0100, + .wTotalLength = sizeof(MS_CS_INTERFACE_DESCRIPTOR) + +sizeof(MIDI_IN_JACK_DESCRIPTOR) + +sizeof(MIDI_IN_JACK_DESCRIPTOR) + +MIDI_OUT_JACK_DESCRIPTOR_SIZE(1) + +MIDI_OUT_JACK_DESCRIPTOR_SIZE(1) + +sizeof(usb_descriptor_endpoint) + +MS_CS_BULK_ENDPOINT_DESCRIPTOR_SIZE(1) + +sizeof(usb_descriptor_endpoint) + +MS_CS_BULK_ENDPOINT_DESCRIPTOR_SIZE(1) + /* 0x41-4 */, + }, + + .MIDI_IN_JACK_1 = { + .bLength = sizeof(MIDI_IN_JACK_DESCRIPTOR), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE, + .SubType = MIDI_IN_JACK, + .bJackType = MIDI_JACK_EMBEDDED, + .bJackId = 0x01, + .iJack = 0x05, + }, + + .MIDI_IN_JACK_2 = { + .bLength = sizeof(MIDI_IN_JACK_DESCRIPTOR), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE, + .SubType = MIDI_IN_JACK, + .bJackType = MIDI_JACK_EXTERNAL, + .bJackId = 0x02, + .iJack = 0x00, + }, + + .MIDI_OUT_JACK_3 = { + .bLength = MIDI_OUT_JACK_DESCRIPTOR_SIZE(1), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE, + .SubType = MIDI_OUT_JACK, + .bJackType = MIDI_JACK_EMBEDDED, + .bJackId = 0x03, + .bNrInputPins = 0x01, + .baSourceId = {0x02}, + .baSourcePin = {0x01}, + .iJack = 0x00, + }, + + .MIDI_OUT_JACK_4 = { + .bLength = MIDI_OUT_JACK_DESCRIPTOR_SIZE(1), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE, + .SubType = MIDI_OUT_JACK, + .bJackType = MIDI_JACK_EXTERNAL, +// .bJackId = 0x04, + .bJackId = 0x03, + .bNrInputPins = 0x01, + .baSourceId = {0x01}, + .baSourcePin = {0x01}, + .iJack = 0x00, + }, + + .DataOutEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT | + 0), // PATCH: USB_MIDI_RX_ENDP + .bmAttributes = USB_EP_TYPE_BULK, + .wMaxPacketSize = 64, // PATCH + .bInterval = 0x00, + }, + + .MS_CS_DataOutEndpoint = { + .bLength = MS_CS_BULK_ENDPOINT_DESCRIPTOR_SIZE(1), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CS_ENDPOINT, + .SubType = 0x01, + .bNumEmbMIDIJack = 0x01, + .baAssocJackID = {0x01}, + }, + + .DataInEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | 0), // PATCH: USB_MIDI_TX_ENDP + .bmAttributes = USB_EP_TYPE_BULK, + .wMaxPacketSize = 64, // PATCH + .bInterval = 0x00, + }, + + .MS_CS_DataInEndpoint = { + .bLength = MS_CS_BULK_ENDPOINT_DESCRIPTOR_SIZE(1), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CS_ENDPOINT, + .SubType = 0x01, + .bNumEmbMIDIJack = 0x01, + .baAssocJackID = {0x03}, + }, + +}; + +/* I/O state */ + +/* Received data */ +static volatile uint32 midiBufferRx[64/4]; +/* Read index into midiBufferRx */ +static volatile uint32 rx_offset = 0; +/* Transmit data */ +static volatile uint32 midiBufferTx[64/4]; +/* Write index into midiBufferTx */ +static volatile uint32 tx_offset = 0; +/* Number of bytes left to transmit */ +static volatile uint32 n_unsent_packets = 0; +/* Are we currently sending an IN packet? */ +static volatile uint8 transmitting = 0; +/* Number of unread bytes */ +static volatile uint32 n_unread_packets = 0; + +uint32_t usb_midi_txEPSize = 64; +static uint32_t rxEPSize = 64; + +// eventually all of this should be in a place for settings which can be written to flash. +volatile uint8 myMidiChannel = DEFAULT_MIDI_CHANNEL; +volatile uint8 myMidiDevice = DEFAULT_MIDI_DEVICE; +volatile uint8 myMidiCable = DEFAULT_MIDI_CABLE; +volatile uint8 myMidiID[] = { LEAFLABS_MMA_VENDOR_1,LEAFLABS_MMA_VENDOR_2,LEAFLABS_MMA_VENDOR_3,0}; + +#define OUT_BYTE(s,v) out[(uint8*)&(s.v)-(uint8*)&s] +#define OUT_16(s,v) *(uint16_t*)&OUT_BYTE(s,v) // OK on Cortex which can handle unaligned writes + +static USBEndpointInfo midiEndpoints[2] = { + { + .callback = midiDataRxCb, + .pmaSize = 64, // patch + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 0, + .align = 1, + }, + { + .callback = midiDataTxCb, + .pmaSize = 64, // patch + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 1, + .exclusive = 0, + } +}; + +static void getMIDIPartDescriptor(uint8* out) { + memcpy(out, &usbMIDIDescriptor_Config, sizeof(usbMIDIDescriptor_Config)); + // patch to reflect where the part goes in the descriptor + OUT_BYTE(usbMIDIDescriptor_Config, AC_Interface.bInterfaceNumber) += usbMIDIPart.startInterface; + OUT_BYTE(usbMIDIDescriptor_Config, MS_Interface.bInterfaceNumber) += usbMIDIPart.startInterface; + OUT_BYTE(usbMIDIDescriptor_Config, AC_CS_Interface.baInterfaceNr) += usbMIDIPart.startInterface; + OUT_BYTE(usbMIDIDescriptor_Config, DataOutEndpoint.bEndpointAddress) += USB_MIDI_RX_ENDP; + OUT_BYTE(usbMIDIDescriptor_Config, DataInEndpoint.bEndpointAddress) += USB_MIDI_TX_ENDP; + OUT_16(usbMIDIDescriptor_Config, DataInEndpoint.wMaxPacketSize) = usb_midi_txEPSize; + OUT_16(usbMIDIDescriptor_Config, DataOutEndpoint.wMaxPacketSize) = rxEPSize; +} + +USBCompositePart usbMIDIPart = { + .numInterfaces = 2, + .numEndpoints = sizeof(midiEndpoints)/sizeof(*midiEndpoints), + .descriptorSize = sizeof(usbMIDIDescriptor_Config), + .getPartDescriptor = getMIDIPartDescriptor, + .usbInit = NULL, + .usbReset = usbMIDIReset, + .usbDataSetup = NULL, + .usbNoDataSetup = NULL, + .endpoints = midiEndpoints +}; + +void usb_midi_setTXEPSize(uint32_t size) { + size = (size+3)/4*4; + if (size == 0 || size > 64) + size = 64; + midiEndpoints[1].pmaSize = size; + usb_midi_txEPSize = size; +} + +void usb_midi_setRXEPSize(uint32_t size) { + size = (size+3)/4*4; + if (size == 0 || size > 64) + size = 64; + midiEndpoints[0].pmaSize = size; + rxEPSize = size; +} + +/* + * MIDI interface + */ + +/* This function is non-blocking. + * + * It copies data from a usercode buffer into the USB peripheral TX + * buffer, and returns the number of bytes copied. */ +uint32 usb_midi_tx(const uint32* buf, uint32 packets) { + uint32 bytes=packets*4; + /* Last transmission hasn't finished, so abort. */ + if (usb_midi_is_transmitting()) { + /* Copy to TxBuffer */ + + return 0; /* return len */ + } + + /* We can only put usb_midi_txEPSize bytes in the buffer. */ + if (bytes > usb_midi_txEPSize) { + bytes = usb_midi_txEPSize; + packets=bytes/4; + } + + /* Queue bytes for sending. */ + if (packets) { + usb_copy_to_pma_ptr((uint8 *)buf, bytes, USB_MIDI_TX_PMA_PTR); + } + // We still need to wait for the interrupt, even if we're sending + // zero bytes. (Sending zero-size packets is useful for flushing + // host-side buffers.) + n_unsent_packets = packets; + transmitting = 1; + usb_generic_set_tx(USB_MIDI_TX_ENDPOINT_INFO, bytes); + + return packets; +} + +uint32 usb_midi_data_available(void) { + return n_unread_packets; +} + +uint8 usb_midi_is_transmitting(void) { + return transmitting; +} + +uint16 usb_midi_get_pending(void) { + return n_unsent_packets; +} + +/* Nonblocking byte receive. + * + * Copies up to len bytes from our private data buffer (*NOT* the PMA) + * into buf and deq's the FIFO. */ +uint32 usb_midi_rx(uint32* buf, uint32 packets) { + /* Copy bytes to buffer. */ + uint32 n_copied = usb_midi_peek(buf, packets); + + /* Mark bytes as read. */ + n_unread_packets -= n_copied; + rx_offset += n_copied; + + /* If all bytes have been read, re-enable the RX endpoint, which + * was set to NAK when the current batch of bytes was received. */ + if (n_unread_packets == 0) { + usb_generic_enable_rx(USB_MIDI_RX_ENDPOINT_INFO); + rx_offset = 0; + } + + return n_copied; +} + +/* Nonblocking byte lookahead. + * + * Looks at unread bytes without marking them as read. */ +uint32 usb_midi_peek(uint32* buf, uint32 packets) { + uint32 i; + if (packets > n_unread_packets) { + packets = n_unread_packets; + } + + for (i = 0; i < packets; i++) { + buf[i] = midiBufferRx[i + rx_offset]; + } + + return packets; +} + +/* + * Callbacks + */ + +static void midiDataTxCb(void) { + n_unsent_packets = 0; + transmitting = 0; +} + +static void midiDataRxCb(void) { + usb_generic_pause_rx(USB_MIDI_RX_ENDPOINT_INFO); + n_unread_packets = usb_get_ep_rx_count(USB_MIDI_RX_ENDP) / 4; + /* This copy won't overwrite unread bytes, since we've set the RX + * endpoint to NAK, and will only set it to VALID when all bytes + * have been read. */ + + usb_copy_from_pma_ptr((uint8*)midiBufferRx, n_unread_packets * 4, + USB_MIDI_RX_PMA_PTR); + + // discard volatile + LglSysexHandler((uint32*)midiBufferRx,(uint32*)&rx_offset,(uint32*)&n_unread_packets); + + if (n_unread_packets == 0) { + usb_generic_enable_rx(USB_MIDI_RX_ENDPOINT_INFO); + rx_offset = 0; + } + +} + +static void usbMIDIReset(void) { + /* Reset the RX/TX state */ + n_unread_packets = 0; + n_unsent_packets = 0; + rx_offset = 0; +} + + +// .............THIS IS NOT WORKING YET................ +// send debugging information to +static uint8_t sysexbuffer[80]={CIN_SYSEX,0xF0,0x7D,0x33,CIN_SYSEX,0x33,0x00,0xf7}; // !!!bad hardcoded number foo !!! +uint8_t iSysHexLine(uint8_t rectype, uint16_t address, uint8_t *payload,uint8_t payloadlength, uint8_t *buffer); +void sendThroughSysex(char *printbuffer, int bufferlength) { + int n; + n = iSysHexLine(1, 0 , (uint8_t *) printbuffer, (uint8_t) bufferlength , sysexbuffer+6); + usb_midi_tx((uint32*)sysexbuffer,n/4); +} + +#define HIGHBYTE(x) ((uint8_t) (((x) >> 8) & 0x00ff) ) +#define LOWBYTE(x) ((uint8_t) ((x) & 0x00ff) ) +#define HIGHNIBBLE(x) ((((uint8_t)(x)) & 0xF0) >> 4) +#define LOWNIBBLE(x) (((uint8_t)(x)) & 0x0F) +#define HEXCHAR(c) ((c>9)?55+c:48+c) + + +uint8_t iSysHexLine(uint8_t rectype, uint16_t address, uint8_t *payload,uint8_t payloadlength, uint8_t *buffer) { + + int i=0; int j; int thirdone; + uint8_t n=0; + uint16_t checksum=0; + //uint16_t length=0; + + buffer[i++]=':'; + + checksum+=payloadlength; + buffer[i++]=HEXCHAR(HIGHNIBBLE(payloadlength)); + buffer[i++]=HEXCHAR(LOWNIBBLE(payloadlength)); + buffer[i++]=CIN_SYSEX; + + n=HIGHBYTE(address); + checksum+=n; + buffer[i++]=HEXCHAR(HIGHNIBBLE(n)); + buffer[i++]=HEXCHAR(LOWNIBBLE(n)); + + n=LOWBYTE(address); + checksum+=n; + buffer[i++]=HEXCHAR(HIGHNIBBLE(n)); + buffer[i++]=CIN_SYSEX; + buffer[i++]=HEXCHAR(LOWNIBBLE(n)); + + n=rectype; + checksum+=n; + buffer[i++]=HEXCHAR(HIGHNIBBLE(n)); + buffer[i++]=HEXCHAR(LOWNIBBLE(n)); + buffer[i++]=CIN_SYSEX; + thirdone=0; + for (j=0; j +#include +#include +#include +#include "usb_generic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern USBCompositePart usbMIDIPart; + +typedef union { + uint8 byte[4]; + uint32 data; +} USB_MIDI_Event_Packet; + +/* + * USB MIDI Requests + */ + +/* + * Descriptors, etc. + */ +#define USB_DESCRIPTOR_TYPE_CS_INTERFACE 0x24 +#define USB_DESCRIPTOR_TYPE_CS_ENDPOINT 0x25 + + +#define USB_DEVICE_CLASS_UNDEFINED 0x00 +#define USB_DEVICE_CLASS_CDC 0x02 +#define USB_DEVICE_SUBCLASS_UNDEFINED 0x00 + +#define USB_INTERFACE_CLASS_AUDIO 0x01 +#define USB_INTERFACE_SUBCLASS_UNDEFINED 0x00 +#define USB_INTERFACE_AUDIOCONTROL 0x01 +#define USB_INTERFACE_AUDIOSTREAMING 0x02 +#define USB_INTERFACE_MIDISTREAMING 0x03 + +/* MIDI Streaming class specific interfaces */ +#define MIDI_IN_JACK 0x02 +#define MIDI_OUT_JACK 0x03 + +#define MIDI_JACK_EMBEDDED 0x01 +#define MIDI_JACK_EXTERNAL 0x02 + + +#define AC_CS_INTERFACE_DESCRIPTOR_SIZE(DataSize) (8 + DataSize) +#define AC_CS_INTERFACE_DESCRIPTOR(DataSize) \ + struct { \ + uint8 bLength; \ + uint8 bDescriptorType; \ + uint8 SubType; \ + uint16 bcdADC; \ + uint16 wTotalLength; \ + uint8 bInCollection; \ + uint8 baInterfaceNr[DataSize]; \ + } __packed + +typedef struct { + uint8 bLength; + uint8 bDescriptorType; + uint8 SubType; + uint16 bcdADC; + uint16 wTotalLength; + } __packed MS_CS_INTERFACE_DESCRIPTOR; + +typedef struct { + uint8 bLength; + uint8 bDescriptorType; + uint8 SubType; + uint8 bJackType; + uint8 bJackId; + uint8 iJack; + } __packed MIDI_IN_JACK_DESCRIPTOR; + +#define MIDI_OUT_JACK_DESCRIPTOR_SIZE(DataSize) (7 + 2*DataSize) +#define MIDI_OUT_JACK_DESCRIPTOR(DataSize) \ + struct { \ + uint8 bLength; \ + uint8 bDescriptorType; \ + uint8 SubType; \ + uint8 bJackType; \ + uint8 bJackId; \ + uint8 bNrInputPins; \ + uint8 baSourceId[DataSize]; \ + uint8 baSourcePin[DataSize]; \ + uint8 iJack; \ + } __packed + + +#define MS_CS_BULK_ENDPOINT_DESCRIPTOR_SIZE(DataSize) (4 + DataSize) +#define MS_CS_BULK_ENDPOINT_DESCRIPTOR(DataSize) \ + struct { \ + uint8 bLength; \ + uint8 bDescriptorType; \ + uint8 SubType; \ + uint8 bNumEmbMIDIJack; \ + uint8 baAssocJackID[DataSize]; \ + } __packed + +/* + * Endpoint configuration + */ + +#ifndef __cplusplus +#define USB_MIDI_DECLARE_DEV_DESC(vid, pid) \ + { \ + .bLength = sizeof(usb_descriptor_device), \ + .bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE, \ + .bcdUSB = 0x0110, \ + .bDeviceClass = USB_DEVICE_CLASS_UNDEFINED, \ + .bDeviceSubClass = USB_DEVICE_SUBCLASS_UNDEFINED, \ + .bDeviceProtocol = 0x00, \ + .bMaxPacketSize0 = 0x40, \ + .idVendor = vid, \ + .idProduct = pid, \ + .bcdDevice = 0x0200, \ + .iManufacturer = 0x01, \ + .iProduct = 0x02, \ + .iSerialNumber = 0x00, \ + .bNumConfigurations = 0x01, \ + } +#endif + +/* + * Sysex Stuff. + */ + +#define SYSEX_BUFFER_LENGTH 256 + + + /* + * MIDI interface + */ + +void usb_midi_setTXEPSize(uint32_t size); +void usb_midi_setRXEPSize(uint32_t size); +uint32 usb_midi_tx(const uint32* buf, uint32 len); +uint32 usb_midi_rx(uint32* buf, uint32 len); +uint32 usb_midi_peek(uint32* buf, uint32 len); + +uint32 usb_midi_data_available(void); /* in RX buffer */ +uint16 usb_midi_get_pending(void); +uint8 usb_midi_is_transmitting(void); + +void sendThroughSysex(char *printbuffer, int bufferlength); + +extern uint32_t usb_midi_txEPSize; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/STM32F1/libraries/USBComposite/usb_multi_serial.c b/STM32F1/libraries/USBComposite/usb_multi_serial.c new file mode 100644 index 000000000..23d212cbd --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_multi_serial.c @@ -0,0 +1,658 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/usb/stm32f1/usb_hid.c + * @brief USB HID (human interface device) support + * + * FIXME: this works on the STM32F1 USB peripherals, and probably no + * place else. Nonportable bits really need to be factored out, and + * the result made cleaner. + */ + +#include "usb_multi_serial.h" +#include "usb_generic.h" +#include +#include +#include + +/* Private headers */ +#include "usb_lib_globals.h" +#include "usb_reg_map.h" + +#define CDCACM_ENDPOINT_TX 0 +#define CDCACM_ENDPOINT_MANAGEMENT 1 +#define CDCACM_ENDPOINT_RX 2 + +#define NUM_SERIAL_ENDPOINTS 3 +#define CCI_INTERFACE_OFFSET 0x00 +#define DCI_INTERFACE_OFFSET 0x01 +#define NUM_INTERFACES 2 +#define SERIAL_MANAGEMENT_INTERFACE_NUMBER(i) (usbMultiSerialPart.startInterface+CCI_INTERFACE_OFFSET+(port)*NUM_INTERFACES) + +#define CDC_SERIAL_RX_BUFFER_SIZE 256 // must be power of 2 +#define CDC_SERIAL_RX_BUFFER_SIZE_MASK (CDC_SERIAL_RX_BUFFER_SIZE-1) +#define CDC_SERIAL_TX_BUFFER_SIZE 256 // must be power of 2 +#define CDC_SERIAL_TX_BUFFER_SIZE_MASK (CDC_SERIAL_TX_BUFFER_SIZE-1) + +#define USB_CDCACM_MANAGEMENT_ENDP(port) (serialEndpoints[NUM_SERIAL_ENDPOINTS*(port)+CDCACM_ENDPOINT_MANAGEMENT].address) +#define USB_CDCACM_MANAGEMENT_ENDPOINT_INFO(port) (&serialEndpoints[NUM_SERIAL_ENDPOINTS*(port)+CDCACM_ENDPOINT_MANAGEMENT]) +#define USB_CDCACM_RX_ENDPOINT_INFO(port) (&serialEndpoints[NUM_SERIAL_ENDPOINTS*(port)+CDCACM_ENDPOINT_RX]) +#define USB_CDCACM_TX_ENDPOINT_INFO(port) (&serialEndpoints[NUM_SERIAL_ENDPOINTS*(port)+CDCACM_ENDPOINT_TX]) +#define USB_CDCACM_TX_ENDP(port) (serialEndpoints[NUM_SERIAL_ENDPOINTS*(port)+CDCACM_ENDPOINT_TX].address) +#define USB_CDCACM_RX_ENDP(port) (serialEndpoints[NUM_SERIAL_ENDPOINTS*(port)+CDCACM_ENDPOINT_RX].address) +#define USB_CDCACM_TX_PMA_PTR(port) (serialEndpoints[NUM_SERIAL_ENDPOINTS*(port)+CDCACM_ENDPOINT_TX].pma) +#define USB_CDCACM_RX_PMA_PTR(port) (serialEndpoints[NUM_SERIAL_ENDPOINTS*(port)+CDCACM_ENDPOINT_RX].pma) + +/* usb_lib headers */ +#include "usb_type.h" +#include "usb_core.h" +#include "usb_def.h" + +static void serialUSBReset(void); +static RESULT serialUSBDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength); +static RESULT serialUSBNoDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex); +static void vcomDataTxCb0(void); +static void vcomDataRxCb0(void); +static void vcomDataTxCb1(void); +static void vcomDataRxCb1(void); +static void vcomDataTxCb2(void); +static void vcomDataRxCb2(void); + +static volatile struct port_data { + /* Received data */ + uint8* vcomBufferRx; + /* Write index to vcomBufferRx */ + uint32 vcom_rx_head; + /* Read index from vcomBufferRx */ + uint32 vcom_rx_tail; + + // Tx data + uint8* vcomBufferTx; + // Write index to vcomBufferTx + uint32 vcom_tx_head; + // Read index from vcomBufferTx + uint32 vcom_tx_tail; + composite_cdcacm_line_coding line_coding; + uint8 line_dtr_rts; + int8 transmitting; + void (*rx_hook)(unsigned, void*); + void (*iface_setup_hook)(unsigned, void*); + uint32_t txEPSize; + uint32_t rxEPSize; +} ports[USB_MULTI_SERIAL_MAX_PORTS] = {{0}}; + +static void vcomDataTxCb(uint32 port); +static void vcomDataRxCb(uint32 port); + +static void vcomDataTxCb0(void) { + vcomDataTxCb(0); +} + +static void vcomDataTxCb1(void) { + vcomDataTxCb(1); +} + +static void vcomDataTxCb2(void) { + vcomDataTxCb(2); +} + +static void vcomDataRxCb0(void) { + vcomDataRxCb(0); +} + +static void vcomDataRxCb1(void) { + vcomDataRxCb(1); +} + +static void vcomDataRxCb2(void) { + vcomDataRxCb(2); +} + + +static uint32 numPorts = 3; + +static void usb_multi_serial_clear(void) { + memset((void*)ports, 0, sizeof ports); + numPorts = USB_MULTI_SERIAL_MAX_PORTS; +} + + +/* + * Descriptors + */ + +typedef struct { + //CDCACM + IADescriptor IAD; + usb_descriptor_interface CCI_Interface; + CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader; + CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_CallManagement; + CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_ACM; + CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union; + usb_descriptor_endpoint ManagementEndpoint; + usb_descriptor_interface DCI_Interface; + usb_descriptor_endpoint DataOutEndpoint; + usb_descriptor_endpoint DataInEndpoint; +} __packed serial_part_config; + + +static const serial_part_config serialPartConfigData = { + .IAD = { + .bLength = 0x08, + .bDescriptorType = 0x0B, + .bFirstInterface = CCI_INTERFACE_OFFSET, // PATCH + .bInterfaceCount = 0x02, + .bFunctionClass = 0x02, + .bFunctionSubClass = 0x02, + .bFunctionProtocol = 0x01, + .iFunction = 0x02, + }, + .CCI_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = CCI_INTERFACE_OFFSET, // PATCH + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x01, + .bInterfaceClass = USB_INTERFACE_CLASS_CDC, + .bInterfaceSubClass = USB_INTERFACE_SUBCLASS_CDC_ACM, + .bInterfaceProtocol = 0x01, /* Common AT Commands */ + .iInterface = 0x00, + }, + + .CDC_Functional_IntHeader = { + .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2), + .bDescriptorType = 0x24, + .SubType = 0x00, + .Data = {0x01, 0x10}, + }, + + .CDC_Functional_CallManagement = { + .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2), + .bDescriptorType = 0x24, + .SubType = 0x01, + .Data = {0x03, DCI_INTERFACE_OFFSET}, // PATCH + }, + + .CDC_Functional_ACM = { + .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(1), + .bDescriptorType = 0x24, + .SubType = 0x02, + .Data = {0x06}, + }, + + .CDC_Functional_Union = { + .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2), + .bDescriptorType = 0x24, + .SubType = 0x06, + .Data = {CCI_INTERFACE_OFFSET, DCI_INTERFACE_OFFSET}, // PATCH, PATCH + }, + + .ManagementEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | + 0), // PATCH: CDCACM_ENDPOINT_MANAGEMENT + .bmAttributes = USB_EP_TYPE_INTERRUPT, + .wMaxPacketSize = USBHID_CDCACM_MANAGEMENT_EPSIZE, + .bInterval = 0xFF, + }, + + .DCI_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = DCI_INTERFACE_OFFSET, // PATCH + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x02, + .bInterfaceClass = USB_INTERFACE_CLASS_DIC, + .bInterfaceSubClass = 0x00, /* None */ + .bInterfaceProtocol = 0x00, /* None */ + .iInterface = 0x00, + }, + + .DataOutEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT | + 0), // patch: CDCACM_ENDPOINT_RX + .bmAttributes = USB_EP_TYPE_BULK, + .wMaxPacketSize = USB_MULTI_SERIAL_DEFAULT_RX_SIZE, // patch + .bInterval = 0x00, + }, + + .DataInEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | 0), // PATCH: CDCACM_ENDPOINT_TX + .bmAttributes = USB_EP_TYPE_BULK, + .wMaxPacketSize = USB_MULTI_SERIAL_DEFAULT_TX_SIZE, // patch + .bInterval = 0x00, + } +}; + +static USBEndpointInfo serialEndpoints[NUM_SERIAL_ENDPOINTS*USB_MULTI_SERIAL_MAX_PORTS] = { + { + .callback = vcomDataTxCb0, + .pmaSize = USB_MULTI_SERIAL_DEFAULT_TX_SIZE, // patch + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 1, + }, + { + .callback = NULL, + .pmaSize = USBHID_CDCACM_MANAGEMENT_EPSIZE, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 1, + }, + { + .callback = vcomDataRxCb0, + .pmaSize = USB_MULTI_SERIAL_DEFAULT_RX_SIZE, // patch + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 0, + }, + { + .callback = vcomDataTxCb1, + .pmaSize = USB_MULTI_SERIAL_DEFAULT_TX_SIZE, // patch + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 1, + }, + { + .callback = NULL, + .pmaSize = USBHID_CDCACM_MANAGEMENT_EPSIZE, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 1, + }, + { + .callback = vcomDataRxCb1, + .pmaSize = USB_MULTI_SERIAL_DEFAULT_RX_SIZE, // patch + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 0, + }, + { + .callback = vcomDataTxCb2, + .pmaSize = USB_MULTI_SERIAL_DEFAULT_TX_SIZE, // patch + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 1, + }, + { + .callback = NULL, + .pmaSize = USBHID_CDCACM_MANAGEMENT_EPSIZE, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 1, + }, + { + .callback = vcomDataRxCb2, + .pmaSize = USB_MULTI_SERIAL_DEFAULT_RX_SIZE, // patch + .type = USB_GENERIC_ENDPOINT_TYPE_BULK, + .tx = 0, + }, +}; + +#define OUT_BYTE(s,v) out[(uint8*)&(s.v)-(uint8*)&s] +#define OUT_16(s,v) *(uint16_t*)&OUT_BYTE(s,v) // OK on Cortex which can handle unaligned writes + +static void getSerialPartDescriptor(uint8* _out) { + uint8* out = _out; + uint16 interface = usbMultiSerialPart.startInterface; + for (uint32 i=0; iline_coding.dwDTERate = 115200; + p->line_coding.bCharFormat = USBHID_CDCACM_STOP_BITS_1; + p->line_coding.bParityType = USBHID_CDCACM_PARITY_NONE; + p->line_coding.bDataBits = 8; + p->vcomBufferTx = buffers; + buffers += CDC_SERIAL_TX_BUFFER_SIZE; + p->vcomBufferRx = buffers; + p->rxEPSize = USB_MULTI_SERIAL_DEFAULT_RX_SIZE; + p->txEPSize = USB_MULTI_SERIAL_DEFAULT_TX_SIZE; + buffers += CDC_SERIAL_RX_BUFFER_SIZE; + } + + usbMultiSerialPart.numInterfaces = NUM_INTERFACES * numPorts; + usbMultiSerialPart.descriptorSize = sizeof(serial_part_config) * numPorts; + usbMultiSerialPart.numEndpoints = NUM_SERIAL_ENDPOINTS * numPorts; +} + +/* Other state (line coding, DTR/RTS) */ + +/* DTR in bit 0, RTS in bit 1. */ + +void multi_serial_set_hooks(uint32 port, unsigned hook_flags, void (*hook)(unsigned, void*)) { + volatile struct port_data* p = &ports[port]; + if (hook_flags & USBHID_CDCACM_HOOK_RX) { + p->rx_hook = hook; + } + if (hook_flags & USBHID_CDCACM_HOOK_IFACE_SETUP) { + p->iface_setup_hook = hook; + } +} + +/* This function is non-blocking. + * + * It copies data from a user buffer into the USB peripheral TX + * buffer, and returns the number of bytes copied. */ +uint32 multi_serial_tx(uint32 port, const uint8* buf, uint32 len) +{ + if (len==0) return 0; // no data to send + + volatile struct port_data* p = &ports[port]; + + uint32 head = p->vcom_tx_head; // load volatile variable + uint32 tx_unsent = (head - p->vcom_tx_tail) & CDC_SERIAL_TX_BUFFER_SIZE_MASK; + + // We can only put bytes in the buffer if there is place + if (len > (CDC_SERIAL_TX_BUFFER_SIZE-tx_unsent-1) ) { + len = (CDC_SERIAL_TX_BUFFER_SIZE-tx_unsent-1); + } + if (len==0) return 0; // buffer full + + uint16 i; + // copy data from user buffer to USB Tx buffer + for (i=0; ivcomBufferTx[head] = buf[i]; + head = (head+1) & CDC_SERIAL_TX_BUFFER_SIZE_MASK; + } + p->vcom_tx_head = head; // store volatile variable + + while(p->transmitting >= 0); + + if (p->transmitting < 0) { + vcomDataTxCb(port); // initiate data transmission + } + + return len; +} + + + +uint32 multi_serial_data_available(uint32 port) { + volatile struct port_data* p = &ports[port]; + return (p->vcom_rx_head - p->vcom_rx_tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; +} + +uint16 multi_serial_get_pending(uint32 port) { + volatile struct port_data* p = &ports[port]; + return (p->vcom_tx_head - p->vcom_tx_tail) & CDC_SERIAL_TX_BUFFER_SIZE_MASK; +} + +/* Non-blocking byte receive. + * + * Copies up to len bytes from our private data buffer (*NOT* the PMA) + * into buf and deq's the FIFO. */ +uint32 multi_serial_rx(uint32 port, uint8* buf, uint32 len) +{ + volatile struct port_data* p = &ports[port]; + /* Copy bytes to buffer. */ + uint32 n_copied = multi_serial_peek(port, buf, len); + + /* Mark bytes as read. */ + uint16 tail = p->vcom_rx_tail; // load volatile variable + tail = (tail + n_copied) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + p->vcom_rx_tail = tail; // store volatile variable + + uint32 rx_unread = (p->vcom_rx_head - tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + // If buffer was emptied to a pre-set value, re-enable the RX endpoint + if ( rx_unread <= 64 ) { // experimental value, gives the best performance + usb_generic_enable_rx(USB_CDCACM_RX_ENDPOINT_INFO(port)); + } + return n_copied; +} + +/* Non-blocking byte lookahead. + * + * Looks at unread bytes without marking them as read. */ +uint32 multi_serial_peek(uint32 port, uint8* buf, uint32 len) +{ + volatile struct port_data* p = &ports[port]; + unsigned i; + uint32 tail = p->vcom_rx_tail; + uint32 rx_unread = (p->vcom_rx_head-tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + + if (len > rx_unread) { + len = rx_unread; + } + + for (i = 0; i < len; i++) { + buf[i] = p->vcomBufferRx[tail]; + tail = (tail + 1) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + } + + return len; +} + +uint32 multi_serial_peek_ex(uint32 port, uint8* buf, uint32 offset, uint32 len) +{ + volatile struct port_data* p = &ports[port]; + unsigned i; + uint32 tail = (p->vcom_rx_tail + offset) & CDC_SERIAL_RX_BUFFER_SIZE_MASK ; + uint32 rx_unread = (p->vcom_rx_head-tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + + if (len + offset > rx_unread) { + len = rx_unread - offset; + } + + for (i = 0; i < len; i++) { + buf[i] = p->vcomBufferRx[tail]; + tail = (tail + 1) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + } + + return len; +} + +/* Roger Clark. Added. for Arduino 1.0 API support of Serial.peek() */ +int multi_serial_peek_char(uint32 port) +{ + if (multi_serial_data_available(port) == 0) + { + return -1; + } + + return ports[port].vcomBufferRx[ports[port].vcom_rx_tail]; +} + +uint8 multi_serial_get_dtr(uint32 port) { + return ((ports[port].line_dtr_rts & USBHID_CDCACM_CONTROL_LINE_DTR) != 0); +} + +uint8 multi_serial_get_rts(uint32 port) { + return ((ports[port].line_dtr_rts & USBHID_CDCACM_CONTROL_LINE_RTS) != 0); +} + +void multi_serial_get_line_coding(uint32 port, composite_cdcacm_line_coding *ret) { + volatile struct port_data* p = &ports[port]; + ret->dwDTERate = p->line_coding.dwDTERate; + ret->bCharFormat = p->line_coding.bCharFormat; + ret->bParityType = p->line_coding.bParityType; + ret->bDataBits = p->line_coding.bDataBits; +} + +int multi_serial_get_baud(uint32 port) { + return ports[port].line_coding.dwDTERate; +} + +int multi_serial_get_stop_bits(uint32 port) { + return ports[port].line_coding.bCharFormat; +} + +int multi_serial_get_parity(uint32 port) { + return ports[port].line_coding.bParityType; +} + +int multi_serial_get_n_data_bits(uint32 port) { + return ports[port].line_coding.bDataBits; +} + +/* + * Callbacks + */ +static void vcomDataTxCb(uint32 port) +{ + volatile struct port_data* p = &ports[port]; + usb_generic_send_from_circular_buffer(USB_CDCACM_TX_ENDPOINT_INFO(port), + p->vcomBufferTx, CDC_SERIAL_TX_BUFFER_SIZE, p->vcom_tx_head, &(p->vcom_tx_tail), &(p->transmitting)); +} + + +static void vcomDataRxCb(uint32 port) +{ + volatile struct port_data* p = &ports[port]; + uint32 head = p->vcom_rx_head; + usb_generic_read_to_circular_buffer(USB_CDCACM_RX_ENDPOINT_INFO(port), + p->vcomBufferRx, CDC_SERIAL_RX_BUFFER_SIZE, &head); + p->vcom_rx_head = head; // store volatile variable + + uint32 rx_unread = (head - p->vcom_rx_tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK; + // only enable further Rx if there is enough room to receive one more packet + if ( rx_unread < (CDC_SERIAL_RX_BUFFER_SIZE-p->rxEPSize) ) { + usb_generic_enable_rx(USB_CDCACM_RX_ENDPOINT_INFO(port)); + } + + if (p->rx_hook) { + p->rx_hook(USBHID_CDCACM_HOOK_RX, 0); + } +} + +static void serialUSBReset(void) { + //VCOM + for (uint32 port = 0; portvcom_rx_head = 0; + p->vcom_rx_tail = 0; + p->vcom_tx_head = 0; + p->vcom_tx_tail = 0; + p->transmitting = -1; + } +} + +#pragma GCC diagnostic ignored "-Wunused-parameter" +static RESULT serialUSBDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength) { + RESULT ret = USB_UNSUPPORT; + + if ((requestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT) && interface % NUM_INTERFACES == CCI_INTERFACE_OFFSET) { + uint32 port = interface / NUM_INTERFACES; + switch (request) { + case USBHID_CDCACM_GET_LINE_CODING: + usb_generic_control_tx_setup(&ports[port].line_coding, sizeof(ports[port].line_coding), NULL); + ret = USB_SUCCESS; + break; + case USBHID_CDCACM_SET_LINE_CODING: + usb_generic_control_rx_setup(&ports[port].line_coding, sizeof(ports[port].line_coding), NULL); + ret = USB_SUCCESS; + break; + default: + break; + } + /* Call the user hook. */ + if (ports[port].iface_setup_hook) { + uint8 req_copy = request; + ports[port].iface_setup_hook(USBHID_CDCACM_HOOK_IFACE_SETUP, &req_copy); + } + } + + return ret; +} + +static RESULT serialUSBNoDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex) { + RESULT ret = USB_UNSUPPORT; + + if ((requestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT) && interface % NUM_INTERFACES == CCI_INTERFACE_OFFSET) { + volatile struct port_data* p = &ports[interface / NUM_INTERFACES]; + switch(request) { + case USBHID_CDCACM_SET_COMM_FEATURE: + /* We support set comm. feature, but don't handle it. */ + ret = USB_SUCCESS; + break; + case USBHID_CDCACM_SET_CONTROL_LINE_STATE: + /* Track changes to DTR and RTS. */ + p->line_dtr_rts = wValue0 & + (USBHID_CDCACM_CONTROL_LINE_DTR | + USBHID_CDCACM_CONTROL_LINE_RTS); + ret = USB_SUCCESS; + break; + } + /* Call the user hook. */ + if (p->iface_setup_hook) { + uint8 req_copy = request; + p->iface_setup_hook(USBHID_CDCACM_HOOK_IFACE_SETUP, &req_copy); + } + } + return ret; +} + diff --git a/STM32F1/libraries/USBComposite/usb_multi_serial.h b/STM32F1/libraries/USBComposite/usb_multi_serial.h new file mode 100644 index 000000000..fb2203235 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_multi_serial.h @@ -0,0 +1,94 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/include/libmaple/usb_device.h + * @brief USB Composite with CDC ACM and HID support + * + * IMPORTANT: this API is unstable, and may change without notice. + */ + +#ifndef _USB_MULTI_SERIAL_H_ +#define _USB_MULTI_SERIAL_H_ + +#include +#include +#include "usb_generic.h" +#include "usb_composite_serial.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define USB_MULTI_SERIAL_MAX_PORTS 3 +#define USB_MULTI_SERIAL_DEFAULT_TX_SIZE 24 +#define USB_MULTI_SERIAL_DEFAULT_RX_SIZE 64 // must be pwoer of 2 for mysterious reasons +#define USB_MULTI_SERIAL_BUFFER_SIZE 256 // must be power of 2 due to code structure +#define USB_MULTI_SERIAL_BUFFERS_SIZE(numPorts) ((numPorts)*2*USB_MULTI_SERIAL_BUFFER_SIZE) + +void multi_serial_initialize_port_data(uint32 numPorts, uint8* buffers); + +extern USBCompositePart usbMultiSerialPart; + +/* + * CDC ACM interface + */ + +uint32 multi_serial_tx(uint32 port, const uint8* buf, uint32 len); +uint32 multi_serial_rx(uint32 port, uint8* buf, uint32 len); +uint32 multi_serial_peek(uint32 port, uint8* buf, uint32 len); +uint32 multi_serial_peek_ex(uint32 port, uint8* buf, uint32 offset, uint32 len); +void multi_serial_setTXEPSize(uint32 port, uint16_t size); +void multi_serial_setRXEPSize(uint32 port, uint16_t size); + +uint32 multi_serial_data_available(uint32 port); /* in RX buffer */ +uint16 multi_serial_get_pending(uint32 port); + +uint8 multi_serial_get_dtr(uint32 port); +uint8 multi_serial_get_rts(uint32 port); + +/* Retrieve a copy of the current line coding structure. */ +void multi_serial_get_line_coding(uint32, composite_cdcacm_line_coding*); + +/* Line coding conveniences. */ +int multi_serial_get_baud(uint32 port); /* dwDTERate */ +int multi_serial_get_stop_bits(uint32 port); /* bCharFormat */ +int multi_serial_get_parity(uint32 port); /* bParityType */ +int multi_serial_get_n_data_bits(uint32 port); /* bDataBits */ + +/* + * Hack: hooks for bootloader reset signalling + */ + +void multi_serial_set_hooks(uint32 port, unsigned hook_flags, void (*hook)(unsigned, void*)); + +#define multi_serial_remove_hooks(port, hook_flags) multi_serial_remove_hooks(port, hook_flags, 0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/STM32F1/libraries/USBComposite/usb_multi_x360.c b/STM32F1/libraries/USBComposite/usb_multi_x360.c new file mode 100644 index 000000000..849e2da8a --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_multi_x360.c @@ -0,0 +1,260 @@ +/*****************************f************************************************* + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * FIXME: this works on the STM32F1 USB peripherals, and probably no + * place else. Nonportable bits really need to be factored out, and + * the result made cleaner. + */ + +#include "usb_generic.h" +#include "usb_x360_generic.h" +#include "usb_multi_x360.h" + +#include + +#include +#include + +/* Private headers */ +#include "usb_lib_globals.h" +#include "usb_reg_map.h" + +/* usb_lib headers */ +#include "usb_type.h" +#include "usb_core.h" +#include "usb_def.h" + +#define NUM_INTERFACES 1 +#define NUM_ENDPOINTS 2 + +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) +#define HID_ENDPOINT_INT 1 + +#define HID_DESCRIPTOR_TYPE 0x21 + +#define REPORT_DESCRIPTOR 0x22 + + +typedef struct +{ + uint8_t len; // 9 + uint8_t dtype; // 0x21 + uint8_t versionL; // 0x101 + uint8_t versionH; // 0x101 + uint8_t country; + uint8_t numDesc; + uint8_t desctype; // 0x22 report + uint8_t descLenL; + uint8_t descLenH; +} HIDDescriptor; + +/* + * Descriptors + */ + +#if 0 +const uint8_t hid_report_descriptor[] = { + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x05, // USAGE (Game Pad) + 0xa1, 0x01, // COLLECTION (Application) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x3a, // USAGE (Counted Buffer) + 0xa1, 0x02, // COLLECTION (Logical) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x02, // REPORT_COUNT (2) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x3f, // USAGE (Reserved) + 0x09, 0x3b, // USAGE (Byte Count) + 0x81, 0x01, // INPUT (Cnst,Ary,Abs) + 0x75, 0x01, // REPORT_SIZE (1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x45, 0x01, // PHYSICAL_MAXIMUM (1) + 0x95, 0x04, // REPORT_COUNT (4) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x0c, // USAGE_MINIMUM (Button 12) + 0x29, 0x0f, // USAGE_MAXIMUM (Button 15) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x01, // REPORT_SIZE (1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x45, 0x01, // PHYSICAL_MAXIMUM (1) + 0x95, 0x04, // REPORT_COUNT (4) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x09, 0x09, // USAGE (Button 9) + 0x09, 0x0a, // USAGE (Button 10) + 0x09, 0x07, // USAGE (Button 7) + 0x09, 0x08, // USAGE (Button 8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x01, // REPORT_SIZE (1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x45, 0x01, // PHYSICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x09, 0x05, // USAGE (Button 5) + 0x09, 0x06, // USAGE (Button 6) + 0x09, 0x0b, // USAGE (Button 11) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x01, // INPUT (Cnst,Ary,Abs) + 0x75, 0x01, // REPORT_SIZE (1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x45, 0x01, // PHYSICAL_MAXIMUM (1) + 0x95, 0x04, // REPORT_COUNT (4) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x04, // USAGE_MAXIMUM (Button 4) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x08, // REPORT_SIZE (8) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255) + 0x95, 0x02, // REPORT_COUNT (2) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x32, // USAGE (Z) + 0x09, 0x35, // USAGE (Rz) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x10, // REPORT_SIZE (16) + 0x16, 0x00, 0x80, // LOGICAL_MINIMUM (-32768) + 0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767) + 0x36, 0x00, 0x80, // PHYSICAL_MINIMUM (-32768) + 0x46, 0xff, 0x7f, // PHYSICAL_MAXIMUM (32767) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + 0x95, 0x02, // REPORT_COUNT (2) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0xc0, // END_COLLECTION + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + 0x95, 0x02, // REPORT_COUNT (2) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x33, // USAGE (Rx) + 0x09, 0x34, // USAGE (Ry) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0xc0, // END_COLLECTION + 0xc0, // END_COLLECTION + 0xc0 // END_COLLECTION +}; +#endif + +typedef struct { +// usb_descriptor_config_header Config_Header; + usb_descriptor_interface HID_Interface; + uint8 unknown_descriptor1[17]; + usb_descriptor_endpoint DataInEndpoint; + usb_descriptor_endpoint DataOutEndpoint; +} __packed usb_descriptor_config; + + +#define MAX_POWER (100 >> 1) +static const usb_descriptor_config X360Descriptor_Config = +{ +#if 0 + .Config_Header = { + .bLength = sizeof(usb_descriptor_config_header), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION, + .wTotalLength = sizeof(usb_descriptor_config),//0, + .bNumInterfaces = 0x01, + .bConfigurationValue = 0x01, + .iConfiguration = 0x00, + .bmAttributes = (USB_CONFIG_ATTR_BUSPOWERED | + USB_CONFIG_ATTR_SELF_POWERED), + .bMaxPower = MAX_POWER, + }, +#endif + + .HID_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = X360_INTERFACE_OFFSET, // PATCH + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x02, + .bInterfaceClass = 0xFF, + .bInterfaceSubClass = 0x5D, + .bInterfaceProtocol = 0x01, + .iInterface = 0x00, + }, + + .unknown_descriptor1 = { + 17,33,0,1,1,37,129/* PATCH 0x80 | USB_X360_TX_ENDP */,20,0,0,0,0,19,2/* was 2, now PATCH: USB_X360_RX_ENDP */,8,0,0, + }, + + .DataInEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | 0),//PATCH: USB_X360_TX_ENDP + .bmAttributes = USB_EP_TYPE_INTERRUPT, + .wMaxPacketSize = 0x20, + .bInterval = 4, + }, + + .DataOutEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT | 0),//PATCH: USB_X360_RX_ENDP + .bmAttributes = USB_EP_TYPE_INTERRUPT, + .wMaxPacketSize = 0x20, + .bInterval = 8, + }, +}; + +#define OUT_BYTE(s,v) out[(uint8*)&(s.v)-(uint8*)&s] +#define OUT_16(s,v) *(uint16_t*)&OUT_BYTE(s,v) // OK on Cortex which can handle unaligned writes + +static void getMultiX360PartDescriptor(uint8* out) { + for(uint32 i=0; i +#include +#include #ifdef __cplusplus extern "C" { #endif -#include -#include -#include -#include + +void usb_multi_x360_initialize_controller_data(uint32 _numControllers, uint8* buffers); #ifdef __cplusplus } diff --git a/STM32F1/libraries/USBComposite/usb_scsi.c b/STM32F1/libraries/USBComposite/usb_scsi.c new file mode 100644 index 000000000..7b42647ed --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_scsi.c @@ -0,0 +1,339 @@ +#include "usb_mass.h" +#include "usb_mass_mal.h" +#include "usb_mass_internal.h" +#include "usb_scsi.h" + +#include +#include + +/* Private headers */ +#include "usb_lib_globals.h" +#include "usb_reg_map.h" +#include "usb_regs.h" + +/* usb_lib headers */ +#include "usb_type.h" +#include "usb_core.h" +#include "usb_def.h" + +#define SCSI_READ_FORMAT_CAPACITY_DATA_LEN 0x0C +#define SCSI_READ_FORMAT_CAPACITY10_DATA_LEN 0x08 +#define SCSI_MODE_SENSE6_DATA_LEN 0x04 +#define SCSI_MODE_SENSE10_DATA_LEN 0x08 + +#define SCSI_TXFR_IDLE 0 +#define SCSI_TXFR_ONGOING 1 + +extern uint32_t usb_mass_sil_write(uint8_t* pBufferPointer, uint32_t wBufferSize); + +/* See usb_scsi_data.c */ +extern uint8_t SCSI_page00InquiryData[]; +extern uint8_t SCSI_standardInquiryData[]; +extern uint8_t SCSI_standardInquiryData2[]; +extern uint8_t SCSI_senseData[]; +extern uint8_t SCSI_modeSense6Data[]; +extern uint8_t SCSI_modeSense10Data[]; +extern uint8_t SCSI_readFormatCapacityData[]; +extern uint8_t SCSI_readFormatCapacity10Data[]; + +uint32_t SCSI_lba; +uint32_t SCSI_blkLen; +uint8_t SCSI_transferState = SCSI_TXFR_IDLE; +uint32_t SCSI_blockReadCount = 0; +uint32_t SCSI_blockOffset; +uint32_t SCSI_counter = 0; +uint8_t SCSI_dataBuffer[512]; /* 512 bytes (SDCard block size) */ + +uint8_t scsi_address_management(uint8_t lun, uint8_t cmd, uint32_t lba, uint32_t blockNbr); +void scsi_read_memory(uint8_t lun, uint32_t memoryOffset, uint32_t transferLength); +void scsi_write_memory(uint8_t lun, uint32_t memoryOffset, uint32_t transferLength); + +void scsi_inquiry_cmd(uint8_t lun) { + uint8_t* inquiryData; + uint16_t inquiryDataLength; + + if (usb_mass_CBW.CB[1] & 0x01) /*Evpd is set*/ { + inquiryData = SCSI_page00InquiryData; + inquiryDataLength = 5; + } else { + if (lun == 0) { + inquiryData = SCSI_standardInquiryData; + } else { + inquiryData = SCSI_standardInquiryData2; + } + + if (usb_mass_CBW.CB[4] <= SCSI_STANDARD_INQUIRY_DATA_LEN) { + inquiryDataLength = usb_mass_CBW.CB[4]; + } else { + inquiryDataLength = SCSI_STANDARD_INQUIRY_DATA_LEN; + } + } + usb_mass_transfer_data_request(inquiryData, inquiryDataLength); +} + +void scsi_request_sense_cmd(uint8_t lun) { + (void)lun; + uint8_t requestSenseDataLength; + if (usb_mass_CBW.CB[4] <= SCSI_REQUEST_SENSE_DATA_LEN) { + requestSenseDataLength = usb_mass_CBW.CB[4]; + } else { + requestSenseDataLength = SCSI_REQUEST_SENSE_DATA_LEN; + } + usb_mass_transfer_data_request(SCSI_senseData, requestSenseDataLength); +} + +void scsi_start_stop_unit_cmd(uint8_t lun) { + (void)lun; + usb_mass_bot_set_csw(BOT_CSW_CMD_PASSED, BOT_SEND_CSW_ENABLE); +} + +void scsi_mode_sense6_cmd(uint8_t lun) { + (void)lun; + usb_mass_transfer_data_request(SCSI_modeSense6Data, SCSI_MODE_SENSE6_DATA_LEN); +} + +void scsi_mode_sense10_cmd(uint8_t lun) { + (void)lun; + usb_mass_transfer_data_request(SCSI_modeSense10Data, SCSI_MODE_SENSE10_DATA_LEN); +} + +void scsi_read_format_capacity_cmd(uint8_t lun) { + if (usb_mass_mal_get_status(lun)) { + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_NOT_READY, SCSI_MEDIUM_NOT_PRESENT); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_ENABLE); + usb_mass_bot_abort(BOT_DIR_IN); + return; + } + SCSI_readFormatCapacityData[4] = (uint8_t) (usb_mass_drives[lun].blockCount >> 24); + SCSI_readFormatCapacityData[5] = (uint8_t) (usb_mass_drives[lun].blockCount >> 16); + SCSI_readFormatCapacityData[6] = (uint8_t) (usb_mass_drives[lun].blockCount >> 8); + SCSI_readFormatCapacityData[7] = (uint8_t) (usb_mass_drives[lun].blockCount); + + SCSI_readFormatCapacityData[9] = (uint8_t) (SCSI_BLOCK_SIZE >> 16); + SCSI_readFormatCapacityData[10] = (uint8_t) (SCSI_BLOCK_SIZE >> 8); + SCSI_readFormatCapacityData[11] = (uint8_t) (SCSI_BLOCK_SIZE); + usb_mass_transfer_data_request(SCSI_readFormatCapacityData, SCSI_READ_FORMAT_CAPACITY_DATA_LEN); +} + +void scsi_read_capacity10_cmd(uint8_t lun) { + if (usb_mass_mal_get_status(lun)) { + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_NOT_READY, SCSI_MEDIUM_NOT_PRESENT); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_ENABLE); + usb_mass_bot_abort(BOT_DIR_IN); + return; + } + + SCSI_readFormatCapacity10Data[0] = (uint8_t) ((usb_mass_drives[lun].blockCount - 1) >> 24); + SCSI_readFormatCapacity10Data[1] = (uint8_t) ((usb_mass_drives[lun].blockCount - 1) >> 16); + SCSI_readFormatCapacity10Data[2] = (uint8_t) ((usb_mass_drives[lun].blockCount - 1) >> 8); + SCSI_readFormatCapacity10Data[3] = (uint8_t) (usb_mass_drives[lun].blockCount - 1); + + SCSI_readFormatCapacity10Data[4] = (uint8_t) (SCSI_BLOCK_SIZE >> 24); + SCSI_readFormatCapacity10Data[5] = (uint8_t) (SCSI_BLOCK_SIZE >> 16); + SCSI_readFormatCapacity10Data[6] = (uint8_t) (SCSI_BLOCK_SIZE >> 8); + SCSI_readFormatCapacity10Data[7] = (uint8_t) (SCSI_BLOCK_SIZE); + usb_mass_transfer_data_request(SCSI_readFormatCapacity10Data, SCSI_READ_FORMAT_CAPACITY10_DATA_LEN); +} + +void scsi_read10_cmd(uint8_t lun, uint32_t lba, uint32_t blockNbr) { + if (usb_mass_botState == BOT_STATE_IDLE) { + if (!(scsi_address_management(usb_mass_CBW.bLUN, SCSI_READ10, lba, blockNbr))) /*address out of range*/ { + return; + } + + if ((usb_mass_CBW.bmFlags & 0x80) != 0) { + usb_mass_botState = BOT_STATE_DATA_IN; + scsi_read_memory(lun, lba, blockNbr); + } else { + usb_mass_bot_abort(BOT_DIR_BOTH); + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_INVALID_FIELED_IN_COMMAND); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_ENABLE); + } + return; + } else if (usb_mass_botState == BOT_STATE_DATA_IN) { + scsi_read_memory(lun, lba, blockNbr); + } +} + +void scsi_write10_cmd(uint8_t lun, uint32_t lba, uint32_t blockNbr) { + if (usb_mass_botState == BOT_STATE_IDLE) { + if (!(scsi_address_management(usb_mass_CBW.bLUN, SCSI_WRITE10, lba, blockNbr)))/*address out of range*/ { + return; + } + + if ((usb_mass_CBW.bmFlags & 0x80) == 0) { + usb_mass_botState = BOT_STATE_DATA_OUT; + usb_generic_enable_rx(USB_MASS_RX_ENDPOINT_INFO); + } else { + usb_mass_bot_abort(BOT_DIR_IN); + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_INVALID_FIELED_IN_COMMAND); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_DISABLE); + } + return; + } else if (usb_mass_botState == BOT_STATE_DATA_OUT) { + scsi_write_memory(lun, lba, blockNbr); + } +} + +void scsi_test_unit_ready_cmd(uint8_t lun) { + if (usb_mass_mal_get_status(lun)) { + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_NOT_READY, SCSI_MEDIUM_NOT_PRESENT); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_ENABLE); + usb_mass_bot_abort(BOT_DIR_IN); + return; + } else { + usb_mass_bot_set_csw(BOT_CSW_CMD_PASSED, BOT_SEND_CSW_ENABLE); + } +} + +void scsi_verify10_cmd(uint8_t lun) { + (void)lun; + if ((usb_mass_CBW.dDataLength == 0) && !(usb_mass_CBW.CB[1] & SCSI_BLKVFY))/* BLKVFY not set*/ { + usb_mass_bot_set_csw(BOT_CSW_CMD_PASSED, BOT_SEND_CSW_ENABLE); + } else { + usb_mass_bot_abort(BOT_DIR_BOTH); + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_INVALID_FIELED_IN_COMMAND); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_DISABLE); + } +} + +void scsi_format_cmd(uint8_t lun) { + if (usb_mass_mal_get_status(lun)) { + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_NOT_READY, SCSI_MEDIUM_NOT_PRESENT); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_ENABLE); + usb_mass_bot_abort(BOT_DIR_IN); + return; + } + usb_mass_mal_format(lun); + usb_mass_bot_set_csw(BOT_CSW_CMD_PASSED, BOT_SEND_CSW_ENABLE); +} + +void scsi_set_sense_data(uint8_t lun, uint8_t sensKey, uint8_t asc) { + (void)lun; + SCSI_senseData[2] = sensKey; + SCSI_senseData[12] = asc; +} + +void scsi_invalid_cmd(uint8_t lun) { + (void)lun; + if (usb_mass_CBW.dDataLength == 0) { + usb_mass_bot_abort(BOT_DIR_IN); + } else { + if ((usb_mass_CBW.bmFlags & 0x80) != 0) { + usb_mass_bot_abort(BOT_DIR_IN); + } else { + usb_mass_bot_abort(BOT_DIR_BOTH); + } + } + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_INVALID_COMMAND); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_DISABLE); +} + +uint8_t scsi_address_management(uint8_t lun, uint8_t cmd, uint32_t lba, uint32_t blockNbr) { + + if ((lba + blockNbr) > usb_mass_drives[lun].blockCount) { + if (cmd == SCSI_WRITE10) { + usb_mass_bot_abort(BOT_DIR_BOTH); + } + usb_mass_bot_abort(BOT_DIR_IN); + scsi_set_sense_data(lun, SCSI_ILLEGAL_REQUEST, SCSI_ADDRESS_OUT_OF_RANGE); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_DISABLE); + return (FALSE); + } + + + if (usb_mass_CBW.dDataLength != blockNbr * SCSI_BLOCK_SIZE) { + if (cmd == SCSI_WRITE10) { + usb_mass_bot_abort(BOT_DIR_BOTH); + } else { + usb_mass_bot_abort(BOT_DIR_IN); + } + scsi_set_sense_data(usb_mass_CBW.bLUN, SCSI_ILLEGAL_REQUEST, SCSI_INVALID_FIELED_IN_COMMAND); + usb_mass_bot_set_csw(BOT_CSW_CMD_FAILED, BOT_SEND_CSW_DISABLE); + return (FALSE); + } + return (TRUE); +} + +void scsi_read_memory(uint8_t lun, uint32_t startSector, uint32_t numSectors) { + static uint32_t length; + static uint64_t offset; + + if (SCSI_transferState == SCSI_TXFR_IDLE) { + offset = (uint64_t)startSector * SCSI_BLOCK_SIZE; + length = numSectors * SCSI_BLOCK_SIZE; + SCSI_transferState = SCSI_TXFR_ONGOING; + } + + if (SCSI_transferState == SCSI_TXFR_ONGOING) { + if (SCSI_blockReadCount == 0) { + usb_mass_mal_read_memory(lun, SCSI_dataBuffer, (uint32_t)(offset/SCSI_BLOCK_SIZE), 1); + + SCSI_blockReadCount = SCSI_BLOCK_SIZE - MAX_BULK_PACKET_SIZE; + SCSI_blockOffset = MAX_BULK_PACKET_SIZE; + + usb_mass_sil_write(SCSI_dataBuffer, MAX_BULK_PACKET_SIZE); + } else { + usb_mass_sil_write(SCSI_dataBuffer + SCSI_blockOffset, MAX_BULK_PACKET_SIZE); + + SCSI_blockReadCount -= MAX_BULK_PACKET_SIZE; + SCSI_blockOffset += MAX_BULK_PACKET_SIZE; + } + + offset += MAX_BULK_PACKET_SIZE; + length -= MAX_BULK_PACKET_SIZE; + + usb_mass_CSW.dDataResidue -= MAX_BULK_PACKET_SIZE; + usb_mass_CSW.bStatus = BOT_CSW_CMD_PASSED; + // TODO: Led_RW_ON(); + } + + if (length == 0) { + SCSI_blockReadCount = 0; + SCSI_blockOffset = 0; + offset = 0; + usb_mass_botState = BOT_STATE_DATA_IN_LAST; + SCSI_transferState = SCSI_TXFR_IDLE; + // TODO: Led_RW_OFF(); + } +} + +void scsi_write_memory(uint8_t lun, uint32_t startSector, uint32_t numSectors) { + static uint32_t length; + static uint64_t offset; + uint32_t idx; + uint32_t temp = SCSI_counter + 64; + + if (SCSI_transferState == SCSI_TXFR_IDLE) { + offset = (uint64_t)startSector * SCSI_BLOCK_SIZE; + length = numSectors * SCSI_BLOCK_SIZE; + SCSI_transferState = SCSI_TXFR_ONGOING; + } + + if (SCSI_transferState == SCSI_TXFR_ONGOING) { + + for (idx = 0; SCSI_counter < temp; SCSI_counter++) { + *((uint8_t *) SCSI_dataBuffer + SCSI_counter) = usb_mass_bulkDataBuff[idx++]; + } + + offset += usb_mass_dataLength; + length -= usb_mass_dataLength; + + if (!(length % SCSI_BLOCK_SIZE)) { + SCSI_counter = 0; + usb_mass_mal_write_memory(lun, SCSI_dataBuffer, (uint32_t)(offset/SCSI_BLOCK_SIZE) - 1, 1); + } + + usb_mass_CSW.dDataResidue -= usb_mass_dataLength; + usb_generic_enable_rx(USB_MASS_RX_ENDPOINT_INFO); /* enable the next transaction*/ // TODO + + // TODO: Led_RW_ON(); + } + + if ((length == 0) || (usb_mass_botState == BOT_STATE_CSW_Send)) { + SCSI_counter = 0; + usb_mass_bot_set_csw(BOT_CSW_CMD_PASSED, BOT_SEND_CSW_ENABLE); + SCSI_transferState = SCSI_TXFR_IDLE; + // TODO: Led_RW_OFF(); + } +} diff --git a/STM32F1/libraries/USBComposite/usb_scsi.h b/STM32F1/libraries/USBComposite/usb_scsi.h new file mode 100644 index 000000000..8a99899ab --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_scsi.h @@ -0,0 +1,94 @@ +#ifndef __USB_SCSI_H +#define __USB_SCSI_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + /* SCSI Commands */ +#define SCSI_FORMAT_UNIT 0x04 +#define SCSI_INQUIRY 0x12 +#define SCSI_MODE_SELECT6 0x15 +#define SCSI_MODE_SELECT10 0x55 +#define SCSI_MODE_SENSE6 0x1A +#define SCSI_MODE_SENSE10 0x5A +#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E +#define SCSI_READ6 0x08 +#define SCSI_READ10 0x28 +#define SCSI_READ12 0xA8 +#define SCSI_READ16 0x88 + +#define SCSI_READ_CAPACITY10 0x25 +#define SCSI_READ_CAPACITY16 0x9E + +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_START_STOP_UNIT 0x1B +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_WRITE6 0x0A +#define SCSI_WRITE10 0x2A +#define SCSI_WRITE12 0xAA +#define SCSI_WRITE16 0x8A + +#define SCSI_VERIFY10 0x2F +#define SCSI_VERIFY12 0xAF +#define SCSI_VERIFY16 0x8F + +#define SCSI_SEND_DIAGNOSTIC 0x1D +#define SCSI_READ_FORMAT_CAPACITIES 0x23 + +#define SCSI_NO_SENSE 0 +#define SCSI_RECOVERED_ERROR 1 +#define SCSI_NOT_READY 2 +#define SCSI_MEDIUM_ERROR 3 +#define SCSI_HARDWARE_ERROR 4 +#define SCSI_ILLEGAL_REQUEST 5 +#define SCSI_UNIT_ATTENTION 6 +#define SCSI_DATA_PROTECT 7 +#define SCSI_BLANK_CHECK 8 +#define SCSI_VENDOR_SPECIFIC 9 +#define SCSI_COPY_ABORTED 10 +#define SCSI_ABORTED_COMMAND 11 +#define SCSI_VOLUME_OVERFLOW 13 +#define SCSI_MISCOMPARE 14 + +#define SCSI_INVALID_COMMAND 0x20 +#define SCSI_INVALID_FIELED_IN_COMMAND 0x24 +#define SCSI_PARAMETER_LIST_LENGTH_ERROR 0x1A +#define SCSI_INVALID_FIELD_IN_PARAMETER_LIST 0x26 +#define SCSI_ADDRESS_OUT_OF_RANGE 0x21 +#define SCSI_MEDIUM_NOT_PRESENT 0x3A +#define SCSI_MEDIUM_HAVE_CHANGED 0x28 + +#define SCSI_READ_FORMAT_CAPACITY_DATA_LEN 0x0C +#define SCSI_READ_CAPACITY10_DATA_LEN 0x08 +#define SCSI_MODE_SENSE10_DATA_LEN 0x08 +#define SCSI_MODE_SENSE6_DATA_LEN 0x04 +#define SCSI_REQUEST_SENSE_DATA_LEN 0x12 +#define SCSI_STANDARD_INQUIRY_DATA_LEN 0x24 +#define SCSI_BLKVFY 0x04 + + extern uint32_t SCSI_lba; + extern uint32_t SCSI_blkLen; + + void scsi_inquiry_cmd(uint8_t lun); + void scsi_request_sense_cmd(uint8_t lun); + void scsi_start_stop_unit_cmd(uint8_t lun); + void scsi_mode_sense6_cmd(uint8_t lun); + void scsi_mode_sense10_cmd(uint8_t lun); + void scsi_read_format_capacity_cmd(uint8_t lun); + void scsi_read_capacity10_cmd(uint8_t lun); + void scsi_read10_cmd(uint8_t lun, uint32_t lba, uint32_t blockNbr); + void scsi_write10_cmd(uint8_t lun, uint32_t lba, uint32_t blockNbr); + void scsi_test_unit_ready_cmd(uint8_t lun); + void scsi_verify10_cmd(uint8_t lun); + void scsi_format_cmd(uint8_t lun); + void scsi_set_sense_data(uint8_t lun, uint8_t sensKey, uint8_t asc); + void scsi_invalid_cmd(uint8_t lun); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/STM32F1/libraries/USBComposite/usb_scsi_data.c b/STM32F1/libraries/USBComposite/usb_scsi_data.c new file mode 100644 index 000000000..a692fd769 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_scsi_data.c @@ -0,0 +1,120 @@ + +#include "usb_scsi.h" + +uint8_t SCSI_page00InquiryData[] = { + 0x00, /* PERIPHERAL QUALIFIER & PERIPHERAL DEVICE TYPE*/ + 0x00, + 0x00, + 0x00, + 0x00 /* Supported Pages 00*/ +}; + +uint8_t SCSI_standardInquiryData[] = { + 0x00, /* Direct Access Device */ + 0x80, /* RMB = 1: Removable Medium */ + 0x02, /* Version: No conformance claim to standard */ + 0x02, + + 36 - 4, /* Additional Length */ + 0x00, /* SCCS = 1: Storage Controller Component */ + 0x00, + 0x00, + /* Vendor Identification */ + 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', + /* Product Identification */ + 'S', 'D', ' ', 'F', 'l', 'a', 's', 'h', ' ', + 'D', 'i', 's', 'k', ' ', ' ', ' ', + /* Product Revision Level */ + '1', '.', '0', ' ' +}; + +uint8_t SCSI_standardInquiryData2[] = { + 0x00, /* Direct Access Device */ + 0x80, /* RMB = 1: Removable Medium */ + 0x02, /* Version: No conformance claim to standard */ + 0x02, + + 36 - 4, /* Additional Length */ + 0x00, /* SCCS = 1: Storage Controller Component */ + 0x00, + 0x00, + /* Vendor Identification */ + 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', + /* Product Identification */ + 'N', 'A', 'N', 'D', ' ', 'F', 'l', 'a', 's', 'h', ' ', + 'D', 'i', 's', 'k', ' ', + /* Product Revision Level */ + '1', '.', '0', ' ' +}; + +uint8_t SCSI_senseData[] = { + 0x70, /*RespCode*/ + 0x00, /*SegmentNumber*/ + SCSI_NO_SENSE, /* Sens_Key*/ + 0x00, + 0x00, + 0x00, + 0x00, /*Information*/ + 0x0A, /*AdditionalSenseLength*/ + 0x00, + 0x00, + 0x00, + 0x00, /*CmdInformation*/ + SCSI_NO_SENSE, /*Asc*/ + 0x00, /*ASCQ*/ + 0x00, /*FRUC*/ + 0x00, /*TBD*/ + 0x00, + 0x00 /*SenseKeySpecific*/ +}; + +uint8_t SCSI_modeSense6Data[] = { + 0x03, + 0x00, + 0x00, + 0x00, +}; + +uint8_t SCSI_modeSense10Data[] = { + 0x00, + 0x06, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; + +uint8_t SCSI_readFormatCapacityData[] = { + 0x00, + 0x00, + 0x00, + 0x08, /* Capacity List Length */ + + /* Block Count */ + 0, + 0, + 0, + 0, + + /* Block Length */ + 0x02, /* Descriptor Code: Formatted Media */ + 0, + 0, + 0 +}; + +uint8_t SCSI_readFormatCapacity10Data[] = { + /* Last Logical Block */ + 0, + 0, + 0, + 0, + + /* Block Length */ + 0, + 0, + 0, + 0 +}; \ No newline at end of file diff --git a/STM32F3/cores/maple/libmaple/dma_private.h b/STM32F1/libraries/USBComposite/usb_setup.cpp similarity index 57% rename from STM32F3/cores/maple/libmaple/dma_private.h rename to STM32F1/libraries/USBComposite/usb_setup.cpp index b25ded2b9..c711c312b 100644 --- a/STM32F3/cores/maple/libmaple/dma_private.h +++ b/STM32F1/libraries/USBComposite/usb_setup.cpp @@ -24,38 +24,35 @@ * SOFTWARE. *****************************************************************************/ -#ifndef _LIBMAPLE_DMA_PRIVATE_H_ -#define _LIBMAPLE_DMA_PRIVATE_H_ - -#include -#include - -/* - * IRQ handling +/** + * @file wirish/stm32f1/boards_setup.cpp + * @author Marti Bolivar + * @brief STM32F1 chip setup. + * + * This file controls how init() behaves on the STM32F1. Be very + * careful when changing anything here. Many of these values depend + * upon each other. */ -/* Wrap this in an ifdef to shut up GCC. (We provide DMA_GET_HANDLER - * in the series support files, which need dma_irq_handler().) */ -#ifdef DMA_GET_HANDLER -static __always_inline void dma_irq_handler(dma_dev *dev, dma_tube tube) { - void (*handler)(void) = DMA_GET_HANDLER(dev, tube); - if (handler) { - handler(); - dma_clear_isr_bits(dev, tube); /* in case handler doesn't */ - } -} -#endif +#include "boards_private.h" +#include +#include -/* - * Conveniences for dealing with tube sources/destinations - */ +#include -enum dma_atype { - DMA_ATYPE_MEM, - DMA_ATYPE_PER, - DMA_ATYPE_OTHER, -}; +namespace wirish { + namespace priv { -enum dma_atype _dma_addr_type(__io void *addr); + void board_setup_usb(void) { +#ifdef GENERIC_BOOTLOADER + //Reset the USB interface on generic boards - developed by Victor PV + gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_OUTPUT_PP); + gpio_write_bit(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit,0); + + for(volatile unsigned int i=0;i<512;i++);// Only small delay seems to be needed, and USB pins will get configured in Serial.begin + gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING); +#endif + } -#endif + } +} diff --git a/STM32F1/libraries/USBComposite/usb_x360_generic.c b/STM32F1/libraries/USBComposite/usb_x360_generic.c new file mode 100644 index 000000000..202831656 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_x360_generic.c @@ -0,0 +1,427 @@ +/*****************************f************************************************* + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * FIXME: this works on the STM32F1 USB peripherals, and probably no + * place else. Nonportable bits really need to be factored out, and + * the result made cleaner. + */ + +#include "usb_generic.h" +#include "usb_x360_generic.h" + +#include + +#include +#include + +/* Private headers */ +#include "usb_lib_globals.h" +#include "usb_reg_map.h" + +/* usb_lib headers */ +#include "usb_type.h" +#include "usb_core.h" +#include "usb_def.h" + +typedef enum _HID_REQUESTS +{ + + GET_REPORT = 1, + GET_IDLE, + GET_PROTOCOL, + + SET_REPORT = 9, + SET_IDLE, + SET_PROTOCOL + +} HID_REQUESTS; + +#define NUM_INTERFACES 1 +#define NUM_ENDPOINTS 2 + +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) +#define HID_ENDPOINT_INT 1 + +#define HID_DESCRIPTOR_TYPE 0x21 + +#define REPORT_DESCRIPTOR 0x22 + + +typedef struct +{ + uint8_t len; // 9 + uint8_t dtype; // 0x21 + uint8_t versionL; // 0x101 + uint8_t versionH; // 0x101 + uint8_t country; + uint8_t numDesc; + uint8_t desctype; // 0x22 report + uint8_t descLenL; + uint8_t descLenH; +} HIDDescriptor; + +#define X360_INTERFACE_OFFSET 0 +#define X360_INTERFACE_NUMBER (X360_INTERFACE_OFFSET+usbX360Part.startInterface) +#define X360_ENDPOINT_TX 0 +#define X360_ENDPOINT_RX 1 + +static void x360_clear(void); + +uint32 x360_num_controllers = USB_X360_MAX_CONTROLLERS; + +static void x360DataRxCb(uint32 controller); +static void x360DataTxCb(uint32 controller); +static void x360DataTxCb0(void) { x360DataTxCb(0); } +static void x360DataRxCb0(void) { x360DataRxCb(0); } +static void x360DataTxCb1(void) { x360DataTxCb(1); } +static void x360DataRxCb1(void) { x360DataRxCb(1); } +static void x360DataTxCb2(void) { x360DataTxCb(2); } +static void x360DataRxCb2(void) { x360DataRxCb(2); } +static void x360DataTxCb3(void) { x360DataTxCb(3); } +static void x360DataRxCb3(void) { x360DataRxCb(3); } + +static void x360Reset(void); +static RESULT x360DataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength); +static RESULT x360NoDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex); + +/* + * Descriptors + */ + +#if 0 +const uint8_t hid_report_descriptor[] = { + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x05, // USAGE (Game Pad) + 0xa1, 0x01, // COLLECTION (Application) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x3a, // USAGE (Counted Buffer) + 0xa1, 0x02, // COLLECTION (Logical) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x02, // REPORT_COUNT (2) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x3f, // USAGE (Reserved) + 0x09, 0x3b, // USAGE (Byte Count) + 0x81, 0x01, // INPUT (Cnst,Ary,Abs) + 0x75, 0x01, // REPORT_SIZE (1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x45, 0x01, // PHYSICAL_MAXIMUM (1) + 0x95, 0x04, // REPORT_COUNT (4) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x0c, // USAGE_MINIMUM (Button 12) + 0x29, 0x0f, // USAGE_MAXIMUM (Button 15) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x01, // REPORT_SIZE (1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x45, 0x01, // PHYSICAL_MAXIMUM (1) + 0x95, 0x04, // REPORT_COUNT (4) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x09, 0x09, // USAGE (Button 9) + 0x09, 0x0a, // USAGE (Button 10) + 0x09, 0x07, // USAGE (Button 7) + 0x09, 0x08, // USAGE (Button 8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x01, // REPORT_SIZE (1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x45, 0x01, // PHYSICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x09, 0x05, // USAGE (Button 5) + 0x09, 0x06, // USAGE (Button 6) + 0x09, 0x0b, // USAGE (Button 11) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x01, // INPUT (Cnst,Ary,Abs) + 0x75, 0x01, // REPORT_SIZE (1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x45, 0x01, // PHYSICAL_MAXIMUM (1) + 0x95, 0x04, // REPORT_COUNT (4) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x04, // USAGE_MAXIMUM (Button 4) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x08, // REPORT_SIZE (8) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) + 0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255) + 0x95, 0x02, // REPORT_COUNT (2) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x32, // USAGE (Z) + 0x09, 0x35, // USAGE (Rz) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x10, // REPORT_SIZE (16) + 0x16, 0x00, 0x80, // LOGICAL_MINIMUM (-32768) + 0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767) + 0x36, 0x00, 0x80, // PHYSICAL_MINIMUM (-32768) + 0x46, 0xff, 0x7f, // PHYSICAL_MAXIMUM (32767) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + 0x95, 0x02, // REPORT_COUNT (2) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0xc0, // END_COLLECTION + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + 0x95, 0x02, // REPORT_COUNT (2) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x33, // USAGE (Rx) + 0x09, 0x34, // USAGE (Ry) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0xc0, // END_COLLECTION + 0xc0, // END_COLLECTION + 0xc0 // END_COLLECTION +}; +#endif + +typedef struct { +// usb_descriptor_config_header Config_Header; + usb_descriptor_interface HID_Interface; + uint8 unknown_descriptor1[20]; + usb_descriptor_endpoint DataInEndpoint; + usb_descriptor_endpoint DataOutEndpoint; +} __packed usb_descriptor_config; + + +USBEndpointInfo x360Endpoints[NUM_ENDPOINTS*USB_X360_MAX_CONTROLLERS] = { + { + .callback = x360DataTxCb0, + .pmaSize = 0x20, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 1 + }, + { + .callback = x360DataRxCb0, + .pmaSize = 0x20, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 0, + }, + { + .callback = x360DataTxCb1, + .pmaSize = 0x20, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 1 + }, + { + .callback = x360DataRxCb1, + .pmaSize = 0x20, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 0, + }, + { + .callback = x360DataTxCb2, + .pmaSize = 0x20, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 1 + }, + { + .callback = x360DataRxCb2, + .pmaSize = 0x20, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 0, + }, + { + .callback = x360DataTxCb3, + .pmaSize = 0x20, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 1 + }, + { + .callback = x360DataRxCb3, + .pmaSize = 0x20, + .type = USB_GENERIC_ENDPOINT_TYPE_INTERRUPT, + .tx = 0, + }, +}; + +USBCompositePart usbX360Part = { + .numInterfaces = USB_X360_MAX_CONTROLLERS * NUM_INTERFACES, + .numEndpoints = sizeof(x360Endpoints)/sizeof(*x360Endpoints), + .descriptorSize = 0, // patch + .getPartDescriptor = NULL, // patch + .usbInit = NULL, + .usbReset = x360Reset, + .usbDataSetup = x360DataSetup, + .usbNoDataSetup = x360NoDataSetup, + .endpoints = x360Endpoints, + .clear = x360_clear +}; + + +static volatile struct controller_data { + uint32 ProtocolValue; + uint8* hidBufferRx; + uint32 n_unsent_bytes; + uint8 transmitting; + void (*rumble_callback)(uint8 left, uint8 right); + void (*led_callback)(uint8 pattern); +} controllers[USB_X360_MAX_CONTROLLERS] = {{0}}; + +static void x360_clear(void) { + memset((void*)controllers, 0, sizeof controllers); + x360_num_controllers = USB_X360_MAX_CONTROLLERS; +} + +void x360_generic_initialize_controller_data(uint32 _numControllers, uint8* buffers) { + x360_num_controllers = _numControllers; + + for (uint32 i=0; ihidBufferRx = buffers; + buffers += USB_X360_RX_EPSIZE; + c->rumble_callback = NULL; + c->led_callback = NULL; + } + + usbX360Part.numInterfaces = NUM_INTERFACES * x360_num_controllers; + usbX360Part.numEndpoints = NUM_ENDPOINTS * x360_num_controllers; +} + + +/* + * HID interface + */ + +void x360_set_rumble_callback(uint32 controller, void (*callback)(uint8 left, uint8 right)) { + controllers[controller].rumble_callback = callback; +} + +void x360_set_led_callback(uint32 controller, void (*callback)(uint8 pattern)) { + controllers[controller].led_callback = callback; +} + +uint8 x360_is_transmitting(uint32 controller) { + return controllers[controller].transmitting; +} + +/* This function is non-blocking. + * + * It copies data from a usercode buffer into the USB peripheral TX + * buffer, and returns the number of bytes copied. */ +uint32 x360_tx(uint32 controller, const uint8* buf, uint32 len) { + volatile struct controller_data* c = &controllers[controller]; + + /* Last transmission hasn't finished, so abort. */ + if (x360_is_transmitting(controller)) { + return 0; + } + + /* We can only put USB_X360_TX_EPSIZE bytes in the buffer. */ + if (len > USB_X360_TX_EPSIZE) { + len = USB_X360_TX_EPSIZE; + } + + /* Queue bytes for sending. */ + if (len) { + usb_copy_to_pma_ptr(buf, len, USB_X360_TX_PMA_PTR(controller)); + } + // We still need to wait for the interrupt, even if we're sending + // zero bytes. (Sending zero-size packets is useful for flushing + // host-side buffers.) + c->n_unsent_bytes = len; + c->transmitting = 1; + usb_generic_set_tx(USB_X360_TX_ENDPOINT_INFO(controller), len); + + return len; +} + +static void x360DataRxCb(uint32 controller) +{ + volatile struct controller_data* c = &controllers[controller]; + USBEndpointInfo* ep = USB_X360_RX_ENDPOINT_INFO(controller); + + volatile uint8* hidBufferRx = c->hidBufferRx; + + uint32 ep_rx_size = usb_generic_read_to_buffer(ep, hidBufferRx, USB_X360_RX_EPSIZE); + + if (ep_rx_size == 3) { // wired + if (c->led_callback != NULL && hidBufferRx[0] == 1 && hidBufferRx[1] == 3) + c->led_callback(hidBufferRx[2]); + } + else if (ep_rx_size == 8) { // wired + if (c->rumble_callback != NULL && hidBufferRx[0] == 0 && hidBufferRx[1] == 8) + c->rumble_callback(hidBufferRx[3],hidBufferRx[4]); + } + else if (ep_rx_size == 12) { // wireless + if (c->led_callback != NULL && hidBufferRx[0] == 0 && hidBufferRx[1] == 0) + c->led_callback(hidBufferRx[3]); + if (c->rumble_callback != NULL && hidBufferRx[0] == 0 && hidBufferRx[1] == 1) + c->rumble_callback(hidBufferRx[5],hidBufferRx[6]); + } + + usb_generic_enable_rx(ep); +} + +/* + * Callbacks + */ + +static void x360DataTxCb(uint32 controller) { + volatile struct controller_data* c = &controllers[controller]; + + c->n_unsent_bytes = 0; + c->transmitting = 0; +} + + +static void x360Reset(void) { + /* Reset the RX/TX state */ + for (uint8 i = 0 ; i < x360_num_controllers ; i++) { + volatile struct controller_data* c = &controllers[i]; + c->n_unsent_bytes = 0; + c->transmitting = 0; + } +} + +#pragma GCC diagnostic ignored "-Wunused-parameter" +static RESULT x360DataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex, uint16 wLength) { + if((requestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT) && request == GET_PROTOCOL) { + usb_generic_control_tx_setup(&controllers[interface / NUM_INTERFACES].ProtocolValue, 1, NULL); + return USB_SUCCESS; + } + return USB_UNSUPPORT; +} + +static RESULT x360NoDataSetup(uint8 request, uint8 interface, uint8 requestType, uint8 wValue0, uint8 wValue1, uint16 wIndex) { + if ((requestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT) && request == SET_PROTOCOL) { + controllers[interface / NUM_INTERFACES].ProtocolValue = wValue0; + return USB_SUCCESS; + } + return USB_UNSUPPORT; +} diff --git a/STM32F1/libraries/USBComposite/usb_x360_generic.h b/STM32F1/libraries/USBComposite/usb_x360_generic.h new file mode 100644 index 000000000..004736ae8 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_x360_generic.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +#ifndef _USB_X360_GENERIC_H +#define _USB_X360_GENERIC_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Descriptors, etc. + */ + +//extern const uint8_t hid_report_descriptor[]; + +/* + * Endpoint configuration + */ + +#define USB_X360_MAX_CONTROLLERS 4 +#define USB_X360_TX_EPSIZE 0x20 +#define USB_X360_RX_EPSIZE 0x20 +#define USB_X360_BUFFER_SIZE_PER_CONTROLLER USB_X360_RX_EPSIZE + +extern USBEndpointInfo x360Endpoints[]; +extern uint32 x360_num_controllers; +extern USBCompositePart usbX360Part; +/* + * HID interface + */ + +uint32 x360_tx(uint32 controller, const uint8* buf, uint32 len); +uint8 x360_is_transmitting(uint32 controller); +void x360_set_rumble_callback(uint32 controller, void (*callback)(uint8 left, uint8 right)); +void x360_set_led_callback(uint32 controller, void (*callback)(uint8 pattern)); +void x360_generic_initialize_controller_data(uint32 _numControllers, uint8* buffers); + +#define X360_INTERFACE_OFFSET 0 +#define X360_INTERFACE_NUMBER (X360_INTERFACE_OFFSET+usbX360Part.startInterface) +#define X360_NUM_INTERFACES 1 +#define X360_ENDPOINT_TX 0 +#define X360_ENDPOINT_RX 1 +#define X360_NUM_ENDPOINTS 2 + +#define USB_X360_RX_ENDPOINT_INFO(i) &x360Endpoints[(i)*X360_NUM_ENDPOINTS+X360_ENDPOINT_RX] +#define USB_X360_TX_ENDPOINT_INFO(i) &x360Endpoints[(i)*X360_NUM_ENDPOINTS+X360_ENDPOINT_TX] +#define USB_X360_RX_PMA_PTR(i) x360Endpoints[(i)*X360_NUM_ENDPOINTS+X360_ENDPOINT_RX].pma +#define USB_X360_TX_PMA_PTR(i) x360Endpoints[(i)*X360_NUM_ENDPOINTS+X360_ENDPOINT_TX].pma +#define USB_X360_RX_ENDP(i) x360Endpoints[(i)*X360_NUM_ENDPOINTS+X360_ENDPOINT_RX].address +#define USB_X360_TX_ENDP(i) x360Endpoints[(i)*X360_NUM_ENDPOINTS+X360_ENDPOINT_TX].address + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/STM32F1/libraries/USBComposite/usb_x360w.c b/STM32F1/libraries/USBComposite/usb_x360w.c new file mode 100644 index 000000000..3cebb19e9 --- /dev/null +++ b/STM32F1/libraries/USBComposite/usb_x360w.c @@ -0,0 +1,136 @@ +/*****************************f************************************************* + * The MIT License + * + * Copyright (c) 2011 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * FIXME: this works on the STM32F1 USB peripherals, and probably no + * place else. Nonportable bits really need to be factored out, and + * the result made cleaner. + */ + +#include "usb_generic.h" +#include "usb_x360_generic.h" +#include "usb_x360w.h" + +#include + +#include +#include + +/* Private headers */ +#include "usb_lib_globals.h" +#include "usb_reg_map.h" + +/* usb_lib headers */ +#include "usb_type.h" +#include "usb_core.h" +#include "usb_def.h" + +typedef struct { +// usb_descriptor_config_header Config_Header; + usb_descriptor_interface HID_Interface; + uint8 unknown_descriptor1[20]; + usb_descriptor_endpoint DataInEndpoint; + usb_descriptor_endpoint DataOutEndpoint; +} __packed usb_descriptor_config; + + +#define MAX_POWER (100 >> 1) +static const usb_descriptor_config X360WDescriptor_Config = +{ +#if 0 + .Config_Header = { + .bLength = sizeof(usb_descriptor_config_header), + .bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION, + .wTotalLength = sizeof(usb_descriptor_config),//0, + .bNumInterfaces = 0x01, + .bConfigurationValue = 0x01, + .iConfiguration = 0x00, + .bmAttributes = (USB_CONFIG_ATTR_BUSPOWERED | + USB_CONFIG_ATTR_SELF_POWERED), + .bMaxPower = MAX_POWER, + }, +#endif + + .HID_Interface = { + .bLength = sizeof(usb_descriptor_interface), + .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = X360_INTERFACE_OFFSET, // PATCH + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x02, + .bInterfaceClass = 0xFF, + .bInterfaceSubClass = 0x5D, + .bInterfaceProtocol = 129, + .iInterface = 0x00, + }, + + .unknown_descriptor1 = { +// 17,33,0,1,1,37,129/* PATCH 0x80 | USB_X360W_TX_ENDP */,20,0,0,0,0,19,2/* was 2, now PATCH: USB_X360W_RX_ENDP */,8,0,0, + 0x14,0x22,0x00,0x01,0x13,0x81/* PATCH 0x80 | USB_X360W_TX_ENDP */,0x1d,0x00,0x17,0x01,0x02,0x08,0x13,0x01/* PATCH: USB_X360W_RX_ENDP */,0x0c,0x00,0x0c,0x01,0x02,0x08 + }, + + .DataInEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | 0),//PATCH: USB_X360W_TX_ENDP + .bmAttributes = USB_EP_TYPE_INTERRUPT, + .wMaxPacketSize = 0x20, + .bInterval = 4, + }, + + .DataOutEndpoint = { + .bLength = sizeof(usb_descriptor_endpoint), + .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT | 0),//PATCH: USB_X360W_RX_ENDP + .bmAttributes = USB_EP_TYPE_INTERRUPT, + .wMaxPacketSize = 0x20, + .bInterval = 8, + }, +}; + +#define OUT_BYTE(s,v) out[(uint8*)&(s.v)-(uint8*)&s] +#define OUT_16(s,v) *(uint16_t*)&OUT_BYTE(s,v) // OK on Cortex which can handle unaligned writes + +static void getX360WPartDescriptor(uint8* out) { + for(uint32 i=0; i +#ifndef _USB_X360W_H +#define _USB_X360W_H #include -#include +#include +#include -void delay(unsigned long ms) { - uint32 i; - for (i = 0; i < ms; i++) { - delayMicroseconds(1000); - } -} +#ifdef __cplusplus +extern "C" { +#endif -void delayMicroseconds(uint32 us) { - delay_us(us); +void x360w_initialize_controller_data(uint32 _numControllers, uint8* buffers); + +#ifdef __cplusplus } +#endif + +#endif diff --git a/STM32F1/libraries/WS2812B/src/WS2812B.cpp b/STM32F1/libraries/WS2812B/src/WS2812B.cpp index 36483fccd..14155461e 100644 --- a/STM32F1/libraries/WS2812B/src/WS2812B.cpp +++ b/STM32F1/libraries/WS2812B/src/WS2812B.cpp @@ -30,7 +30,7 @@ // Constructor when n is the number of LEDs in the strip WS2812B::WS2812B(uint16_t number_of_leds) : - brightness(0), pixels(NULL) + brightness(0), pixels(NULL), doubleBuffer(NULL), begun(false) { updateLength(number_of_leds); } diff --git a/STM32F1/libraries/Wire/SoftWire.cpp b/STM32F1/libraries/Wire/SoftWire.cpp index 4e3cdd587..646c9bfaf 100644 --- a/STM32F1/libraries/Wire/SoftWire.cpp +++ b/STM32F1/libraries/Wire/SoftWire.cpp @@ -58,17 +58,15 @@ void SoftWire::set_scl(bool state) { I2C_DELAY(this->i2c_delay); gpio_write_bit(sclDevice,sclBit, state); -// digitalWrite(this->scl_pin,state); //Allow for clock stretching - dangerous currently if (state == HIGH) { - while(digitalRead(this->scl_pin) == 0); + while (gpio_read_bit(sclDevice,sclBit) == 0); } } void SoftWire::set_sda(bool state) { I2C_DELAY(this->i2c_delay); gpio_write_bit(sdaDevice,sdaBit, state); - //digitalWrite(this->sda_pin, state); } void SoftWire::i2c_start() { @@ -93,7 +91,7 @@ bool SoftWire::i2c_get_ack() { set_sda(HIGH); set_scl(HIGH); - bool ret = !digitalRead(this->sda_pin); + bool ret = (gpio_read_bit(sdaDevice, sdaBit) == 0); set_scl(LOW); return ret; } @@ -117,7 +115,7 @@ uint8 SoftWire::i2c_shift_in() { int i; for (i = 0; i < 8; i++) { set_scl(HIGH); - data |= digitalRead(this->sda_pin) << (7-i); + data |= gpio_read_bit(sdaDevice, sdaBit) ? (1 << (7-i)) : 0; set_scl(LOW); } @@ -195,6 +193,7 @@ SoftWire::SoftWire(uint8 scl, uint8 sda, uint8 delay) : i2c_delay(delay) { } void SoftWire::begin(uint8 self_addr) { + (void)self_addr; tx_buf_idx = 0; tx_buf_overflow = false; rx_buf_idx = 0; diff --git a/STM32F1/libraries/Wire/Wire.cpp b/STM32F1/libraries/Wire/Wire.cpp index dbf4c663b..4982bbbaa 100644 --- a/STM32F1/libraries/Wire/Wire.cpp +++ b/STM32F1/libraries/Wire/Wire.cpp @@ -44,13 +44,15 @@ uint8 TwoWire::process(uint8 stop) { if (sel_hard->error_flags & I2C_SR1_AF) { /* NACK */ res = (sel_hard->error_flags & I2C_SR1_ADDR ? ENACKADDR : ENACKTRNS); - } else if (sel_hard->error_flags & I2C_SR1_OVR) { /* Over/Underrun */ - res = EDATA; - } else { /* Bus or Arbitration error */ - res = EOTHER; + } else { + if (sel_hard->error_flags & I2C_SR1_OVR) { /* Over/Underrun */ + res = EDATA; + } else { /* Bus or Arbitration error */ + res = EOTHER; + } + i2c_disable(sel_hard); + i2c_master_enable(sel_hard, dev_flags, frequency); } - i2c_disable(sel_hard); - i2c_master_enable(sel_hard, (I2C_BUS_RESET | dev_flags)); } return res; } @@ -60,8 +62,9 @@ uint8 TwoWire::process(){ } // TODO: Add in Error Handling if devsel is out of range for other Maples -TwoWire::TwoWire(uint8 dev_sel, uint8 flags) { - if (dev_sel == 1) { +TwoWire::TwoWire(uint8 dev_sel, uint8 flags, uint32 freq) { + + if (dev_sel == 1) { sel_hard = I2C1; } else if (dev_sel == 2) { sel_hard = I2C2; @@ -69,6 +72,12 @@ TwoWire::TwoWire(uint8 dev_sel, uint8 flags) { ASSERT(1); } dev_flags = flags; + + if (freq == 100000 && (flags & I2C_FAST_MODE)) // compatibility patch + frequency = 400000; + else + frequency = freq; + } TwoWire::~TwoWire() { @@ -77,7 +86,7 @@ TwoWire::~TwoWire() { } void TwoWire::begin(uint8 self_addr) { - i2c_master_enable(sel_hard, dev_flags); + i2c_master_enable(sel_hard, dev_flags, frequency); } void TwoWire::end() { @@ -87,19 +96,11 @@ void TwoWire::end() { void TwoWire::setClock(uint32_t frequencyHz) { - switch(frequencyHz) - { - case 400000: - dev_flags |= I2C_FAST_MODE;// set FAST_MODE bit - break; - case 100000: - default: - dev_flags &= ~I2C_FAST_MODE;// clear FAST_MODE bit - break; - } + if (sel_hard->regs->CR1 & I2C_CR1_PE){ + frequency = frequencyHz; i2c_disable(sel_hard); - i2c_master_enable(sel_hard, dev_flags); + i2c_master_enable(sel_hard, dev_flags, frequency); } } diff --git a/STM32F1/libraries/Wire/Wire.h b/STM32F1/libraries/Wire/Wire.h index ab05d4216..a2890c196 100644 --- a/STM32F1/libraries/Wire/Wire.h +++ b/STM32F1/libraries/Wire/Wire.h @@ -47,32 +47,37 @@ class TwoWire : public WireBase { private: i2c_dev* sel_hard; uint8 dev_flags; + uint32 frequency; //new variable to store i2c frequency protected: /* * Processes the incoming I2C message defined by WireBase to the * hardware. If an error occured, restart the I2C device. */ - uint8 process(uint8); + uint8 process(uint8 stop); uint8 process(); public: /* * Check if devsel is within range and enable selected I2C interface with - * passed flags + * passed flags and frequency. + *(frequency tested go up to 1.2Mhz @F_CPU 72Mhz with capable slaves) */ - TwoWire(uint8, uint8 = 0); + TwoWire(uint8 dev_sel, uint8 flags = 0, uint32 freq = 100000); /* * Shuts down (disables) the hardware I2C */ void end(); + /* + * Sets the hardware I2C clock + */ void setClock(uint32_t frequencyHz); /* * Disables the I2C device and remove the device address. */ ~TwoWire(); - void begin(uint8 = 0x00); + void begin(uint8 self_addr = 0x00); }; extern TwoWire Wire; #endif // _TWOWIRE_H_ diff --git a/STM32F1/libraries/Wire/library.properties b/STM32F1/libraries/Wire/library.properties new file mode 100644 index 000000000..06b7aee78 --- /dev/null +++ b/STM32F1/libraries/Wire/library.properties @@ -0,0 +1,10 @@ +name=Wire +version=1.0 +author=Roger Clark +maintainer= +sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. +paragraph= +category=Communication +url=http://www.arduino.cc/en/Reference/Wire +architectures=STM32F1 +include=Wire.h,SoftWire.h diff --git a/STM32F1/libraries/Wire/utility/WireBase.cpp b/STM32F1/libraries/Wire/utility/WireBase.cpp index 220d845d7..327eabff0 100644 --- a/STM32F1/libraries/Wire/utility/WireBase.cpp +++ b/STM32F1/libraries/Wire/utility/WireBase.cpp @@ -42,6 +42,7 @@ #include "wirish.h" void WireBase::begin(uint8 self_addr) { + (void)self_addr; tx_buf_idx = 0; tx_buf_overflow = false; rx_buf_idx = 0; @@ -71,13 +72,13 @@ uint8 WireBase::endTransmission(bool stop) { } uint8 WireBase::endTransmission(){ - endTransmission(true); + return endTransmission(true); } //TODO: Add the ability to queue messages (adding a boolean to end of function // call, allows for the Arduino style to stay while also giving the flexibility // to bulk send -uint8 WireBase::requestFrom(uint8 address, int num_bytes) { +uint8 WireBase::requestFrom(uint8 address, int num_bytes,bool stop) { if (num_bytes > BUFFER_LENGTH) { num_bytes = BUFFER_LENGTH; } @@ -85,37 +86,43 @@ uint8 WireBase::requestFrom(uint8 address, int num_bytes) { itc_msg.flags = I2C_MSG_READ; itc_msg.length = num_bytes; itc_msg.data = &rx_buf[rx_buf_idx]; - process(); + process(stop); rx_buf_len += itc_msg.xferred; itc_msg.flags = 0; return rx_buf_len; } -uint8 WireBase::requestFrom(int address, int numBytes) { - return WireBase::requestFrom((uint8)address, numBytes); +uint8 WireBase::requestFrom(int address, int numBytes, bool stop) { + return WireBase::requestFrom((uint8)address, numBytes,stop); } -void WireBase::write(uint8 value) { +size_t WireBase::write(uint8 value) { if (tx_buf_idx == BUFFER_LENGTH) { tx_buf_overflow = true; - return; + return 0; } tx_buf[tx_buf_idx++] = value; itc_msg.length++; + return 1; } -void WireBase::write(uint8* buf, int len) { +size_t WireBase::write(uint8* buf, int len) { for (uint8 i = 0; i < len; i++) { - write(buf[i]); + if (!write(buf[i])) + { + return i; + } } + return len; } -void WireBase::write(int value) { - write((uint8)value); + +size_t WireBase::write(int value) { + return write((uint8)value); } -void WireBase::write(int* buf, int len) { - write((uint8*)buf, (uint8)len); +size_t WireBase::write(int* buf, int len) { + return write((uint8*)buf, (uint8)len); } void WireBase::write(char* buf) { diff --git a/STM32F1/libraries/Wire/utility/WireBase.h b/STM32F1/libraries/Wire/utility/WireBase.h index 72facded6..764f76bbb 100644 --- a/STM32F1/libraries/Wire/utility/WireBase.h +++ b/STM32F1/libraries/Wire/utility/WireBase.h @@ -77,6 +77,12 @@ class WireBase { // Abstraction is awesome! // Allow derived classes to overwrite begin function virtual void begin(uint8 = 0x00); + /* + * Deinitialises the class interface + */ + // Allow derived classes to overwrite end function + virtual void end() {} + /* * Sets up the transmission message to be processed */ @@ -98,32 +104,34 @@ class WireBase { // Abstraction is awesome! * Request bytes from a slave device and process the request, * storing into the receiving buffer. */ - uint8 requestFrom(uint8, int); + uint8 requestFrom(uint8, int,bool stop=false); /* * Allow only 8 bit addresses to be used when requesting bytes */ - uint8 requestFrom(int, int); + uint8 requestFrom(int address, int numBytes, bool stop=true); + /* * Stack up bytes to be sent when transmitting */ - void write(uint8); + size_t write(uint8); /* * Stack up bytes from the array to be sent when transmitting */ - void write(uint8*, int); + size_t write(uint8*, int); + size_t write(const uint8* buf, int nr) { return write((uint8*)buf,nr); } /* * Ensure that a sending data will only be 8-bit bytes */ - void write(int); + size_t write(int); /* * Ensure that an array sending data will only be 8-bit bytes */ - void write(int*, int); + size_t write(int*, int); /* * Stack up bytes from a string to be sent when transmitting diff --git a/STM32F1/libraries/WireSlave/examples/SFRRanger_reader/SFRRanger_reader.ino b/STM32F1/libraries/WireSlave/examples/SFRRanger_reader/SFRRanger_reader.ino new file mode 100644 index 000000000..9409bb10e --- /dev/null +++ b/STM32F1/libraries/WireSlave/examples/SFRRanger_reader/SFRRanger_reader.ino @@ -0,0 +1,87 @@ +// I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder +// by Nicholas Zambetti +// and James Tichenor + +// Demonstrates use of the Wire library reading data from the +// Devantech Utrasonic Rangers SFR08 and SFR10 + +// Created 29 April 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) + Serial.begin(115200); // start serial communication at 9600bps +} + +int reading = 0; + +void loop() +{ + // step 1: instruct sensor to read echoes + Wire.beginTransmission(112); // transmit to device #112 (0x70) + // the address specified in the datasheet is 224 (0xE0) + // but i2c adressing uses the high 7 bits so it's 112 + Wire.write(byte(0x00)); // sets register pointer to the command register (0x00) + Wire.write(byte(0x50)); // command sensor to measure in "inches" (0x50) + // use 0x51 for centimeters + // use 0x52 for ping microseconds + Wire.endTransmission(); // stop transmitting + + // step 2: wait for readings to happen + delay(70); // datasheet suggests at least 65 milliseconds + + // step 3: instruct sensor to return a particular echo reading + Wire.beginTransmission(112); // transmit to device #112 + Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02) + Wire.endTransmission(); // stop transmitting + + // step 4: request reading from sensor + Wire.requestFrom(112, 2); // request 2 bytes from slave device #112 + + // step 5: receive reading from sensor + if(2 <= Wire.available()) // if two bytes were received + { + reading = Wire.read(); // receive high byte (overwrites previous reading) + reading = reading << 8; // shift high byte to be high 8 bits + reading |= Wire.read(); // receive low byte as lower 8 bits + Serial.println(reading); // print the reading + } + + delay(250); // wait a bit since people have to read the output :) +} + + +/* + +// The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08) +// usage: changeAddress(0x70, 0xE6); + +void changeAddress(byte oldAddress, byte newAddress) +{ + Wire.beginTransmission(oldAddress); + Wire.write(byte(0x00)); + Wire.write(byte(0xA0)); + Wire.endTransmission(); + + Wire.beginTransmission(oldAddress); + Wire.write(byte(0x00)); + Wire.write(byte(0xAA)); + Wire.endTransmission(); + + Wire.beginTransmission(oldAddress); + Wire.write(byte(0x00)); + Wire.write(byte(0xA5)); + Wire.endTransmission(); + + Wire.beginTransmission(oldAddress); + Wire.write(byte(0x00)); + Wire.write(newAddress); + Wire.endTransmission(); +} + +*/ diff --git a/STM32F1/libraries/WireSlave/examples/digital_potentiometer/digital_potentiometer.ino b/STM32F1/libraries/WireSlave/examples/digital_potentiometer/digital_potentiometer.ino new file mode 100644 index 000000000..8830ada12 --- /dev/null +++ b/STM32F1/libraries/WireSlave/examples/digital_potentiometer/digital_potentiometer.ino @@ -0,0 +1,38 @@ +// I2C Digital Potentiometer +// by Nicholas Zambetti +// and Shawn Bonkowski + +// Demonstrates use of the Wire library +// Controls AD5171 digital potentiometer via I2C/TWI + +// Created 31 March 2006 + +// This example code is in the public domain. + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) +} + +byte val = 0; + +void loop() +{ + Wire.beginTransmission(44); // transmit to device #44 (0x2c) + // device address is specified in datasheet + Wire.write(byte(0x00)); // sends instruction byte + Wire.write(val); // sends potentiometer value byte + Wire.endTransmission(); // stop transmitting + + val++; // increment value + if(val == 64) // if reached 64th position (max) + { + val = 0; // start over from lowest value + } + delay(500); +} diff --git a/STM32F1/libraries/WireSlave/examples/i2c_libmaple_slave_reader/i2c_libmaple_slave_reader.ino b/STM32F1/libraries/WireSlave/examples/i2c_libmaple_slave_reader/i2c_libmaple_slave_reader.ino new file mode 100644 index 000000000..d99cd2272 --- /dev/null +++ b/STM32F1/libraries/WireSlave/examples/i2c_libmaple_slave_reader/i2c_libmaple_slave_reader.ino @@ -0,0 +1,108 @@ +/* +* i2c_slave example.cpp +* +* You can use this sketch in combination with master_writer.pde +* +* Created on: 4 Sep 2012 +* Author: Barry Carter +* +* Updated 2019 by Donna Whisnant to reflect new WireSlave library updates +* +* Note: While this example shows how to call the core's low-level I2C +* functions directly, their API is less stable than the Arduino API +* and it's easier to get yourself into trouble with the many quirks +* and peculiarities of the ST I2C peripheral. Thus, it's recommended +* that you instead use the WireSlave TwoWire class and the predefined +* Wire and Wire1 objects, which are ilustrated in the other examples. +* +*/ +#include +#include + +i2c_msg txMsg = {}; +uint8 txBuffer[255]; + +i2c_msg rxMsg = {}; +uint8 rxBuffer[255]; + +volatile uint32_t lastMessageTime; + +void funcrx(i2c_msg *msg __attribute__((unused))){ + // This function is called when data is received: + // msg->addr will be our slave address being accessed + // msg->data will point to our receive buffer + // msg->xferred will be the length of the incoming message (number of bytes received) + // msg->length is the overall size of the buffer (as it was initialized) + + if (msg->xferred != 5) { + Serial.print("Bad data received:\r\n"); + } + Serial.print("length: "); + Serial.println(msg->xferred); + for (int i=0; ixferred; i++) { + // Print as char + Serial.print((char)msg->data[i]); + Serial.print(' '); + // Print as byte + Serial.println(msg->data[i], 16); + } + + lastMessageTime = millis(); +} + +void functx(i2c_msg *msg){ + // + // We will get this callback for each outgoing packet. Fill in the msg buffer + // with the data to transmit and set the length to the size of the message. + // + msg->data[0] = 0x31; + msg->data[1] = 0x32; + msg->data[2] = 0x33; + msg->data[3] = 0x34; + msg->data[4] = 0x35; + msg->length = 5; +} + +void setup() { + Serial.begin(115200); + Serial.println("libmaple I2C slave reader example"); + + // Init the message structures + // and attach the buffers: + txMsg.data = txBuffer; // The functx callback will be called with this structure with 'data' pointing to our buffer + txMsg.length = 0; // No initial transmit message length + + rxMsg.data = rxBuffer; + rxMsg.length = sizeof(rxBuffer); // The rxMsg buffer should reflect the size of the buffer available to receive + + /* Init slave mode. Enables master too + * + * We are going to configure the slave device to + * - enable fast I2C (400khz) + * - dual addresses (can have 2 addresses per module) + * general call (accepts data writes to 0x00 on a broadcast basis) + * + */ + i2c_slave_enable(I2C1, I2C_FAST_MODE | I2C_SLAVE_DUAL_ADDRESS | I2C_SLAVE_GENERAL_CALL, 400000); + + // attach receive handler + i2c_slave_attach_recv_handler(I2C1, &rxMsg, funcrx); + // attach transmit handler + i2c_slave_attach_transmit_handler(I2C1, &txMsg, functx); + + // set address #1 to 4 + i2c_slave_set_own_address(I2C1, 4); + + // set address #2 to 5 + i2c_slave_set_own_address2(I2C1, 5); + + // Start clock + lastMessageTime = millis(); +} + +void loop() { + if((millis() - lastMessageTime) > 3000){ + Serial.println("Nothing received in 3 seconds."); + lastMessageTime = millis(); + } +} diff --git a/STM32F1/libraries/WireSlave/examples/i2c_scanner_wire/i2c_scanner_wire.ino b/STM32F1/libraries/WireSlave/examples/i2c_scanner_wire/i2c_scanner_wire.ino new file mode 100644 index 000000000..44af4dc1d --- /dev/null +++ b/STM32F1/libraries/WireSlave/examples/i2c_scanner_wire/i2c_scanner_wire.ino @@ -0,0 +1,78 @@ +// -------------------------------------- +// i2c_scanner +// +// Version 1 +// This program (or code that looks like it) +// can be found in many places. +// For example on the Arduino.cc forum. +// The original author is not know. +// Version 2, Juni 2012, Using Arduino 1.0.1 +// Adapted to be as simple as possible by Arduino.cc user Krodal +// Version 3, Feb 26 2013 +// V3 by louarnold +// Version 4, March 3, 2013, Using Arduino 1.0.3 +// by Arduino.cc user Krodal. +// Changes by louarnold removed. +// Scanning addresses changed from 0...127 to 1...119, +// according to the i2c scanner by Nick Gammon +// http://www.gammon.com.au/forum/?id=10896 +// Version 5, March 28, 2013 +// As version 4, but address scans now to 127. +// A sensor seems to use address 120. +// +// This sketch tests the standard 7-bit addresses +// Devices with higher bit address might not be seen properly. +// + +#include + +//use IIC2 +//TwoWire WIRE2 (2,I2C_FAST_MODE); +//#define Wire WIRE2 + + +void setup() { + + Serial.begin(115200); + Wire.begin(); + Serial.println("\nI2C Scanner"); +} + + +void loop() { + byte error, address; + int nDevices; + + Serial.println("Scanning..."); + + nDevices = 0; + for(address = 1; address < 127; address++) { + // The i2c_scanner uses the return value of + // the Write.endTransmisstion to see if + // a device did acknowledge to the address. + + Wire.beginTransmission(address); + error = Wire.endTransmission(); + + if (error == 0) { + Serial.print("I2C device found at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.println(address, HEX); + + nDevices++; + } + else if (error == 4) { + Serial.print("Unknown error at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.println(address, HEX); + } + } + if (nDevices == 0) + Serial.println("No I2C devices found"); + else + Serial.println("done"); + + delay(5000); // wait 5 seconds for next scan +} diff --git a/STM32F1/libraries/WireSlave/examples/master_reader/master_reader.ino b/STM32F1/libraries/WireSlave/examples/master_reader/master_reader.ino new file mode 100644 index 000000000..bd914e368 --- /dev/null +++ b/STM32F1/libraries/WireSlave/examples/master_reader/master_reader.ino @@ -0,0 +1,32 @@ +// Wire Master Reader +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Reads data from an I2C/TWI slave device +// Refer to the "Wire Slave Sender" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) + Serial.begin(115200); // start serial for output +} + +void loop() +{ + Wire.requestFrom(8, 6); // request 6 bytes from slave device #8 + + while(Wire.available()) // slave may send less than requested + { + char c = Wire.read(); // receive a byte as character + Serial.print(c); // print the character + } + + delay(500); +} diff --git a/STM32F1/libraries/WireSlave/examples/master_writer/master_writer.ino b/STM32F1/libraries/WireSlave/examples/master_writer/master_writer.ino new file mode 100644 index 000000000..f997473a7 --- /dev/null +++ b/STM32F1/libraries/WireSlave/examples/master_writer/master_writer.ino @@ -0,0 +1,31 @@ +// Wire Master Writer +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Writes data to an I2C/TWI slave device +// Refer to the "Wire Slave Receiver" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) +} + +byte x = 0; + +void loop() +{ + Wire.beginTransmission(4); // transmit to device #4 + Wire.write("x is "); // sends five bytes + Wire.write(x); // sends one byte + Wire.endTransmission(); // stop transmitting + + x++; + delay(500); +} diff --git a/STM32F1/libraries/WireSlave/examples/selftest1/code.cpp b/STM32F1/libraries/WireSlave/examples/selftest1/code.cpp new file mode 100644 index 000000000..d2bce8c61 --- /dev/null +++ b/STM32F1/libraries/WireSlave/examples/selftest1/code.cpp @@ -0,0 +1,68 @@ +// Wire Slave Receiver +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Receives data as an I2C/TWI slave device +// Refer to the "Wire Master Writer" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + +#include +//#define Serial Serial1 + +#define MasterWire Wire +#define SlaveWire Wire1 +#define ENABLE_SLAVE +#define ENABLE_MASTER + +void receiveEvent(int howMany); + +void setup(){ + Serial.begin(115200); // start serial for output + + #ifdef ENABLE_MASTER + MasterWire.begin(); // join i2c bus #1 as master + Serial.println("Done with MasterWire.begin "); + #endif + + #ifdef ENABLE_SLAVE + SlaveWire.begin(4); // join i2c bus #2 as slave with address #4 + Serial.println("Done with SlaveWire.begin "); + #endif + + #ifdef ENABLE_SLAVE + SlaveWire.onReceive(receiveEvent); // register event + #endif +} + +void loop(){ + #ifdef ENABLE_MASTER + static byte x = 0; + Serial.print("Master writing "); + Serial.println(x); + + MasterWire.beginTransmission(4); // transmit to device #4 + MasterWire.write("x is "); // sends five bytes + MasterWire.write(x); // sends one byte + MasterWire.endTransmission(); // stop transmitting + + x++; + #endif + delay(500); +} + +// function that executes whenever data is received from master +// this function is registered as an event, see setup() +// Note that it is not advicable to call Serial.print() from within an ISR +void receiveEvent(int howMany){ + //Serial.print("Slave receving "); + while(1 < SlaveWire.available()){ // loop through all but the last + char c = SlaveWire.read(); // receive byte as a character + Serial.print(c); // print the character + } + int x = SlaveWire.read(); // receive byte as an integer + Serial.println(x); // print the integer +} + diff --git a/STM32F1/libraries/WireSlave/examples/selftest1/selftest1.ino b/STM32F1/libraries/WireSlave/examples/selftest1/selftest1.ino new file mode 100644 index 000000000..58f1e5c2c --- /dev/null +++ b/STM32F1/libraries/WireSlave/examples/selftest1/selftest1.ino @@ -0,0 +1,16 @@ +// Wire Slave Receiver +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Receives data as an I2C/TWI slave device +// Refer to the "Wire Master Writer" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + +// The code is temporarily moved to the code.cpp. +// This makes it possible to set breakpoints in eclipse IDE. +// I'm sure that there is an Eclipse configuration that makes it +// possible for it to detect .ino files as .cpp, but I'm lazy + diff --git a/STM32F1/libraries/WireSlave/examples/slave_receiver/slave_receiver.ino b/STM32F1/libraries/WireSlave/examples/slave_receiver/slave_receiver.ino new file mode 100644 index 000000000..bf9f255f8 --- /dev/null +++ b/STM32F1/libraries/WireSlave/examples/slave_receiver/slave_receiver.ino @@ -0,0 +1,36 @@ +// Wire Slave Receiver +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Receives data as an I2C/TWI slave device +// Refer to the "Wire Master Writer" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup(){ + Serial.begin(115200); // start serial for output + + Wire.begin(4); // join i2c bus with address #4 + Wire.onReceive(receiveEvent); // register event +} + +void loop(){ + delay(100); +} + +// function that executes whenever data is received from master +// this function is registered as an event, see setup() +// Note that it is not advicable to call Serial.print() from within an ISR +void receiveEvent(int howMany){ + while(1 < Wire.available()){ // loop through all but the last + char c = Wire.read(); // receive byte as a character + Serial.print(c); // print the character + } + int x = Wire.read(); // receive byte as an integer + Serial.println(x); // print the integer +} diff --git a/STM32F1/libraries/WireSlave/examples/slave_sender/slave_sender.ino b/STM32F1/libraries/WireSlave/examples/slave_sender/slave_sender.ino new file mode 100644 index 000000000..75add4a00 --- /dev/null +++ b/STM32F1/libraries/WireSlave/examples/slave_sender/slave_sender.ino @@ -0,0 +1,32 @@ +// Wire Slave Sender +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Sends data as an I2C/TWI slave device +// Refer to the "Wire Master Reader" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(8); // join i2c bus with address #8 + Wire.onRequest(requestEvent); // register event +} + +void loop() +{ + delay(100); +} + +// function that executes whenever data is requested by master +// this function is registered as an event, see setup() +void requestEvent() +{ + Wire.write("hello "); // respond with message of 6 bytes + // as expected by master +} diff --git a/STM32F1/libraries/WireSlave/keywords.txt b/STM32F1/libraries/WireSlave/keywords.txt new file mode 100644 index 000000000..47ffd52d0 --- /dev/null +++ b/STM32F1/libraries/WireSlave/keywords.txt @@ -0,0 +1,31 @@ +####################################### +# Syntax Coloring Map For Wire +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +setClock KEYWORD2 +beginTransmission KEYWORD2 +endTransmission KEYWORD2 +requestFrom KEYWORD2 +onReceive KEYWORD2 +onRequest KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +Wire KEYWORD2 +Wire1 KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/STM32F1/libraries/WireSlave/library.properties b/STM32F1/libraries/WireSlave/library.properties new file mode 100644 index 000000000..4a491609c --- /dev/null +++ b/STM32F1/libraries/WireSlave/library.properties @@ -0,0 +1,11 @@ +name=Wire_Slave +version=1.0 +author=Roger Clark,Nicholas Zambetti,Todd Krein,Perry Hung,Barry Carter,Donna Whisnant +email= +sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. +paragraph=Allows the communication between devices or sensors connected via Two Wire (I2C) Interface Bus. Includes both Master and Slave drivers for both Hardware I2C ports of STM32F1 micros. +url=http://www.arduino.cc/en/Reference/Wire +architectures=STM32F1 +maintainer= +category=Communication +include=src/Wire_slave.h diff --git a/STM32F1/libraries/WireSlave/src/Wire.h b/STM32F1/libraries/WireSlave/src/Wire.h new file mode 100644 index 000000000..0a47d0322 --- /dev/null +++ b/STM32F1/libraries/WireSlave/src/Wire.h @@ -0,0 +1,4 @@ +#pragma once +#include "Wire_slave.h" + +//#error "Something is trying to include Wire.h when Wire_slave.h is already included, they are mutually exclusive" diff --git a/STM32F1/libraries/WireSlave/src/Wire_slave.cpp b/STM32F1/libraries/WireSlave/src/Wire_slave.cpp new file mode 100644 index 000000000..bf3ce3f31 --- /dev/null +++ b/STM32F1/libraries/WireSlave/src/Wire_slave.cpp @@ -0,0 +1,522 @@ +/* + TwoWire.cpp - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts + + Modified 2019 by Donna Whisnant to merge WireSlave changes with the core to + make slave mode work and without having conflicting data type defintions and + to improve the WireSlave functionality, completing some of the missing pieces. + + */ + +#include +#include +#include + +#include "Wire_slave.h" +#include +#include + +static constexpr uint16_t MASTER_ADDRESS = 0x01; // Use 0x01 since it's an invalid device address. 0x00 = General Call, but 0x01 is reserved for Start Byte + +// Constructors //////////////////////////////////////////////////////////////// + +TwoWire::TwoWire(i2c_dev* i2cDevice, uint32_t flags, uint32_t frequencyHz) + : sel_hard(i2cDevice), + rxBuffer(nullptr), + rxBufferAllocated(0), + rxBufferIndex(0), + rxBufferLength(0), + txBuffer(nullptr), + txBufferAllocated(0), + txBufferIndex(0), + txBufferLength(0), + transmitting(false), + haveReset(false), + useGeneralCall((flags & I2C_SLAVE_GENERAL_CALL) ? true : false), + dev_flags(flags), + itc_msg({}), + itc_slave_msg({}), + frequency((flags & I2C_FAST_MODE) ? 400000 : frequencyHz), + user_onRequest(nullptr), + user_onReceive(nullptr) +{ +} + +// Public Methods ////////////////////////////////////////////////////////////// + +void TwoWire::begin(void) +{ + begin(MASTER_ADDRESS, MASTER_ADDRESS); +} + +void TwoWire::begin(uint16_t address) +{ + begin(address, MASTER_ADDRESS); +} + +void TwoWire::begin(uint16_t myAddress1, uint16_t myAddress2) +{ + rxBufferIndex = 0; + rxBufferLength = 0; + allocateRxBuffer(BUFFER_LENGTH); + + txBufferIndex = 0; + txBufferLength = 0; + allocateTxBuffer(BUFFER_LENGTH); + + transmitting = false; + + // Note: Leave speed set as configured in dev_flags + // in case user calls setClock() before begin(). + if (myAddress1 == MASTER_ADDRESS) { + dev_flags &= (I2C_FAST_MODE | I2C_DUTY_16_9); // Note: Clear I2C_SLAVE_MODE flag + i2c_master_enable(sel_hard, dev_flags | (!haveReset ? I2C_PUP_RESET : 0), frequency); + } else { + dev_flags &= (I2C_FAST_MODE | I2C_DUTY_16_9); + dev_flags |= I2C_SLAVE_MODE; + if (myAddress2 != MASTER_ADDRESS) dev_flags |= I2C_SLAVE_DUAL_ADDRESS; + if (useGeneralCall) dev_flags |= I2C_SLAVE_GENERAL_CALL; + + itc_slave_msg.addr = myAddress1; + itc_slave_msg.flags = 0; + itc_slave_msg.data = slaveRxBuffer; + itc_slave_msg.length = sizeof(slaveRxBuffer); // length will be the size of the receive buffer that the IRQ routine can use + itc_slave_msg.xferred = 0; + + itc_msg.addr = 0; + itc_msg.flags = 0; + itc_msg.data = txBuffer; + itc_msg.length = 0; + itc_msg.xferred = 0; + + if (sel_hard->regs == I2C1_BASE) { + // attach receive handler + i2c_slave_attach_recv_handler(sel_hard, &itc_slave_msg, onReceiveService1); + // attach transmit handler + i2c_slave_attach_transmit_handler(sel_hard, &itc_msg, onRequestService1); + } + #if WIRE_INTERFACES_COUNT > 1 + else if (sel_hard->regs == I2C2_BASE) { + // attach receive handler + i2c_slave_attach_recv_handler(sel_hard, &itc_slave_msg, onReceiveService2); + // attach transmit handler + i2c_slave_attach_transmit_handler(sel_hard, &itc_msg, onRequestService2); + } + #endif + + i2c_slave_enable(sel_hard, dev_flags | (!haveReset ? I2C_PUP_RESET : 0), frequency); // Must enable first so that RCC, etc, get configured + + // TODO : Add support for 10-bit addresses + i2c_slave_set_own_address(sel_hard, myAddress1); + if (dev_flags & I2C_SLAVE_DUAL_ADDRESS) { + i2c_slave_set_own_address2(sel_hard, myAddress2); + } + } + + haveReset = true; +} + +void TwoWire::end(void) +{ + flush(); // Make sure all transmissions are complete + i2c_disable(sel_hard); // Disable peripheral + i2c_master_release_bus(sel_hard); // Release pins and switch the port pins from AF back to GPIO + free(txBuffer); + txBuffer = nullptr; + txBufferAllocated = 0; + free(rxBuffer); + rxBuffer = nullptr; + rxBufferAllocated = 0; +} + +void TwoWire::setClock(uint32_t frequencyHz) +{ + switch (frequencyHz) { + case 400000: + dev_flags |= I2C_FAST_MODE; // set FAST_MODE bit + break; + case 100000: + default: + dev_flags &= ~I2C_FAST_MODE; // clear FAST_MODE bit + break; + } + frequency = frequencyHz; + if (sel_hard->regs->CR1 & I2C_CR1_PE) { + i2c_master_enable(sel_hard, dev_flags, frequency); + } +} + +uint8 TwoWire::process(bool stop) +{ + if (!stop) itc_msg.flags |= I2C_MSG_NOSTOP; + int8 res = i2c_master_xfer(sel_hard, &itc_msg, 1, getTimeout()); + itc_msg.flags &= ~I2C_MSG_NOSTOP; + + if (res == I2C_ERROR_PROTOCOL) { + if (sel_hard->error_flags & I2C_SR1_AF) { /* NACK */ + res = (sel_hard->error_flags & I2C_SR1_ADDR ? ENACKADDR : ENACKTRNS); + } else if (sel_hard->error_flags & I2C_SR1_OVR) { /* Over/Underrun */ + res = EDATA; + } else { /* Bus or Arbitration error */ + res = EOTHER; + } + } else if (res == I2C_ERROR_TIMEOUT) { + res = EOTHER; // Arduino API spec doesn't have a special error for timeout so use EOTHER + } else if (res != 0) { + res = EOTHER; + } + + if (sel_hard->state == I2C_STATE_ERROR) { + // All errors should reset the bus: + i2c_master_enable(sel_hard, (I2C_BUS_RESET | dev_flags), frequency); // This will transition the state back to IDLE + } + + return res; +} + +//TODO: Add the ability to queue messages (adding a boolean to end of function +// call, allows for the Arduino style to stay while also giving the flexibility +// to bulk send +uint8 TwoWire::requestFrom(uint16_t address, uint8_t num_bytes, uint32_t iaddress, uint8_t isize, bool sendStop) +{ + if (!isMaster()) return 0; + + allocateRxBuffer(num_bytes); + // error if no memory block available to allocate the buffer + if (rxBuffer == nullptr) { + return 0; // This function returns number of bytes returned from slave (so can't return an error code value!) + } + + // reset rx buffer iterator vars + rxBufferIndex = 0; + rxBufferLength = 0; + + itc_msg.addr = address; + itc_msg.flags = I2C_MSG_READ; + itc_msg.length = num_bytes; + itc_msg.data = rxBuffer; + if (process(sendStop) != 0) { + itc_msg.flags = 0; // Clear message flags because we are no longer reading + return 0; // Failure means we received no data back + } + + // TODO handle iaddress & isize + rxBufferLength += itc_msg.xferred; + itc_msg.flags = 0; + + return itc_msg.xferred; +} + +uint8_t TwoWire::requestFrom(uint16_t address, uint8_t quantity, bool sendStop) +{ + return requestFrom(address, quantity, (uint32_t) 0, (uint8_t) 0, sendStop); +} + +uint8_t TwoWire::requestFrom(uint16_t address, uint8_t quantity) +{ + return requestFrom(address, quantity, (uint32_t) 0, (uint8_t) 0, true); +} + +void TwoWire::beginTransmission(uint16_t address) +{ + if (isMaster()) { + // indicate that we are transmitting + transmitting = true; + + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; + + itc_msg.addr = address; + itc_msg.data = txBuffer; + itc_msg.length = 0; + itc_msg.flags = 0; + } +} + +// +// Originally, 'endTransmission' was an f(void) function. +// It has been modified to take one parameter indicating +// whether or not a STOP should be performed on the bus. +// Calling endTransmission(false) allows a sketch to +// perform a repeated start. +// +// WARNING: Nothing in the library keeps track of whether +// the bus tenure has been properly ended with a STOP. It +// is very possible to leave the bus in a hung state if +// no call to endTransmission(true) is made. Some I2C +// devices will behave oddly if they do not see a STOP. +// +uint8_t TwoWire::endTransmission(bool sendStop) +{ + uint8_t ret = EOTHER; + + if (isMaster() && transmitting) { + itc_msg.data = txBuffer; + itc_msg.length = txBufferLength; + itc_msg.flags = 0; + ret = process(sendStop); + + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; + + // indicate that we are done transmitting + transmitting = false; + } + + return ret; +} + + +// must be called in: +// slave tx event callback +// or after beginTransmission(address) +size_t TwoWire::write(uint8_t data) +{ + if (!transmitting && isMaster()) { + return 0; + } else { + // in master transmitter mode or slave tx event callback + allocateTxBuffer(txBufferLength + 1); + // error if no memory block available to allocate the buffer + if (txBuffer == nullptr) { + setWriteError(); + return 0; + } + // put byte in tx buffer + txBuffer[txBufferIndex] = data; + ++txBufferIndex; + // update amount in buffer + txBufferLength = txBufferIndex; + } + return 1; +} + +/** + * @brief This function must be called in slave Tx event callback or after + * beginTransmission() and before endTransmission(). + * @param pdata: pointer to the buffer data + * @param quantity: number of bytes to write + * @retval number of bytes ready to write. + */ +size_t TwoWire::write(const void *data, uint32_t quantity) +{ + if (!transmitting && isMaster()) { + return 0; + } else { + // in master transmitter mode or slave Tx event callback + allocateTxBuffer(txBufferLength + quantity); + // error if no memory block available to allocate the buffer + if (txBuffer == nullptr) { + setWriteError(); + return 0; + } + // put bytes in tx buffer + memcpy(&txBuffer[txBufferIndex], data, quantity); + txBufferIndex = txBufferIndex + quantity; + // update amount in buffer + txBufferLength = txBufferIndex; + return quantity; + } +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::available(void) +{ + return rxBufferLength - rxBufferIndex; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::read(void) +{ + int value = -1; + + // get each successive byte on each call + if (rxBufferIndex < rxBufferLength) { + value = rxBuffer[rxBufferIndex++]; + } + + return value; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::peek(void) +{ + int value = -1; + + if (rxBufferIndex < rxBufferLength) { + value = rxBuffer[rxBufferIndex]; + } + + return value; +} + +void TwoWire::flush(void) +{ + if (sel_hard->state != I2C_STATE_DISABLED) { // Can't flush if we are disabled + if (!isMaster()) { + if (sel_hard->state == I2C_STATE_BUSY) { // It should already be in the busy state, but check in case there was an error and no timeout + // If this is a slave, let flush make sure + // any pending onRequestService has completed + // so we can turn around and reconfigure as a + // master for multi-master bus transmission: + wait_for_state_change(sel_hard, I2C_STATE_IDLE, getTimeout()); + } + + // Since this function has no return value and is + // an override of the underlying flush() function, + // then force-change our state to idle to cover + // error and timeout conditions: + sel_hard->state = I2C_STATE_IDLE; + } else { + // If this is a master, finish any transmission + // that hasn't been ended: + endTransmission(true); + } + } +} + +// behind the scenes function that is called when data is received +void __attribute__((always_inline)) TwoWire::onReceiveService(i2c_msg* msg) +{ + // don't bother if user hasn't registered a callback + if (!user_onReceive) { + return; + } + + // copy twi rx buffer into local read buffer, enabling new + // reads to happen in parallel + allocateRxBuffer(msg->xferred); + rxBufferIndex = 0; + if (rxBuffer != nullptr) { + memcpy(rxBuffer, msg->data, msg->xferred); + rxBufferLength = msg->xferred; + // alert user program + user_onReceive(msg->xferred); + } else { + rxBufferLength = 0; + user_onReceive(0); // Alert the user program that we received something, but couldn't transfer the data + } +} + +// behind the scenes function that is called when data is requested +void __attribute__((always_inline)) TwoWire::onRequestService(i2c_msg* msg) +{ + // don't bother if user hasn't registered a callback + if (!user_onRequest) return; + + // reset tx buffer iterator vars for slave data write + // !!! this will kill any pending pre-master sendTo() activity + txBufferIndex = 0; + txBufferLength = 0; + // alert user program + user_onRequest(); + + // update i2c_msg + msg->data = txBuffer; // This assignment is necessary as the writes in user function may change the pointer + msg->length = txBufferLength; + + // Note: Caller can't do Master transmission in multi-master until Slave + // transmission is complete! (they should call flush() before switching to master!) +} + +// sets function called on slave write +void TwoWire::onReceive(void (*function)(int)) +{ + user_onReceive = function; +} + +// sets function called on slave read +void TwoWire::onRequest(void (*function)(void)) +{ + user_onRequest = function; +} + +/** + * @brief Allocate the Rx/Tx buffer to the requested length if needed + * @note Minimum allocated size is BUFFER_LENGTH) + * @param length: number of bytes to allocate + */ +inline void TwoWire::allocateRxBuffer(size_t length) +{ + // By default we allocate BUFFER_LENGTH bytes. It is the min size of the buffer. + if (length < BUFFER_LENGTH) length = BUFFER_LENGTH; + // Allocate in increments of BUFFER_LENGTH so we don't fragment the heap: + if ((length % BUFFER_LENGTH) != 0) length += (BUFFER_LENGTH - (length % BUFFER_LENGTH)); + if (rxBufferAllocated < length) { + rxBuffer = (uint8_t *) realloc(rxBuffer, length * sizeof(uint8_t)); + rxBufferAllocated = (rxBuffer != nullptr) ? length : 0; + } +} + +inline void TwoWire::allocateTxBuffer(size_t length) +{ + // By default we allocate BUFFER_LENGTH bytes. It is the min size of the buffer. + if (length < BUFFER_LENGTH) length = BUFFER_LENGTH; + // Allocate in increments of BUFFER_LENGTH so we don't fragment the heap: + if ((length % BUFFER_LENGTH) != 0) length += (BUFFER_LENGTH - (length % BUFFER_LENGTH)); + if (txBufferAllocated < length) { + txBuffer = (uint8_t *) realloc(txBuffer, length * sizeof(uint8_t)); + txBufferAllocated = (txBuffer != nullptr) ? length : 0; + } +} + + +// Preinstantiate Objects ////////////////////////////////////////////////////// + +TwoWire TwoWire::g_Wire(I2C1); +#if WIRE_INTERFACES_COUNT > 1 +TwoWire TwoWire::g_Wire1(I2C2); +#endif + +TwoWire& Wire = TwoWire::getInstance(); +#if WIRE_INTERFACES_COUNT > 1 +TwoWire& Wire1 = TwoWire::getInstance1(); +#endif + + +// onRequestServiceX and onReceiveServiceX can't be inline since they +// are exclusively called via a function pointer +void TwoWire::onRequestService1(i2c_msg* msg) +{ + Wire.onRequestService(msg); +} + +void TwoWire::onReceiveService1(i2c_msg* msg) +{ + Wire.onReceiveService(msg); +} + +#if WIRE_INTERFACES_COUNT > 1 +void TwoWire::onRequestService2(i2c_msg* msg) +{ + Wire1.onRequestService(msg); +} +void TwoWire::onReceiveService2(i2c_msg* msg) +{ + Wire1.onReceiveService(msg); +} +#endif diff --git a/STM32F1/libraries/WireSlave/src/Wire_slave.h b/STM32F1/libraries/WireSlave/src/Wire_slave.h new file mode 100644 index 000000000..31feefd2f --- /dev/null +++ b/STM32F1/libraries/WireSlave/src/Wire_slave.h @@ -0,0 +1,183 @@ +/* + TwoWire.h - TWI/I2C library for Arduino & Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts + + Modified 2019 by Donna Whisnant to merge WireSlave changes with the core to + make slave mode work and without having conflicting data type defintions and + to improve the WireSlave functionality, completing some of the missing pieces. + + */ + +#ifndef TwoWire_h +#define TwoWire_h + +#include +#include +#include +#include + + +// WIRE_HAS_END means Wire has end() +#ifndef WIRE_HAS_END +#define WIRE_HAS_END 1 +#endif + +#ifndef WIRE_INTERFACES_COUNT +#define WIRE_INTERFACES_COUNT 2 +#endif + +/* return codes from endTransmission() */ +typedef enum EndTranmissionCodes { + SUCCESS = 0, /* transmission was successful */ + EDATA = 1, /* too much data */ + ENACKADDR = 2, /* received nack on transmit of address */ + ENACKTRNS = 3, /* received nack on transmit of data */ + EOTHER = 4, /* other error */ +} EndTranmissionCodes; + +class TwoWire: public Stream +{ +private: + i2c_dev* sel_hard; // Pointer to the I2C device for this interface + + uint8_t *rxBuffer; // Receive Buffer -- lazily allocated + size_t rxBufferAllocated; // Receive Buffer bytes allocated + size_t rxBufferIndex; // Receive Buffer index for next byte to read + size_t rxBufferLength; // Receive Buffer bytes stored within the space allocated + + uint8_t *txBuffer; // Transmit Buffer -- lazily allocated + size_t txBufferAllocated; // Transmit Buffer bytes allocated + size_t txBufferIndex; // Transmit Buffer index of next byte to write (will always equal txBufferLength since we aren't doing random access, kept in case random access is added) + size_t txBufferLength; // Transmit Buffer bytes stored within the space allocated + + bool transmitting; // Flag indicating a transmitting master (doesn't track slave transmissions) + bool haveReset; // Flag indicating initial power-on I2C reset status + bool useGeneralCall; // Flag indicating if I2C General Call slave address will be processed by slave + + uint32_t dev_flags; // Flags used for enabling master or slave + i2c_msg itc_msg; // Master Tx/Rx Message and Slave Tx Message + i2c_msg itc_slave_msg; // Slave Rx Message (since it's completely asynchronous) + + uint32_t frequency; // Frequency to use for I2C Master (defaults to 100000) + + void (*user_onRequest)(void); + void (*user_onReceive)(int quantity); + +protected: + bool isMaster() const { return ((dev_flags & I2C_SLAVE_MODE) == 0); } + void allocateRxBuffer(size_t length); + void allocateTxBuffer(size_t length); + + uint8 process(bool stop = true); // wrapper for i2c_master_xfer + + inline void __attribute__((always_inline)) onReceiveService(i2c_msg* msg); + inline void __attribute__((always_inline)) onRequestService(i2c_msg* msg); + + static void onRequestService1(i2c_msg*); + static void onReceiveService1(i2c_msg*); +#if WIRE_INTERFACES_COUNT > 1 + static void onRequestService2(i2c_msg*); + static void onReceiveService2(i2c_msg*); +#endif + + TwoWire(i2c_dev* i2cDevice, uint32_t flags = I2C_SLAVE_GENERAL_CALL, uint32_t frequencyHz = 100000); + TwoWire() = delete; + TwoWire(const TwoWire&) = delete; + TwoWire& operator=(const TwoWire&) = delete; + TwoWire(TwoWire&&) = delete; + TwoWire& operator=(TwoWire&&) = delete; + + static TwoWire g_Wire; + #if WIRE_INTERFACES_COUNT > 1 + static TwoWire g_Wire1; + #endif + +public: + // return the 'Wire' instance (using I2C1) + static inline TwoWire& getInstance() + { + return g_Wire; + } + +#if WIRE_INTERFACES_COUNT > 1 + // return the 'Wire1' instance (using I2C2) + static inline TwoWire& getInstance1() + { + return g_Wire1; + } +#endif + + void begin(); // Master mode + void begin(uint16_t myAddress); // Single-Adddress Slave mode + void begin(uint16_t myAddress1, uint16_t myAddress2); // Dual-Address Slave mode + void end(); // End either Master or Slave + void setClock(uint32_t frequencyHz); // Set Master clock speed + uint32_t getClock() const { return frequency; } // Get Master clock speed + void beginTransmission(uint16_t slaveAddress); // Master transmission start + uint8_t endTransmission(bool sendStop = true); // Master transmission end + + uint8_t requestFrom(uint16_t slaveAddress, uint8_t quantity); // Master Request From Slave + uint8_t requestFrom(uint16_t slaveAddress, uint8_t quantity, bool sendStop); // Master Request From Slave + uint8_t requestFrom(uint16_t slaveAddress, uint8_t num_bytes, uint32_t iaddress, uint8_t isize, bool sendStop); // Master Request From Slave + + virtual size_t write(uint8_t data) override; // Write functions for either Master transmission or Slave onRequest handler + virtual size_t write(const void *data, uint32_t quantity) override; // Note: this is the signature of the base Print::write function + + virtual int available(void) override; // Bytes available in the receive buffer from either Master Request From or Slave onReceive handler + virtual int read(void) override; // Read byte from receive buffer from either Master Request From or Slave onReceive handler + virtual int peek(void) override; // Peek at next byte in receive buffer from either Master Request From or Slave onReceive handler + virtual void flush(void) override; // Finish the last transmission and wait for I2C to go idle. Used to switch Master->Slave or Slave->Master modes + void onReceive(void (*)(int quantity)); // Set Slave Receive Handler function + void onRequest(void (*)(void)); // Set Slave Request Handler function + + // recvSlaveAddress : Can be called from the user-defined onReceive handler + // function to provide the slave address that the message was sent to. + // This will be either the primary or secondary address used in the call + // to begin() or will be '0' if it was a General Call (broadcast) message. + uint16_t recvSlaveAddress() const { return itc_slave_msg.addr; } + + // setGeneralCall : Set whether or not the I2C General Call Slave address (00) + // will be processed. Call this BEFORE calling begin() to activate a slave. + // If begin() was already called, call end(), change the state, and call + // begin() again, otherwise the state will not change. + // The default for this option is 'true'. + void setGeneralCall(bool bEnable) + { + if (sel_hard->state == I2C_STATE_DISABLED) useGeneralCall = bEnable; // Only allow change when disabled + } + + // generalCall : Returns whether or not General Call Slave address (00) + // has been (or will be) enabled on the port configured as a slave. + bool getGeneralCall() const { return useGeneralCall; } + + using Print::write; + + // Minimum I2C Buffer Length: + static constexpr size_t BUFFER_LENGTH = 36; // Use 36 instead of 32 for minimum size so we can transfer 32 bytes of data in addition to addresses for EEPROM, etc. + +private: + uint8_t slaveRxBuffer[BUFFER_LENGTH]; // Fixed length slave IRQ receive buffer +}; + +extern TwoWire& Wire; +#if WIRE_INTERFACES_COUNT > 1 +extern TwoWire& Wire1; +#endif + +#endif // TwoWire_h diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/rcc.h b/STM32F1/libraries/rcc.h similarity index 64% rename from STM32F3/cores/maple/libmaple/stm32f3/include/series/rcc.h rename to STM32F1/libraries/rcc.h index 80577e963..aa9f8d3c9 100644 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/rcc.h +++ b/STM32F1/libraries/rcc.h @@ -3,7 +3,6 @@ * * Copyright (c) 2010 Perry Hung. * Copyright (c) 2011 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -27,25 +26,25 @@ *****************************************************************************/ /** - * @file libmaple/stm32f3/include/series/rcc.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 reset and clock control (RCC) support. + * @file libmaple/stm32f1/include/series/rcc.h + * @brief STM32F1 reset and clock control (RCC) support. */ -#ifndef _LIBMAPLE_STM32F3_RCC_H_ -#define _LIBMAPLE_STM32F3_RCC_H_ +#ifndef _LIBMAPLE_STM32F1_RCC_H_ +#define _LIBMAPLE_STM32F1_RCC_H_ #ifdef __cplusplus extern "C"{ #endif #include +#include /* * Register map */ -/** STM32F3 RCC register map type */ +/** STM32F1 RCC register map type */ typedef struct rcc_reg_map { __io uint32 CR; /**< Clock control register */ __io uint32 CFGR; /**< Clock configuration register */ @@ -57,9 +56,6 @@ typedef struct rcc_reg_map { __io uint32 APB1ENR; /**< APB1 peripheral clock enable register */ __io uint32 BDCR; /**< Backup domain control register */ __io uint32 CSR; /**< Control/status register */ - __io uint32 AHBRSTR; /**< AHB peripheral reset register */ - __io uint32 CFGR2; /**< Control/status register 2 */ - __io uint32 CFGR3; /**< Control/status register 3 */ } rcc_reg_map; #define RCC_BASE ((struct rcc_reg_map*)0x40021000) @@ -92,24 +88,19 @@ typedef struct rcc_reg_map { /* Clock configuration register */ -#define RCC_CFGR_I2SSRC_BIT 23 #define RCC_CFGR_USBPRE_BIT 22 -#define RCC_CFGR_PLLMUL_BIT 18 #define RCC_CFGR_PLLXTPRE_BIT 17 #define RCC_CFGR_PLLSRC_BIT 16 -#define RCC_CFGR_PPRE2_BIT 11 -#define RCC_CFGR_PPRE1_BIT 8 -#define RCC_CFGR_HPRE_BIT 4 #define RCC_CFGR_MCO (0x3 << 24) -#define RCC_CFGR_I2SSRC (1U << RCC_CFGR_I2CSRC_BIT) -#define RCC_CFGR_USBPRE (1U << RCC_CFGR_USBPRE_BIT) -#define RCC_CFGR_PLLMUL (0xF << RCC_CFGR_PLLMUL_BIT) +#define RCC_CFGR_USBPRE (0x3 << RCC_CFGR_USBPRE_BIT) +#define RCC_CFGR_PLLMUL (0xF << 18) #define RCC_CFGR_PLLXTPRE (1U << RCC_CFGR_PLLXTPRE_BIT) #define RCC_CFGR_PLLSRC (1U << RCC_CFGR_PLLSRC_BIT) -#define RCC_CFGR_PPRE2 (0x7 << RCC_CFGR_PPRE2_BIT) -#define RCC_CFGR_PPRE1 (0x7 << RCC_CFGR_PPRE1_BIT) -#define RCC_CFGR_HPRE (0xF << RCC_CFGR_HPRE_BIT) +#define RCC_CFGR_ADCPRE (0x3 << 14) +#define RCC_CFGR_PPRE2 (0x7 << 11) +#define RCC_CFGR_PPRE1 (0x7 << 8) +#define RCC_CFGR_HPRE (0xF << 4) #define RCC_CFGR_SWS (0x3 << 2) #define RCC_CFGR_SWS_PLL (0x2 << 2) #define RCC_CFGR_SWS_HSE (0x1 << 2) @@ -157,28 +148,49 @@ typedef struct rcc_reg_map { /* APB2 peripheral reset register */ -#define RCC_APB2RSTR_TIM17RST_BIT 18 -#define RCC_APB2RSTR_TIM16RST_BIT 17 -#define RCC_APB2RSTR_TIM15RST_BIT 16 +#define RCC_APB2RSTR_TIM11RST_BIT 21 +#define RCC_APB2RSTR_TIM10RST_BIT 20 +#define RCC_APB2RSTR_TIM9RST_BIT 19 +#define RCC_APB2RSTR_ADC3RST_BIT 15 #define RCC_APB2RSTR_USART1RST_BIT 14 #define RCC_APB2RSTR_TIM8RST_BIT 13 #define RCC_APB2RSTR_SPI1RST_BIT 12 #define RCC_APB2RSTR_TIM1RST_BIT 11 -#define RCC_APB2RSTR_SYSCFGRST_BIT 0 - -#define RCC_APB2RSTR_TIM17RST (1U << RCC_APB2RSTR_TIM17RST_BIT) -#define RCC_APB2RSTR_TIM16RST (1U << RCC_APB2RSTR_TIM16RST_BIT) -#define RCC_APB2RSTR_TIM15RST (1U << RCC_APB2RSTR_TIM15RST_BIT) +#define RCC_APB2RSTR_ADC2RST_BIT 10 +#define RCC_APB2RSTR_ADC1RST_BIT 9 +#define RCC_APB2RSTR_IOPGRST_BIT 8 +#define RCC_APB2RSTR_IOPFRST_BIT 7 +#define RCC_APB2RSTR_IOPERST_BIT 6 +#define RCC_APB2RSTR_IOPDRST_BIT 5 +#define RCC_APB2RSTR_IOPCRST_BIT 4 +#define RCC_APB2RSTR_IOPBRST_BIT 3 +#define RCC_APB2RSTR_IOPARST_BIT 2 +#define RCC_APB2RSTR_AFIORST_BIT 0 + +#define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT) +#define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT) +#define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT) +#define RCC_APB2RSTR_ADC3RST (1U << RCC_APB2RSTR_ADC3RST_BIT) #define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT) #define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT) #define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT) #define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT) -#define RCC_APB2RSTR_SYSCFGRST (1U << RCC_APB2RSTR_SYSCFGRST_BIT) +#define RCC_APB2RSTR_ADC2RST (1U << RCC_APB2RSTR_ADC2RST_BIT) +#define RCC_APB2RSTR_ADC1RST (1U << RCC_APB2RSTR_ADC1RST_BIT) +#define RCC_APB2RSTR_IOPGRST (1U << RCC_APB2RSTR_IOPGRST_BIT) +#define RCC_APB2RSTR_IOPFRST (1U << RCC_APB2RSTR_IOPFRST_BIT) +#define RCC_APB2RSTR_IOPERST (1U << RCC_APB2RSTR_IOPERST_BIT) +#define RCC_APB2RSTR_IOPDRST (1U << RCC_APB2RSTR_IOPDRST_BIT) +#define RCC_APB2RSTR_IOPCRST (1U << RCC_APB2RSTR_IOPCRST_BIT) +#define RCC_APB2RSTR_IOPBRST (1U << RCC_APB2RSTR_IOPBRST_BIT) +#define RCC_APB2RSTR_IOPARST (1U << RCC_APB2RSTR_IOPARST_BIT) +#define RCC_APB2RSTR_AFIORST (1U << RCC_APB2RSTR_AFIORST_BIT) /* APB1 peripheral reset register */ #define RCC_APB1RSTR_DACRST_BIT 29 #define RCC_APB1RSTR_PWRRST_BIT 28 +#define RCC_APB1RSTR_BKPRST_BIT 27 #define RCC_APB1RSTR_CANRST_BIT 25 #define RCC_APB1RSTR_USBRST_BIT 23 #define RCC_APB1RSTR_I2C2RST_BIT 22 @@ -190,14 +202,19 @@ typedef struct rcc_reg_map { #define RCC_APB1RSTR_SPI3RST_BIT 15 #define RCC_APB1RSTR_SPI2RST_BIT 14 #define RCC_APB1RSTR_WWDRST_BIT 11 +#define RCC_APB1RSTR_TIM14RST_BIT 8 +#define RCC_APB1RSTR_TIM13RST_BIT 7 +#define RCC_APB1RSTR_TIM12RST_BIT 6 #define RCC_APB1RSTR_TIM7RST_BIT 5 #define RCC_APB1RSTR_TIM6RST_BIT 4 +#define RCC_APB1RSTR_TIM5RST_BIT 3 #define RCC_APB1RSTR_TIM4RST_BIT 2 #define RCC_APB1RSTR_TIM3RST_BIT 1 #define RCC_APB1RSTR_TIM2RST_BIT 0 #define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT) #define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT) +#define RCC_APB1RSTR_BKPRST (1U << RCC_APB1RSTR_BKPRST_BIT) #define RCC_APB1RSTR_CANRST (1U << RCC_APB1RSTR_CANRST_BIT) #define RCC_APB1RSTR_USBRST (1U << RCC_APB1RSTR_USBRST_BIT) #define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT) @@ -209,38 +226,28 @@ typedef struct rcc_reg_map { #define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT) #define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT) #define RCC_APB1RSTR_WWDRST (1U << RCC_APB1RSTR_WWDRST_BIT) +#define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT) +#define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT) +#define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT) #define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT) #define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT) +#define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT) #define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT) #define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT) #define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT) /* AHB peripheral clock enable register */ -#define RCC_AHBENR_ADC34EN_BIT 29 -#define RCC_AHBENR_ADC12EN_BIT 28 -#define RCC_AHBENR_TSCEN_BIT 24 -#define RCC_AHBENR_IOPFEN_BIT 22 -#define RCC_AHBENR_IOPEEN_BIT 21 -#define RCC_AHBENR_IOPDEN_BIT 20 -#define RCC_AHBENR_IOPCEN_BIT 19 -#define RCC_AHBENR_IOPBEN_BIT 18 -#define RCC_AHBENR_IOPAEN_BIT 17 -#define RCC_AHBENR_CRCEN_BIT 6 +#define RCC_AHBENR_SDIOEN_BIT 10 +#define RCC_AHBENR_FSMCEN_BIT 8 +#define RCC_AHBENR_CRCEN_BIT 7 #define RCC_AHBENR_FLITFEN_BIT 4 #define RCC_AHBENR_SRAMEN_BIT 2 #define RCC_AHBENR_DMA2EN_BIT 1 #define RCC_AHBENR_DMA1EN_BIT 0 -#define RCC_AHBENR_ADC34EN (1U << RCC_AHBENR_ADC34EN_BIT) -#define RCC_AHBENR_ADC12EN (1U << RCC_AHBENR_ADC12EN_BIT) -#define RCC_AHBENR_TSCEN (1U << RCC_AHBENR_TSCEN_BIT) -#define RCC_AHBENR_IOPFEN (1U << RCC_AHBENR_IOPFEN_BIT) -#define RCC_AHBENR_IOPEEN (1U << RCC_AHBENR_IOPEEN_BIT) -#define RCC_AHBENR_IOPDEN (1U << RCC_AHBENR_IOPDEN_BIT) -#define RCC_AHBENR_IOPCEN (1U << RCC_AHBENR_IOPCEN_BIT) -#define RCC_AHBENR_IOPBEN (1U << RCC_AHBENR_IOPBEN_BIT) -#define RCC_AHBENR_IOPAEN (1U << RCC_AHBENR_IOPAEN_BIT) +#define RCC_AHBENR_SDIOEN (1U << RCC_AHBENR_SDIOEN_BIT) +#define RCC_AHBENR_FSMCEN (1U << RCC_AHBENR_FSMCEN_BIT) #define RCC_AHBENR_CRCEN (1U << RCC_AHBENR_CRCEN_BIT) #define RCC_AHBENR_FLITFEN (1U << RCC_AHBENR_FLITFEN_BIT) #define RCC_AHBENR_SRAMEN (1U << RCC_AHBENR_SRAMEN_BIT) @@ -249,28 +256,49 @@ typedef struct rcc_reg_map { /* APB2 peripheral clock enable register */ -#define RCC_APB2ENR_TIM17EN_BIT 18 -#define RCC_APB2ENR_TIM16EN_BIT 17 -#define RCC_APB2ENR_TIM15EN_BIT 16 +#define RCC_APB2ENR_TIM11EN_BIT 21 +#define RCC_APB2ENR_TIM10EN_BIT 20 +#define RCC_APB2ENR_TIM9EN_BIT 19 +#define RCC_APB2ENR_ADC3EN_BIT 15 #define RCC_APB2ENR_USART1EN_BIT 14 #define RCC_APB2ENR_TIM8EN_BIT 13 #define RCC_APB2ENR_SPI1EN_BIT 12 #define RCC_APB2ENR_TIM1EN_BIT 11 -#define RCC_APB2ENR_SYSCFGEN_BIT 0 - -#define RCC_APB2ENR_TIM17EN (1U << RCC_APB2ENR_TIM17EN_BIT) -#define RCC_APB2ENR_TIM16EN (1U << RCC_APB2ENR_TIM16EN_BIT) -#define RCC_APB2ENR_TIM15EN (1U << RCC_APB2ENR_TIM15EN_BIT) +#define RCC_APB2ENR_ADC2EN_BIT 10 +#define RCC_APB2ENR_ADC1EN_BIT 9 +#define RCC_APB2ENR_IOPGEN_BIT 8 +#define RCC_APB2ENR_IOPFEN_BIT 7 +#define RCC_APB2ENR_IOPEEN_BIT 6 +#define RCC_APB2ENR_IOPDEN_BIT 5 +#define RCC_APB2ENR_IOPCEN_BIT 4 +#define RCC_APB2ENR_IOPBEN_BIT 3 +#define RCC_APB2ENR_IOPAEN_BIT 2 +#define RCC_APB2ENR_AFIOEN_BIT 0 + +#define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT) +#define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT) +#define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT) +#define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT) #define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT) #define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT) #define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT) #define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT) -#define RCC_APB2ENR_SYSCFGEN (1U << RCC_APB2ENR_SYSCFGEN_BIT) +#define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT) +#define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT) +#define RCC_APB2ENR_IOPGEN (1U << RCC_APB2ENR_IOPGEN_BIT) +#define RCC_APB2ENR_IOPFEN (1U << RCC_APB2ENR_IOPFEN_BIT) +#define RCC_APB2ENR_IOPEEN (1U << RCC_APB2ENR_IOPEEN_BIT) +#define RCC_APB2ENR_IOPDEN (1U << RCC_APB2ENR_IOPDEN_BIT) +#define RCC_APB2ENR_IOPCEN (1U << RCC_APB2ENR_IOPCEN_BIT) +#define RCC_APB2ENR_IOPBEN (1U << RCC_APB2ENR_IOPBEN_BIT) +#define RCC_APB2ENR_IOPAEN (1U << RCC_APB2ENR_IOPAEN_BIT) +#define RCC_APB2ENR_AFIOEN (1U << RCC_APB2ENR_AFIOEN_BIT) /* APB1 peripheral clock enable register */ #define RCC_APB1ENR_DACEN_BIT 29 #define RCC_APB1ENR_PWREN_BIT 28 +#define RCC_APB1ENR_BKPEN_BIT 27 #define RCC_APB1ENR_CANEN_BIT 25 #define RCC_APB1ENR_USBEN_BIT 23 #define RCC_APB1ENR_I2C2EN_BIT 22 @@ -282,14 +310,19 @@ typedef struct rcc_reg_map { #define RCC_APB1ENR_SPI3EN_BIT 15 #define RCC_APB1ENR_SPI2EN_BIT 14 #define RCC_APB1ENR_WWDEN_BIT 11 +#define RCC_APB1ENR_TIM14EN_BIT 8 +#define RCC_APB1ENR_TIM13EN_BIT 7 +#define RCC_APB1ENR_TIM12EN_BIT 6 #define RCC_APB1ENR_TIM7EN_BIT 5 #define RCC_APB1ENR_TIM6EN_BIT 4 +#define RCC_APB1ENR_TIM5EN_BIT 3 #define RCC_APB1ENR_TIM4EN_BIT 2 #define RCC_APB1ENR_TIM3EN_BIT 1 #define RCC_APB1ENR_TIM2EN_BIT 0 #define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT) #define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT) +#define RCC_APB1ENR_BKPEN (1U << RCC_APB1ENR_BKPEN_BIT) #define RCC_APB1ENR_CANEN (1U << RCC_APB1ENR_CANEN_BIT) #define RCC_APB1ENR_USBEN (1U << RCC_APB1ENR_USBEN_BIT) #define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT) @@ -301,8 +334,12 @@ typedef struct rcc_reg_map { #define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT) #define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT) #define RCC_APB1ENR_WWDEN (1U << RCC_APB1ENR_WWDEN_BIT) +#define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT) +#define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT) +#define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT) #define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT) #define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT) +#define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT) #define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT) #define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT) #define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT) @@ -320,6 +357,7 @@ typedef struct rcc_reg_map { #define RCC_BDCR_RTCSEL (0x3 << 8) #define RCC_BDCR_RTCSEL_NONE (0x0 << 8) #define RCC_BDCR_RTCSEL_LSE (0x1 << 8) +#define RCC_BDCR_RTCSEL_LSI (0x2 << 8) // added to support RTClock #define RCC_BDCR_RTCSEL_HSE (0x3 << 8) #define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT) #define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT) @@ -333,7 +371,6 @@ typedef struct rcc_reg_map { #define RCC_CSR_SFTRSTF_BIT 28 #define RCC_CSR_PORRSTF_BIT 27 #define RCC_CSR_PINRSTF_BIT 26 -#define RCC_CSR_OBLRSTF_BIT 25 #define RCC_CSR_RMVF_BIT 24 #define RCC_CSR_LSIRDY_BIT 1 #define RCC_CSR_LSION_BIT 0 @@ -344,95 +381,44 @@ typedef struct rcc_reg_map { #define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT) #define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT) #define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT) -#define RCC_CSR_OBLRSTF (1U << RCC_CSR_OBLRSTF_BIT) #define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT) #define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT) #define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT) -/* AHB peripheral reset register */ - -#define RCC_AHBRSTR_ADC34RST_BIT 29 -#define RCC_AHBRSTR_ADC12RST_BIT 28 -#define RCC_AHBRSTR_TSCRST_BIT 24 -#define RCC_AHBRSTR_IOPFRST_BIT 22 -#define RCC_AHBRSTR_IOPERST_BIT 21 -#define RCC_AHBRSTR_IOPDRST_BIT 20 -#define RCC_AHBRSTR_IOPCRST_BIT 19 -#define RCC_AHBRSTR_IOPBRST_BIT 18 -#define RCC_AHBRSTR_IOPARST_BIT 17 - -#define RCC_AHBRSTR_ADC34RST (1U << RCC_AHBRSTR_ADC34RST_BIT) -#define RCC_AHBRSTR_ADC12RST (1U << RCC_AHBRSTR_ADC12RST_BIT) -#define RCC_AHBRSTR_TSCRST (1U << RCC_AHBRSTR_TSCRST_BIT) -#define RCC_AHBRSTR_IOPFRST (1U << RCC_AHBRSTR_IOPFRST_BIT) -#define RCC_AHBRSTR_IOPERST (1U << RCC_AHBRSTR_IOPERST_BIT) -#define RCC_AHBRSTR_IOPDRST (1U << RCC_AHBRSTR_IOPDRST_BIT) -#define RCC_AHBRSTR_IOPCRST (1U << RCC_AHBRSTR_IOPCRST_BIT) -#define RCC_AHBRSTR_IOPBRST (1U << RCC_AHBRSTR_IOPBRST_BIT) -#define RCC_AHBRSTR_IOPARST (1U << RCC_AHBRSTR_IOPARST_BIT) - -/* Clock configuration register 2 */ - -#define RCC_CFGR2_ADC34PRES_SHIFT 9 -#define RCC_CFGR2_ADC12PRES_SHIFT 4 - -#define RCC_CFGR2_ADC34PRES (0x1f << RCC_CFGR2_ADC34PRES_SHIFT) -#define RCC_CFGR2_ADC12PRES (0x1f << RCC_CFGR2_ADC12PRES_SHIFT) -#define RCC_CFGR2_PREDIV 0xf - -/* Clock configuration register 3 */ //TODO make clock sources configurable - -#define RCC_CFGR3_TIM8SW_BIT 9 -#define RCC_CFGR3_TIM1SW_BIT 8 -#define RCC_CFGR3_I2C2SW_BIT 5 -#define RCC_CFGR3_I2C1SW_BIT 4 - -#define RCC_CFGR3_UART5SW (0x3 << 22) -#define RCC_CFGR3_UART4SW (0x3 << 20) -#define RCC_CFGR3_USART3SW (0x3 << 18) -#define RCC_CFGR3_USART2SW (0x3 << 16) -#define RCC_CFGR_TIM8SW (1U << RCC_CFGR3_TIM8SW_BIT) -#define RCC_CFGR_TIM1SW (1U << RCC_CFGR3_TIM1SW_BIT) -#define RCC_CFGR_I2C2SW (1U << RCC_CFGR3_I2C2SW_BIT) -#define RCC_CFGR_I2C1SW (1U << RCC_CFGR3_I2C1SW_BIT) -#define RCC_CFGR3_USART1SW 0x3 - /* * libmaple-mandated enumeration types. */ /** - * @brief STM32F3 rcc_clk_id. + * @brief STM32F1 rcc_clk_id. */ typedef enum rcc_clk_id { + RCC_ADC1, + RCC_ADC2, + RCC_ADC3, + RCC_AFIO, + RCC_BKP, + RCC_CRC, + RCC_DAC, + RCC_DMA1, + RCC_DMA2, + RCC_FLITF, + RCC_FSMC, RCC_GPIOA, RCC_GPIOB, RCC_GPIOC, RCC_GPIOD, RCC_GPIOE, RCC_GPIOF, - - RCC_ADC12, - RCC_ADC34, - - RCC_DAC, - - RCC_DMA1, - RCC_DMA2, - + RCC_GPIOG, RCC_I2C1, RCC_I2C2, - + RCC_PWR, + RCC_SDIO, RCC_SPI1, RCC_SPI2, RCC_SPI3, - - RCC_USART1, - RCC_USART2, - RCC_USART3, - RCC_UART4, - RCC_UART5, - + RCC_SRAM, RCC_TIMER1, RCC_TIMER2, RCC_TIMER3, @@ -447,29 +433,26 @@ typedef enum rcc_clk_id { RCC_TIMER12, RCC_TIMER13, RCC_TIMER14, - RCC_TIMER15, - RCC_TIMER16, - RCC_TIMER17, - - RCC_SYSCFG, - RCC_CRC, - RCC_FLITF, - RCC_PWR, - RCC_SRAM, + RCC_USART1, + RCC_USART2, + RCC_USART3, + RCC_UART4, + RCC_UART5, RCC_USB, + RCC_CAN, //! JMD after X893 } rcc_clk_id; /** - * @brief STM32F3 PLL clock sources. + * @brief STM32F1 PLL clock sources. * @see rcc_configure_pll() */ typedef enum rcc_pllsrc { - RCC_PLLSRC_HSE = (0x1 << RCC_CFGR_PLLSRC_BIT), - RCC_PLLSRC_HSI_DIV_2 = (0x0 << RCC_CFGR_PLLSRC_BIT) + RCC_PLLSRC_HSE = (0x1 << 16), + RCC_PLLSRC_HSI_DIV_2 = (0x0 << 16) } rcc_pllsrc; /** - * @brief STM32F3 clock domains. + * @brief STM32F1 clock domains. * @see rcc_dev_clk() */ typedef enum rcc_clk_domain { @@ -479,7 +462,7 @@ typedef enum rcc_clk_domain { } rcc_clk_domain; /** - * @brief STM32F3 Prescaler identifiers + * @brief STM32F1 Prescaler identifiers * @see rcc_set_prescaler() */ typedef enum rcc_prescaler { @@ -487,94 +470,90 @@ typedef enum rcc_prescaler { RCC_PRESCALER_APB1, RCC_PRESCALER_APB2, RCC_PRESCALER_USB, + RCC_PRESCALER_ADC } rcc_prescaler; /** - * @brief STM32F3 ADC prescaler dividers + * @brief STM32F1 ADC prescaler dividers * @see rcc_set_prescaler() */ typedef enum rcc_adc_divider { - RCC_ADCPRE_PCLK_DISABLED = 0x00, - RCC_ADCPRE_PCLK_DIV_1 = 0x10, - RCC_ADCPRE_PCLK_DIV_2 = 0x11, - RCC_ADCPRE_PCLK_DIV_4 = 0x12, - RCC_ADCPRE_PCLK_DIV_6 = 0x13, - RCC_ADCPRE_PCLK_DIV_8 = 0x14, - RCC_ADCPRE_PCLK_DIV_10 = 0x15, - RCC_ADCPRE_PCLK_DIV_12 = 0x16, - RCC_ADCPRE_PCLK_DIV_16 = 0x17, - RCC_ADCPRE_PCLK_DIV_32 = 0x18, - RCC_ADCPRE_PCLK_DIV_64 = 0x19, - RCC_ADCPRE_PCLK_DIV_128 = 0x1A, - RCC_ADCPRE_PCLK_DIV_256 = 0x1B, + RCC_ADCPRE_PCLK_DIV_2 = 0x0 << 14, + RCC_ADCPRE_PCLK_DIV_4 = 0x1 << 14, + RCC_ADCPRE_PCLK_DIV_6 = 0x2 << 14, + RCC_ADCPRE_PCLK_DIV_8 = 0x3 << 14, } rcc_adc_divider; /** - * @brief STM32F3 PREDIV prescaler dividers - * @see rcc_set_prescaler() - */ -typedef enum rcc_prediv_divider { - RCC_PREDIV_PCLK_DIV_1 = 0x0, - RCC_PREDIV_PCLK_DIV_2 = 0x1, - RCC_PREDIV_PCLK_DIV_3 = 0x2, - RCC_PREDIV_PCLK_DIV_4 = 0x3, - RCC_PREDIV_PCLK_DIV_5 = 0x4, - RCC_PREDIV_PCLK_DIV_6 = 0x5, - RCC_PREDIV_PCLK_DIV_7 = 0x6, - RCC_PREDIV_PCLK_DIV_8 = 0x7, - RCC_PREDIV_PCLK_DIV_9 = 0x8, - RCC_PREDIV_PCLK_DIV_10 = 0x9, - RCC_PREDIV_PCLK_DIV_11 = 0xA, - RCC_PREDIV_PCLK_DIV_12 = 0xB, - RCC_PREDIV_PCLK_DIV_13 = 0xC, - RCC_PREDIV_PCLK_DIV_14 = 0xD, - RCC_PREDIV_PCLK_DIV_15 = 0xE, - RCC_PREDIV_PCLK_DIV_16 = 0xF, -} rcc_prediv_divider; - -/** - * @brief STM32F3 APB1 prescaler dividers + * @brief STM32F1 APB1 prescaler dividers * @see rcc_set_prescaler() */ typedef enum rcc_apb1_divider { - RCC_APB1_HCLK_DIV_1 = 0x0 << RCC_CFGR_PPRE1_BIT, - RCC_APB1_HCLK_DIV_2 = 0x4 << RCC_CFGR_PPRE1_BIT, - RCC_APB1_HCLK_DIV_4 = 0x5 << RCC_CFGR_PPRE1_BIT, - RCC_APB1_HCLK_DIV_8 = 0x6 << RCC_CFGR_PPRE1_BIT, - RCC_APB1_HCLK_DIV_16 = 0x7 << RCC_CFGR_PPRE1_BIT, + RCC_APB1_HCLK_DIV_1 = 0x0 << 8, + RCC_APB1_HCLK_DIV_2 = 0x4 << 8, + RCC_APB1_HCLK_DIV_4 = 0x5 << 8, + RCC_APB1_HCLK_DIV_8 = 0x6 << 8, + RCC_APB1_HCLK_DIV_16 = 0x7 << 8, } rcc_apb1_divider; /** - * @brief STM32F3 APB2 prescaler dividers + * @brief STM32F1 APB2 prescaler dividers * @see rcc_set_prescaler() */ typedef enum rcc_apb2_divider { - RCC_APB2_HCLK_DIV_1 = 0x0 << RCC_CFGR_PPRE2_BIT, - RCC_APB2_HCLK_DIV_2 = 0x4 << RCC_CFGR_PPRE2_BIT, - RCC_APB2_HCLK_DIV_4 = 0x5 << RCC_CFGR_PPRE2_BIT, - RCC_APB2_HCLK_DIV_8 = 0x6 << RCC_CFGR_PPRE2_BIT, - RCC_APB2_HCLK_DIV_16 = 0x7 << RCC_CFGR_PPRE2_BIT, + RCC_APB2_HCLK_DIV_1 = 0x0 << 11, + RCC_APB2_HCLK_DIV_2 = 0x4 << 11, + RCC_APB2_HCLK_DIV_4 = 0x5 << 11, + RCC_APB2_HCLK_DIV_8 = 0x6 << 11, + RCC_APB2_HCLK_DIV_16 = 0x7 << 11, } rcc_apb2_divider; /** - * @brief STM32F3 AHB prescaler dividers + * @brief STM32F1 AHB prescaler dividers * @see rcc_set_prescaler() */ typedef enum rcc_ahb_divider { - RCC_AHB_SYSCLK_DIV_1 = 0x0 << RCC_CFGR_HPRE_BIT, - RCC_AHB_SYSCLK_DIV_2 = 0x8 << RCC_CFGR_HPRE_BIT, - RCC_AHB_SYSCLK_DIV_4 = 0x9 << RCC_CFGR_HPRE_BIT, - RCC_AHB_SYSCLK_DIV_8 = 0xA << RCC_CFGR_HPRE_BIT, - RCC_AHB_SYSCLK_DIV_16 = 0xB << RCC_CFGR_HPRE_BIT, - RCC_AHB_SYSCLK_DIV_32 = 0xC << RCC_CFGR_HPRE_BIT, - RCC_AHB_SYSCLK_DIV_64 = 0xD << RCC_CFGR_HPRE_BIT, - RCC_AHB_SYSCLK_DIV_128 = 0xD << RCC_CFGR_HPRE_BIT, - RCC_AHB_SYSCLK_DIV_256 = 0xE << RCC_CFGR_HPRE_BIT, - RCC_AHB_SYSCLK_DIV_512 = 0xF << RCC_CFGR_HPRE_BIT, + RCC_AHB_SYSCLK_DIV_1 = 0x0 << 4, + RCC_AHB_SYSCLK_DIV_2 = 0x8 << 4, + RCC_AHB_SYSCLK_DIV_4 = 0x9 << 4, + RCC_AHB_SYSCLK_DIV_8 = 0xA << 4, + RCC_AHB_SYSCLK_DIV_16 = 0xB << 4, + RCC_AHB_SYSCLK_DIV_32 = 0xC << 4, + RCC_AHB_SYSCLK_DIV_64 = 0xD << 4, + RCC_AHB_SYSCLK_DIV_128 = 0xD << 4, + RCC_AHB_SYSCLK_DIV_256 = 0xE << 4, + RCC_AHB_SYSCLK_DIV_512 = 0xF << 4, } rcc_ahb_divider; /** - * @brief STM32F3 clock sources. + * @brief STM32F1 USB prescaler dividers + * @see rcc_set_prescaler() + */ + /* + Set and reset by software to control the USB clock prescaler value. The USB clock +must be 48MHz. These bits can’t be reset if the USB clock is enabled. +00: (CK_PLL / 1.5) selected +01: CK_PLL selected + */ + +typedef enum rcc_usb_divider { + RCC_USB_SYSCLK_DIV_1 = 0x1 << 22, + RCC_USB_SYSCLK_DIV_1_5 = 0x0 << 22, + RCC_USB_SYSCLK_DIV_2 = 0x3 << 22, + RCC_USB_SYSCLK_DIV_2_5 = 0x2 << 22, +} rcc_usb_divider; + + +/** + * @brief Start the low speed internal oscillator + */ +static inline void rcc_start_lsi(void) { + *bb_perip(&RCC_BASE->CSR, RCC_CSR_LSION_BIT) = 1; + while (*bb_perip(&RCC_BASE->CSR, RCC_CSR_LSIRDY_BIT) == 0); +} + +/** + * @brief STM32F1 clock sources. */ typedef enum rcc_clk { RCC_CLK_PLL = (uint16)((offsetof(struct rcc_reg_map, CR) << 8) | @@ -593,37 +572,67 @@ typedef enum rcc_clk { } rcc_clk; /** - * @brief STM32F3 PLL multipliers. + * @brief STM32F1 PLL multipliers. */ typedef enum rcc_pll_multiplier { - RCC_PLLMUL_2 = (0x0 << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_3 = (0x1 << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_4 = (0x2 << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_5 = (0x3 << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_6 = (0x4 << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_7 = (0x5 << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_8 = (0x6 << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_9 = (0x7 << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_10 = (0x8 << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_11 = (0x9 << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_12 = (0xA << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_13 = (0xB << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_14 = (0xC << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_15 = (0xD << RCC_CFGR_PLLMUL_BIT), - RCC_PLLMUL_16 = (0xE << RCC_CFGR_PLLMUL_BIT), + RCC_PLLMUL_2 = (0x0 << 18), + RCC_PLLMUL_3 = (0x1 << 18), + RCC_PLLMUL_4 = (0x2 << 18), + RCC_PLLMUL_5 = (0x3 << 18), + RCC_PLLMUL_6 = (0x4 << 18), + RCC_PLLMUL_7 = (0x5 << 18), + RCC_PLLMUL_8 = (0x6 << 18), + RCC_PLLMUL_9 = (0x7 << 18), + RCC_PLLMUL_10 = (0x8 << 18), + RCC_PLLMUL_11 = (0x9 << 18), + RCC_PLLMUL_12 = (0xA << 18), + RCC_PLLMUL_13 = (0xB << 18), + RCC_PLLMUL_14 = (0xC << 18), + RCC_PLLMUL_15 = (0xD << 18), + RCC_PLLMUL_16 = (0xE << 18), } rcc_pll_multiplier; /* FIXME [0.0.13] Just have data point to an rcc_pll_multiplier! */ +/** + * @brief Start the low speed external oscillatior + */ +static inline void rcc_start_lse(void) { + bb_peri_set_bit(&RCC_BASE->BDCR, RCC_BDCR_LSEBYP_BIT, 0); + bb_peri_set_bit(&RCC_BASE->BDCR, RCC_BDCR_LSEON_BIT, 1); + while (bb_peri_get_bit(&RCC_BASE->BDCR, RCC_BDCR_LSERDY_BIT ) == 0); +} /** - * @brief STM32F3 PLL configuration values. + * @brief STM32F1 PLL configuration values. * Point to one of these with the "data" field in a struct rcc_pll_cfg. * @see struct rcc_pll_cfg. */ -typedef struct stm32f3_rcc_pll_data { +typedef struct stm32f1_rcc_pll_data { rcc_pll_multiplier pll_mul; /**< PLL multiplication factor. */ - rcc_prediv_divider pclk_prediv; /**< PCLK predivider. */ -} stm32f3_rcc_pll_data; +} stm32f1_rcc_pll_data; + +/* + * Deprecated bits. + */ +static inline void rcc_start_hse(void) { // Added to support RTClock +// *bb_perip(&RCC_BASE->CR, RCC_CR_HSEON_BIT) = 1; + while (bb_peri_get_bit(&RCC_BASE->CR, RCC_CR_HSERDY_BIT) == 0); +} + +/** + * @brief Deprecated; STM32F1 only. + * + * Initialize the clock control system. Initializes the system + * clock source to use the PLL driven by an external oscillator. + * + * @param sysclk_src system clock source, must be PLL + * @param pll_src pll clock source, must be HSE + * @param pll_mul pll multiplier + */ +__deprecated +void rcc_clk_init(rcc_sysclk_src sysclk_src, + rcc_pllsrc pll_src, + rcc_pll_multiplier pll_mul); #ifdef __cplusplus } diff --git a/STM32F1/libraries/rcc_f1.c b/STM32F1/libraries/rcc_f1.c new file mode 100644 index 000000000..9040a4dc2 --- /dev/null +++ b/STM32F1/libraries/rcc_f1.c @@ -0,0 +1,174 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/stm32f1/rcc.c + * @brief STM32F1 RCC. + */ + +#include +#include +#include + +#include "rcc_private.h" + +#define APB1 RCC_APB1 +#define APB2 RCC_APB2 +#define AHB RCC_AHB + +/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset + * register bit numbers. */ +const struct rcc_dev_info rcc_dev_table[] = { + [RCC_GPIOA] = { .clk_domain = APB2, .line_num = 2 }, + [RCC_GPIOB] = { .clk_domain = APB2, .line_num = 3 }, + [RCC_GPIOC] = { .clk_domain = APB2, .line_num = 4 }, + [RCC_GPIOD] = { .clk_domain = APB2, .line_num = 5 }, + [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 }, + [RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 }, + [RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 }, + [RCC_ADC3] = { .clk_domain = APB2, .line_num = 15 }, + [RCC_USART1] = { .clk_domain = APB2, .line_num = 14 }, + [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, + [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, + [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 }, + [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 }, + [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 }, + [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 }, + [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 }, + [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 }, + [RCC_DMA1] = { .clk_domain = AHB, .line_num = 0 }, + [RCC_PWR] = { .clk_domain = APB1, .line_num = 28}, + [RCC_BKP] = { .clk_domain = APB1, .line_num = 27}, + [RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 }, + [RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 }, + [RCC_CRC] = { .clk_domain = AHB, .line_num = 6}, + [RCC_FLITF] = { .clk_domain = AHB, .line_num = 4}, + [RCC_SRAM] = { .clk_domain = AHB, .line_num = 2}, + [RCC_USB] = { .clk_domain = APB1, .line_num = 23}, +#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) + [RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 }, + [RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 }, + [RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 }, + [RCC_UART4] = { .clk_domain = APB1, .line_num = 19 }, + [RCC_UART5] = { .clk_domain = APB1, .line_num = 20 }, + [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, + [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, + [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, + [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 }, + [RCC_FSMC] = { .clk_domain = AHB, .line_num = 8 }, + [RCC_DAC] = { .clk_domain = APB1, .line_num = 29 }, + [RCC_DMA2] = { .clk_domain = AHB, .line_num = 1 }, + [RCC_SDIO] = { .clk_domain = AHB, .line_num = 10 }, + [RCC_SPI3] = { .clk_domain = APB1, .line_num = 15 }, +#endif +#ifdef STM32_XL_DENSITY + [RCC_TIMER9] = { .clk_domain = APB2, .line_num = 19 }, + [RCC_TIMER10] = { .clk_domain = APB2, .line_num = 20 }, + [RCC_TIMER11] = { .clk_domain = APB2, .line_num = 21 }, + [RCC_TIMER12] = { .clk_domain = APB1, .line_num = 6 }, + [RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 }, + [RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 }, +#endif + [RCC_CAN] = { .clk_domain = APB1, .line_num = 25 }, //! JMD after X893 +}; + +__deprecated +void rcc_clk_init(rcc_sysclk_src sysclk_src, + rcc_pllsrc pll_src, + rcc_pll_multiplier pll_mul) { + /* Assume that we're going to clock the chip off the PLL, fed by + * the HSE */ + ASSERT(sysclk_src == RCC_CLKSRC_PLL && + pll_src == RCC_PLLSRC_HSE); + + RCC_BASE->CFGR = pll_src | pll_mul | (0x3<<22); + + /* Turn on, and wait for, HSE. */ + rcc_turn_on_clk(RCC_CLK_HSE); + while (!rcc_is_clk_ready(RCC_CLK_HSE)) + ; + + /* Do the same for the main PLL. */ + rcc_turn_on_clk(RCC_CLK_PLL); + while(!rcc_is_clk_ready(RCC_CLK_PLL)) + ; + + /* Finally, switch over to the PLL. */ + rcc_switch_sysclk(RCC_CLKSRC_PLL); +} + +/* pll_cfg->data must point to a valid struct stm32f1_rcc_pll_data. */ +void rcc_configure_pll(rcc_pll_cfg *pll_cfg) { + stm32f1_rcc_pll_data *data = pll_cfg->data; + rcc_pll_multiplier pll_mul = data->pll_mul; + uint32 cfgr; + /* Check that the PLL is disabled. */ + ASSERT_FAULT(!rcc_is_clk_on(RCC_CLK_PLL)); + + cfgr = RCC_BASE->CFGR; + cfgr &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL); + cfgr |= pll_cfg->pllsrc | pll_mul; + + RCC_BASE->CFGR = cfgr; +} + +void rcc_clk_enable(rcc_clk_id id) { + static __io uint32* enable_regs[] = { + [APB1] = &RCC_BASE->APB1ENR, + [APB2] = &RCC_BASE->APB2ENR, + [AHB] = &RCC_BASE->AHBENR, + }; + rcc_do_clk_enable(enable_regs, id); +} + +void rcc_reset_dev(rcc_clk_id id) { + static __io uint32* reset_regs[] = { + [APB1] = &RCC_BASE->APB1RSTR, + [APB2] = &RCC_BASE->APB2RSTR, + }; + rcc_do_reset_dev(reset_regs, id); +} + +void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { + static const uint32 masks[] = { + [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE, + [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1, + [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2, + [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE, + [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE, + }; + rcc_do_set_prescaler(masks, prescaler, divider); +} + +void rcc_clk_disable(rcc_clk_id id) { + static __io uint32* enable_regs[] = { + [APB1] = &RCC_BASE->APB1ENR, + [APB2] = &RCC_BASE->APB2ENR, + [AHB] = &RCC_BASE->AHBENR, + }; + rcc_do_clk_disable(enable_regs, id); +} \ No newline at end of file diff --git a/STM32F1/libraries/stm_fft/cr4_fft_1024_stm32.asm b/STM32F1/libraries/stm_fft/cr4_fft_1024_stm32.asm new file mode 100644 index 000000000..26c17261f --- /dev/null +++ b/STM32F1/libraries/stm_fft/cr4_fft_1024_stm32.asm @@ -0,0 +1,577 @@ +/*;******************** (C) COPYRIGHT 2009 STMicroelectronics ******************** +;* File Name : cr4_fft_1024_stm32.s +;* Author : MCD Application Team +;* Version : V2.0.0 +;* Date : 04/27/2009 +;* Description : Optimized 1024-point radix-4 complex FFT for Cortex-M3 +;******************************************************************************** +;* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +;* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +;* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +;* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +;* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +;* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +;*******************************************************************************/ + +.cpu cortex-m3 +.fpu softvfp +.syntax unified +.thumb +.text + +.global cr4_fft_1024_stm32 +.extern TableFFT + +.equ NPT, 1024 + + +/*;******************************************************************************* +;* Function Name : cr4_fft_1024_stm32 +;* Description : complex radix-4 1024 points FFT +;* Input : - R0 = pssOUT: Output array . +;* - R1 = pssIN: Input array +;* - R2 = Nbin: =1024 number of points, this optimized FFT function +;* can only convert 1024 points. +;* Output : None +;* Return : None +;*********************************************************************************/ +.thumb_func +cr4_fft_1024_stm32: + + STMFD SP!, {R4-R11, LR} + + MOV r12, #0 + MOV r3, r0 + MOV r0,#0 + +preloop_v7: + ADD r14, r1, r12, LSR#22 /*1024pts*/ + + LDRSH r5, [r14, #2] + LDRSH r4, [r14] + ADD r14, #NPT + LDRSH r9, [r14, #2] + LDRSH r8, [r14] + ADD r14, #NPT + LDRSH r7, [r14, #2] + LDRSH r6, [r14] + ADD r14, #NPT + LDRSH r11, [r14, #2] + LDRSH r10, [r14] + ADD r14, #NPT + + + ADD r8, r8, r10 + ADD r9, r9, r11 + SUB r10, r8, r10, LSL#1 + SUB r11, r9, r11, LSL#1 + + MOV r4, r4, ASR#2 + MOV r5, r5, ASR#2 + ADD r4, r4, r6, ASR#2 + ADD r5, r5, r7, ASR#2 + SUB r6, r4, r6, ASR#1 + SUB r7, r5, r7, ASR#1 + + ADD r4, r4, r8, ASR#2 + ADD r5, r5, r9, ASR#2 + SUB r8, r4, r8, ASR#1 + SUB r9, r5, r9, ASR#1 + + ADD r6, r6, r11, ASR#2 + SUB r7, r7, r10, ASR#2 + SUB r11, r6, r11, ASR#1 + ADD r10, r7, r10, ASR#1 + + STRH r5, [r3, #2] + STRH r4, [r3], #4 + STRH r7, [r3, #2] + STRH r6, [r3], #4 + STRH r9, [r3, #2] + STRH r8, [r3], #4 + STRH r10, [r3, #2] + STRH r11, [r3], #4 + + ADD r0, r0, #1 + + RBIT r12, r0 + + CMP r0,#256 /*1024pts*/ + BNE preloop_v7 + + SUB r1, r3, r2, LSL#2 + MOV r0, #16 + MOVS r2, r2, LSR#4 + +/*;------------------------------------------------------------------------------ +; The FFT coefficients table can be stored into Flash or RAM. +; The following two lines of code allow selecting the method for coefficients +; storage. +; In the case of choosing coefficients in RAM, you have to: +; 1. Include the file table_fft.h, which is a part of the DSP library, +; in your main file. +; 2. Decomment the line LDR.W pssK, =TableFFT and comment the line +; ADRL pssK, TableFFT_V7 +; 3. Comment all the TableFFT_V7 data. +;------------------------------------------------------------------------------*/ + ADR r3, TableFFT_V7 + /*LDR.W r3, =TableFFT*/ + + +passloop_v7: + STMFD SP!, {r1,r2} + ADD r12, r0, r0, LSL#1 + ADD r1, r1, r12 + SUB r2, r2, #1<<16 + +grouploop_v7: + ADD r2,r2,r0,LSL#(16-2) + +butterloop_v7: + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r11, [r3, #2] + LDRSH r10, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r11 + ADD r14, r10, r11, LSL#1 + MLA r11, r5, r10, r12 + MLA r10, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r9, [r3, #2] + LDRSH r8, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r9 + ADD r14, r8, r9, LSL#1 + MLA r9, r5, r8, r12 + MLA r8, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r7, [r3, #2] + LDRSH r6, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r7 + ADD r14, r6, r7, LSL#1 + MLA r7, r5, r6, r12 + MLA r6, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + + ADD r8, r8, r10 + ADD r9, r9, r11 + SUB r10, r8, r10, LSL#1 + SUB r11, r9, r11, LSL#1 + + MOV r4, r4, ASR#2 + MOV r5, r5, ASR#2 + ADD r4, r4, r6, ASR#(2+14) + ADD r5, r5, r7, ASR#(2+14) + SUB r6, r4, r6, ASR#(1+14) + SUB r7, r5, r7, ASR#(1+14) + + ADD r4, r4, r8, ASR#(2+14) + ADD r5, r5, r9, ASR#(2+14) + SUB r8, r4, r8, ASR#(1+14) + SUB r9, r5, r9, ASR#(1+14) + + ADD r6, r6, r11, ASR#(2+14) + SUB r7, r7, r10, ASR#(2+14) + SUB r11, r6, r11, ASR#(1+14) + ADD r10, r7, r10, ASR#(1+14) + + STRH r5, [r1, #2] + STRH r4, [r1] + ADD r1, r1, r0 + STRH r7, [r1, #2] + STRH r6, [r1] + ADD r1, r1, r0 + STRH r9, [r1, #2] + STRH r8, [r1] + ADD r1, r1, r0 + STRH r10, [r1, #2] + STRH r11, [r1], #4 + SUBS r2,r2, #1<<16 + BGE butterloop_v7 + ADD r12, r0, r0, LSL#1 + ADD r1, r1, r12 + + SUB r2, r2, #1 + MOVS r14, r2, LSL#16 + IT ne + SUBNE r3, r3, r12 + BNE grouploop_v7 + + LDMFD sp!, {r1, r2} + MOV r0,r0,LSL#2 + MOVS r2, r2, LSR#2 + BNE passloop_v7 + LDMFD SP!, {R4-R11, PC} + + +TableFFT_V7: + + /*N=16*/ + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + /*N=64*/ + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0x2aaa,0x1294, 0x396b,0x0646, 0x3249,0x0c7c + .short 0x11a8,0x238e, 0x3249,0x0c7c, 0x22a3,0x187e + .short 0xf721,0x3179, 0x2aaa,0x1294, 0x11a8,0x238e + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xc695,0x3fb1, 0x1a46,0x1e2b, 0xee58,0x3537 + .short 0xb4be,0x3ec5, 0x11a8,0x238e, 0xdd5d,0x3b21 + .short 0xa963,0x3871, 0x08df,0x289a, 0xcdb7,0x3ec5 + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xa963,0x1e2b, 0xf721,0x3179, 0xb4be,0x3ec5 + .short 0xb4be,0x0c7c, 0xee58,0x3537, 0xac61,0x3b21 + .short 0xc695,0xf9ba, 0xe5ba,0x3871, 0xa73b,0x3537 + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + .short 0xf721,0xd766, 0xd556,0x3d3f, 0xa73b,0x238e + .short 0x11a8,0xcac9, 0xcdb7,0x3ec5, 0xac61,0x187e + .short 0x2aaa,0xc2c1, 0xc695,0x3fb1, 0xb4be,0x0c7c + /*N=256*/ + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0x3b1e,0x04b5, 0x3e69,0x0192, 0x3cc8,0x0324 + .short 0x35eb,0x0964, 0x3cc8,0x0324, 0x396b,0x0646 + .short 0x306c,0x0e06, 0x3b1e,0x04b5, 0x35eb,0x0964 + .short 0x2aaa,0x1294, 0x396b,0x0646, 0x3249,0x0c7c + .short 0x24ae,0x1709, 0x37af,0x07d6, 0x2e88,0x0f8d + .short 0x1e7e,0x1b5d, 0x35eb,0x0964, 0x2aaa,0x1294 + .short 0x1824,0x1f8c, 0x341e,0x0af1, 0x26b3,0x1590 + .short 0x11a8,0x238e, 0x3249,0x0c7c, 0x22a3,0x187e + .short 0x0b14,0x2760, 0x306c,0x0e06, 0x1e7e,0x1b5d + .short 0x0471,0x2afb, 0x2e88,0x0f8d, 0x1a46,0x1e2b + .short 0xfdc7,0x2e5a, 0x2c9d,0x1112, 0x15fe,0x20e7 + .short 0xf721,0x3179, 0x2aaa,0x1294, 0x11a8,0x238e + .short 0xf087,0x3453, 0x28b2,0x1413, 0x0d48,0x2620 + .short 0xea02,0x36e5, 0x26b3,0x1590, 0x08df,0x289a + .short 0xe39c,0x392b, 0x24ae,0x1709, 0x0471,0x2afb + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xd74e,0x3cc5, 0x2093,0x19ef, 0xfb8f,0x2f6c + .short 0xd178,0x3e15, 0x1e7e,0x1b5d, 0xf721,0x3179 + .short 0xcbe2,0x3f0f, 0x1c64,0x1cc6, 0xf2b8,0x3368 + .short 0xc695,0x3fb1, 0x1a46,0x1e2b, 0xee58,0x3537 + .short 0xc197,0x3ffb, 0x1824,0x1f8c, 0xea02,0x36e5 + .short 0xbcf0,0x3fec, 0x15fe,0x20e7, 0xe5ba,0x3871 + .short 0xb8a6,0x3f85, 0x13d5,0x223d, 0xe182,0x39db + .short 0xb4be,0x3ec5, 0x11a8,0x238e, 0xdd5d,0x3b21 + .short 0xb140,0x3daf, 0x0f79,0x24da, 0xd94d,0x3c42 + .short 0xae2e,0x3c42, 0x0d48,0x2620, 0xd556,0x3d3f + .short 0xab8e,0x3a82, 0x0b14,0x2760, 0xd178,0x3e15 + .short 0xa963,0x3871, 0x08df,0x289a, 0xcdb7,0x3ec5 + .short 0xa7b1,0x3612, 0x06a9,0x29ce, 0xca15,0x3f4f + .short 0xa678,0x3368, 0x0471,0x2afb, 0xc695,0x3fb1 + .short 0xa5bc,0x3076, 0x0239,0x2c21, 0xc338,0x3fec + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xa5bc,0x29ce, 0xfdc7,0x2e5a, 0xbcf0,0x3fec + .short 0xa678,0x2620, 0xfb8f,0x2f6c, 0xba09,0x3fb1 + .short 0xa7b1,0x223d, 0xf957,0x3076, 0xb74d,0x3f4f + .short 0xa963,0x1e2b, 0xf721,0x3179, 0xb4be,0x3ec5 + .short 0xab8e,0x19ef, 0xf4ec,0x3274, 0xb25e,0x3e15 + .short 0xae2e,0x1590, 0xf2b8,0x3368, 0xb02d,0x3d3f + .short 0xb140,0x1112, 0xf087,0x3453, 0xae2e,0x3c42 + .short 0xb4be,0x0c7c, 0xee58,0x3537, 0xac61,0x3b21 + .short 0xb8a6,0x07d6, 0xec2b,0x3612, 0xaac8,0x39db + .short 0xbcf0,0x0324, 0xea02,0x36e5, 0xa963,0x3871 + .short 0xc197,0xfe6e, 0xe7dc,0x37b0, 0xa834,0x36e5 + .short 0xc695,0xf9ba, 0xe5ba,0x3871, 0xa73b,0x3537 + .short 0xcbe2,0xf50f, 0xe39c,0x392b, 0xa678,0x3368 + .short 0xd178,0xf073, 0xe182,0x39db, 0xa5ed,0x3179 + .short 0xd74e,0xebed, 0xdf6d,0x3a82, 0xa599,0x2f6c + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + .short 0xe39c,0xe33a, 0xdb52,0x3bb6, 0xa599,0x2afb + .short 0xea02,0xdf19, 0xd94d,0x3c42, 0xa5ed,0x289a + .short 0xf087,0xdb26, 0xd74e,0x3cc5, 0xa678,0x2620 + .short 0xf721,0xd766, 0xd556,0x3d3f, 0xa73b,0x238e + .short 0xfdc7,0xd3df, 0xd363,0x3daf, 0xa834,0x20e7 + .short 0x0471,0xd094, 0xd178,0x3e15, 0xa963,0x1e2b + .short 0x0b14,0xcd8c, 0xcf94,0x3e72, 0xaac8,0x1b5d + .short 0x11a8,0xcac9, 0xcdb7,0x3ec5, 0xac61,0x187e + .short 0x1824,0xc850, 0xcbe2,0x3f0f, 0xae2e,0x1590 + .short 0x1e7e,0xc625, 0xca15,0x3f4f, 0xb02d,0x1294 + .short 0x24ae,0xc44a, 0xc851,0x3f85, 0xb25e,0x0f8d + .short 0x2aaa,0xc2c1, 0xc695,0x3fb1, 0xb4be,0x0c7c + .short 0x306c,0xc18e, 0xc4e2,0x3fd4, 0xb74d,0x0964 + .short 0x35eb,0xc0b1, 0xc338,0x3fec, 0xba09,0x0646 + .short 0x3b1e,0xc02c, 0xc197,0x3ffb, 0xbcf0,0x0324 + /*N=1024*/ + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0x3ed0,0x012e, 0x3f9b,0x0065, 0x3f36,0x00c9 + .short 0x3d9a,0x025b, 0x3f36,0x00c9, 0x3e69,0x0192 + .short 0x3c5f,0x0388, 0x3ed0,0x012e, 0x3d9a,0x025b + .short 0x3b1e,0x04b5, 0x3e69,0x0192, 0x3cc8,0x0324 + .short 0x39d9,0x05e2, 0x3e02,0x01f7, 0x3bf4,0x03ed + .short 0x388e,0x070e, 0x3d9a,0x025b, 0x3b1e,0x04b5 + .short 0x373f,0x0839, 0x3d31,0x02c0, 0x3a46,0x057e + .short 0x35eb,0x0964, 0x3cc8,0x0324, 0x396b,0x0646 + .short 0x3492,0x0a8e, 0x3c5f,0x0388, 0x388e,0x070e + .short 0x3334,0x0bb7, 0x3bf4,0x03ed, 0x37af,0x07d6 + .short 0x31d2,0x0cdf, 0x3b8a,0x0451, 0x36ce,0x089d + .short 0x306c,0x0e06, 0x3b1e,0x04b5, 0x35eb,0x0964 + .short 0x2f02,0x0f2b, 0x3ab2,0x051a, 0x3505,0x0a2b + .short 0x2d93,0x1050, 0x3a46,0x057e, 0x341e,0x0af1 + .short 0x2c21,0x1173, 0x39d9,0x05e2, 0x3334,0x0bb7 + .short 0x2aaa,0x1294, 0x396b,0x0646, 0x3249,0x0c7c + .short 0x2931,0x13b4, 0x38fd,0x06aa, 0x315b,0x0d41 + .short 0x27b3,0x14d2, 0x388e,0x070e, 0x306c,0x0e06 + .short 0x2632,0x15ee, 0x381f,0x0772, 0x2f7b,0x0eca + .short 0x24ae,0x1709, 0x37af,0x07d6, 0x2e88,0x0f8d + .short 0x2326,0x1821, 0x373f,0x0839, 0x2d93,0x1050 + .short 0x219c,0x1937, 0x36ce,0x089d, 0x2c9d,0x1112 + .short 0x200e,0x1a4b, 0x365d,0x0901, 0x2ba4,0x11d3 + .short 0x1e7e,0x1b5d, 0x35eb,0x0964, 0x2aaa,0x1294 + .short 0x1ceb,0x1c6c, 0x3578,0x09c7, 0x29af,0x1354 + .short 0x1b56,0x1d79, 0x3505,0x0a2b, 0x28b2,0x1413 + .short 0x19be,0x1e84, 0x3492,0x0a8e, 0x27b3,0x14d2 + .short 0x1824,0x1f8c, 0x341e,0x0af1, 0x26b3,0x1590 + .short 0x1688,0x2091, 0x33a9,0x0b54, 0x25b1,0x164c + .short 0x14ea,0x2193, 0x3334,0x0bb7, 0x24ae,0x1709 + .short 0x134a,0x2292, 0x32bf,0x0c1a, 0x23a9,0x17c4 + .short 0x11a8,0x238e, 0x3249,0x0c7c, 0x22a3,0x187e + .short 0x1005,0x2488, 0x31d2,0x0cdf, 0x219c,0x1937 + .short 0x0e61,0x257e, 0x315b,0x0d41, 0x2093,0x19ef + .short 0x0cbb,0x2671, 0x30e4,0x0da4, 0x1f89,0x1aa7 + .short 0x0b14,0x2760, 0x306c,0x0e06, 0x1e7e,0x1b5d + .short 0x096d,0x284c, 0x2ff4,0x0e68, 0x1d72,0x1c12 + .short 0x07c4,0x2935, 0x2f7b,0x0eca, 0x1c64,0x1cc6 + .short 0x061b,0x2a1a, 0x2f02,0x0f2b, 0x1b56,0x1d79 + .short 0x0471,0x2afb, 0x2e88,0x0f8d, 0x1a46,0x1e2b + .short 0x02c7,0x2bd8, 0x2e0e,0x0fee, 0x1935,0x1edc + .short 0x011c,0x2cb2, 0x2d93,0x1050, 0x1824,0x1f8c + .short 0xff72,0x2d88, 0x2d18,0x10b1, 0x1711,0x203a + .short 0xfdc7,0x2e5a, 0x2c9d,0x1112, 0x15fe,0x20e7 + .short 0xfc1d,0x2f28, 0x2c21,0x1173, 0x14ea,0x2193 + .short 0xfa73,0x2ff2, 0x2ba4,0x11d3, 0x13d5,0x223d + .short 0xf8ca,0x30b8, 0x2b28,0x1234, 0x12bf,0x22e7 + .short 0xf721,0x3179, 0x2aaa,0x1294, 0x11a8,0x238e + .short 0xf579,0x3236, 0x2a2d,0x12f4, 0x1091,0x2435 + .short 0xf3d2,0x32ef, 0x29af,0x1354, 0x0f79,0x24da + .short 0xf22c,0x33a3, 0x2931,0x13b4, 0x0e61,0x257e + .short 0xf087,0x3453, 0x28b2,0x1413, 0x0d48,0x2620 + .short 0xeee3,0x34ff, 0x2833,0x1473, 0x0c2e,0x26c1 + .short 0xed41,0x35a5, 0x27b3,0x14d2, 0x0b14,0x2760 + .short 0xeba1,0x3648, 0x2733,0x1531, 0x09fa,0x27fe + .short 0xea02,0x36e5, 0x26b3,0x1590, 0x08df,0x289a + .short 0xe865,0x377e, 0x2632,0x15ee, 0x07c4,0x2935 + .short 0xe6cb,0x3812, 0x25b1,0x164c, 0x06a9,0x29ce + .short 0xe532,0x38a1, 0x252f,0x16ab, 0x058d,0x2a65 + .short 0xe39c,0x392b, 0x24ae,0x1709, 0x0471,0x2afb + .short 0xe208,0x39b0, 0x242b,0x1766, 0x0355,0x2b8f + .short 0xe077,0x3a30, 0x23a9,0x17c4, 0x0239,0x2c21 + .short 0xdee9,0x3aab, 0x2326,0x1821, 0x011c,0x2cb2 + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xdbd5,0x3b92, 0x221f,0x18db, 0xfee4,0x2dcf + .short 0xda4f,0x3bfd, 0x219c,0x1937, 0xfdc7,0x2e5a + .short 0xd8cd,0x3c64, 0x2117,0x1993, 0xfcab,0x2ee4 + .short 0xd74e,0x3cc5, 0x2093,0x19ef, 0xfb8f,0x2f6c + .short 0xd5d3,0x3d21, 0x200e,0x1a4b, 0xfa73,0x2ff2 + .short 0xd45c,0x3d78, 0x1f89,0x1aa7, 0xf957,0x3076 + .short 0xd2e8,0x3dc9, 0x1f04,0x1b02, 0xf83c,0x30f9 + .short 0xd178,0x3e15, 0x1e7e,0x1b5d, 0xf721,0x3179 + .short 0xd00c,0x3e5c, 0x1df8,0x1bb8, 0xf606,0x31f8 + .short 0xcea5,0x3e9d, 0x1d72,0x1c12, 0xf4ec,0x3274 + .short 0xcd41,0x3ed8, 0x1ceb,0x1c6c, 0xf3d2,0x32ef + .short 0xcbe2,0x3f0f, 0x1c64,0x1cc6, 0xf2b8,0x3368 + .short 0xca88,0x3f40, 0x1bdd,0x1d20, 0xf19f,0x33df + .short 0xc932,0x3f6b, 0x1b56,0x1d79, 0xf087,0x3453 + .short 0xc7e1,0x3f91, 0x1ace,0x1dd3, 0xef6f,0x34c6 + .short 0xc695,0x3fb1, 0x1a46,0x1e2b, 0xee58,0x3537 + .short 0xc54e,0x3fcc, 0x19be,0x1e84, 0xed41,0x35a5 + .short 0xc40c,0x3fe1, 0x1935,0x1edc, 0xec2b,0x3612 + .short 0xc2cf,0x3ff1, 0x18ad,0x1f34, 0xeb16,0x367d + .short 0xc197,0x3ffb, 0x1824,0x1f8c, 0xea02,0x36e5 + .short 0xc065,0x4000, 0x179b,0x1fe3, 0xe8ef,0x374b + .short 0xbf38,0x3fff, 0x1711,0x203a, 0xe7dc,0x37b0 + .short 0xbe11,0x3ff8, 0x1688,0x2091, 0xe6cb,0x3812 + .short 0xbcf0,0x3fec, 0x15fe,0x20e7, 0xe5ba,0x3871 + .short 0xbbd4,0x3fdb, 0x1574,0x213d, 0xe4aa,0x38cf + .short 0xbabf,0x3fc4, 0x14ea,0x2193, 0xe39c,0x392b + .short 0xb9af,0x3fa7, 0x145f,0x21e8, 0xe28e,0x3984 + .short 0xb8a6,0x3f85, 0x13d5,0x223d, 0xe182,0x39db + .short 0xb7a2,0x3f5d, 0x134a,0x2292, 0xe077,0x3a30 + .short 0xb6a5,0x3f30, 0x12bf,0x22e7, 0xdf6d,0x3a82 + .short 0xb5af,0x3efd, 0x1234,0x233b, 0xde64,0x3ad3 + .short 0xb4be,0x3ec5, 0x11a8,0x238e, 0xdd5d,0x3b21 + .short 0xb3d5,0x3e88, 0x111d,0x23e2, 0xdc57,0x3b6d + .short 0xb2f2,0x3e45, 0x1091,0x2435, 0xdb52,0x3bb6 + .short 0xb215,0x3dfc, 0x1005,0x2488, 0xda4f,0x3bfd + .short 0xb140,0x3daf, 0x0f79,0x24da, 0xd94d,0x3c42 + .short 0xb071,0x3d5b, 0x0eed,0x252c, 0xd84d,0x3c85 + .short 0xafa9,0x3d03, 0x0e61,0x257e, 0xd74e,0x3cc5 + .short 0xaee8,0x3ca5, 0x0dd4,0x25cf, 0xd651,0x3d03 + .short 0xae2e,0x3c42, 0x0d48,0x2620, 0xd556,0x3d3f + .short 0xad7b,0x3bda, 0x0cbb,0x2671, 0xd45c,0x3d78 + .short 0xacd0,0x3b6d, 0x0c2e,0x26c1, 0xd363,0x3daf + .short 0xac2b,0x3afa, 0x0ba1,0x2711, 0xd26d,0x3de3 + .short 0xab8e,0x3a82, 0x0b14,0x2760, 0xd178,0x3e15 + .short 0xaaf8,0x3a06, 0x0a87,0x27af, 0xd085,0x3e45 + .short 0xaa6a,0x3984, 0x09fa,0x27fe, 0xcf94,0x3e72 + .short 0xa9e3,0x38fd, 0x096d,0x284c, 0xcea5,0x3e9d + .short 0xa963,0x3871, 0x08df,0x289a, 0xcdb7,0x3ec5 + .short 0xa8eb,0x37e1, 0x0852,0x28e7, 0xcccc,0x3eeb + .short 0xa87b,0x374b, 0x07c4,0x2935, 0xcbe2,0x3f0f + .short 0xa812,0x36b1, 0x0736,0x2981, 0xcafb,0x3f30 + .short 0xa7b1,0x3612, 0x06a9,0x29ce, 0xca15,0x3f4f + .short 0xa757,0x356e, 0x061b,0x2a1a, 0xc932,0x3f6b + .short 0xa705,0x34c6, 0x058d,0x2a65, 0xc851,0x3f85 + .short 0xa6bb,0x3419, 0x04ff,0x2ab0, 0xc772,0x3f9c + .short 0xa678,0x3368, 0x0471,0x2afb, 0xc695,0x3fb1 + .short 0xa63e,0x32b2, 0x03e3,0x2b45, 0xc5ba,0x3fc4 + .short 0xa60b,0x31f8, 0x0355,0x2b8f, 0xc4e2,0x3fd4 + .short 0xa5e0,0x3139, 0x02c7,0x2bd8, 0xc40c,0x3fe1 + .short 0xa5bc,0x3076, 0x0239,0x2c21, 0xc338,0x3fec + .short 0xa5a1,0x2faf, 0x01aa,0x2c6a, 0xc266,0x3ff5 + .short 0xa58d,0x2ee4, 0x011c,0x2cb2, 0xc197,0x3ffb + .short 0xa581,0x2e15, 0x008e,0x2cfa, 0xc0ca,0x3fff + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xa581,0x2c6a, 0xff72,0x2d88, 0xbf38,0x3fff + .short 0xa58d,0x2b8f, 0xfee4,0x2dcf, 0xbe73,0x3ffb + .short 0xa5a1,0x2ab0, 0xfe56,0x2e15, 0xbdb0,0x3ff5 + .short 0xa5bc,0x29ce, 0xfdc7,0x2e5a, 0xbcf0,0x3fec + .short 0xa5e0,0x28e7, 0xfd39,0x2e9f, 0xbc32,0x3fe1 + .short 0xa60b,0x27fe, 0xfcab,0x2ee4, 0xbb77,0x3fd4 + .short 0xa63e,0x2711, 0xfc1d,0x2f28, 0xbabf,0x3fc4 + .short 0xa678,0x2620, 0xfb8f,0x2f6c, 0xba09,0x3fb1 + .short 0xa6bb,0x252c, 0xfb01,0x2faf, 0xb956,0x3f9c + .short 0xa705,0x2435, 0xfa73,0x2ff2, 0xb8a6,0x3f85 + .short 0xa757,0x233b, 0xf9e5,0x3034, 0xb7f8,0x3f6b + .short 0xa7b1,0x223d, 0xf957,0x3076, 0xb74d,0x3f4f + .short 0xa812,0x213d, 0xf8ca,0x30b8, 0xb6a5,0x3f30 + .short 0xa87b,0x203a, 0xf83c,0x30f9, 0xb600,0x3f0f + .short 0xa8eb,0x1f34, 0xf7ae,0x3139, 0xb55e,0x3eeb + .short 0xa963,0x1e2b, 0xf721,0x3179, 0xb4be,0x3ec5 + .short 0xa9e3,0x1d20, 0xf693,0x31b9, 0xb422,0x3e9d + .short 0xaa6a,0x1c12, 0xf606,0x31f8, 0xb388,0x3e72 + .short 0xaaf8,0x1b02, 0xf579,0x3236, 0xb2f2,0x3e45 + .short 0xab8e,0x19ef, 0xf4ec,0x3274, 0xb25e,0x3e15 + .short 0xac2b,0x18db, 0xf45f,0x32b2, 0xb1cd,0x3de3 + .short 0xacd0,0x17c4, 0xf3d2,0x32ef, 0xb140,0x3daf + .short 0xad7b,0x16ab, 0xf345,0x332c, 0xb0b5,0x3d78 + .short 0xae2e,0x1590, 0xf2b8,0x3368, 0xb02d,0x3d3f + .short 0xaee8,0x1473, 0xf22c,0x33a3, 0xafa9,0x3d03 + .short 0xafa9,0x1354, 0xf19f,0x33df, 0xaf28,0x3cc5 + .short 0xb071,0x1234, 0xf113,0x3419, 0xaea9,0x3c85 + .short 0xb140,0x1112, 0xf087,0x3453, 0xae2e,0x3c42 + .short 0xb215,0x0fee, 0xeffb,0x348d, 0xadb6,0x3bfd + .short 0xb2f2,0x0eca, 0xef6f,0x34c6, 0xad41,0x3bb6 + .short 0xb3d5,0x0da4, 0xeee3,0x34ff, 0xacd0,0x3b6d + .short 0xb4be,0x0c7c, 0xee58,0x3537, 0xac61,0x3b21 + .short 0xb5af,0x0b54, 0xedcc,0x356e, 0xabf6,0x3ad3 + .short 0xb6a5,0x0a2b, 0xed41,0x35a5, 0xab8e,0x3a82 + .short 0xb7a2,0x0901, 0xecb6,0x35dc, 0xab29,0x3a30 + .short 0xb8a6,0x07d6, 0xec2b,0x3612, 0xaac8,0x39db + .short 0xb9af,0x06aa, 0xeba1,0x3648, 0xaa6a,0x3984 + .short 0xbabf,0x057e, 0xeb16,0x367d, 0xaa0f,0x392b + .short 0xbbd4,0x0451, 0xea8c,0x36b1, 0xa9b7,0x38cf + .short 0xbcf0,0x0324, 0xea02,0x36e5, 0xa963,0x3871 + .short 0xbe11,0x01f7, 0xe978,0x3718, 0xa912,0x3812 + .short 0xbf38,0x00c9, 0xe8ef,0x374b, 0xa8c5,0x37b0 + .short 0xc065,0xff9b, 0xe865,0x377e, 0xa87b,0x374b + .short 0xc197,0xfe6e, 0xe7dc,0x37b0, 0xa834,0x36e5 + .short 0xc2cf,0xfd40, 0xe753,0x37e1, 0xa7f1,0x367d + .short 0xc40c,0xfc13, 0xe6cb,0x3812, 0xa7b1,0x3612 + .short 0xc54e,0xfae6, 0xe642,0x3842, 0xa774,0x35a5 + .short 0xc695,0xf9ba, 0xe5ba,0x3871, 0xa73b,0x3537 + .short 0xc7e1,0xf88e, 0xe532,0x38a1, 0xa705,0x34c6 + .short 0xc932,0xf763, 0xe4aa,0x38cf, 0xa6d3,0x3453 + .short 0xca88,0xf639, 0xe423,0x38fd, 0xa6a4,0x33df + .short 0xcbe2,0xf50f, 0xe39c,0x392b, 0xa678,0x3368 + .short 0xcd41,0xf3e6, 0xe315,0x3958, 0xa650,0x32ef + .short 0xcea5,0xf2bf, 0xe28e,0x3984, 0xa62c,0x3274 + .short 0xd00c,0xf198, 0xe208,0x39b0, 0xa60b,0x31f8 + .short 0xd178,0xf073, 0xe182,0x39db, 0xa5ed,0x3179 + .short 0xd2e8,0xef4f, 0xe0fc,0x3a06, 0xa5d3,0x30f9 + .short 0xd45c,0xee2d, 0xe077,0x3a30, 0xa5bc,0x3076 + .short 0xd5d3,0xed0c, 0xdff2,0x3a59, 0xa5a9,0x2ff2 + .short 0xd74e,0xebed, 0xdf6d,0x3a82, 0xa599,0x2f6c + .short 0xd8cd,0xeacf, 0xdee9,0x3aab, 0xa58d,0x2ee4 + .short 0xda4f,0xe9b4, 0xde64,0x3ad3, 0xa585,0x2e5a + .short 0xdbd5,0xe89a, 0xdde1,0x3afa, 0xa57f,0x2dcf + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + .short 0xdee9,0xe66d, 0xdcda,0x3b47, 0xa57f,0x2cb2 + .short 0xe077,0xe559, 0xdc57,0x3b6d, 0xa585,0x2c21 + .short 0xe208,0xe448, 0xdbd5,0x3b92, 0xa58d,0x2b8f + .short 0xe39c,0xe33a, 0xdb52,0x3bb6, 0xa599,0x2afb + .short 0xe532,0xe22d, 0xdad1,0x3bda, 0xa5a9,0x2a65 + .short 0xe6cb,0xe124, 0xda4f,0x3bfd, 0xa5bc,0x29ce + .short 0xe865,0xe01d, 0xd9ce,0x3c20, 0xa5d3,0x2935 + .short 0xea02,0xdf19, 0xd94d,0x3c42, 0xa5ed,0x289a + .short 0xeba1,0xde18, 0xd8cd,0x3c64, 0xa60b,0x27fe + .short 0xed41,0xdd19, 0xd84d,0x3c85, 0xa62c,0x2760 + .short 0xeee3,0xdc1e, 0xd7cd,0x3ca5, 0xa650,0x26c1 + .short 0xf087,0xdb26, 0xd74e,0x3cc5, 0xa678,0x2620 + .short 0xf22c,0xda31, 0xd6cf,0x3ce4, 0xa6a4,0x257e + .short 0xf3d2,0xd93f, 0xd651,0x3d03, 0xa6d3,0x24da + .short 0xf579,0xd851, 0xd5d3,0x3d21, 0xa705,0x2435 + .short 0xf721,0xd766, 0xd556,0x3d3f, 0xa73b,0x238e + .short 0xf8ca,0xd67f, 0xd4d8,0x3d5b, 0xa774,0x22e7 + .short 0xfa73,0xd59b, 0xd45c,0x3d78, 0xa7b1,0x223d + .short 0xfc1d,0xd4bb, 0xd3df,0x3d93, 0xa7f1,0x2193 + .short 0xfdc7,0xd3df, 0xd363,0x3daf, 0xa834,0x20e7 + .short 0xff72,0xd306, 0xd2e8,0x3dc9, 0xa87b,0x203a + .short 0x011c,0xd231, 0xd26d,0x3de3, 0xa8c5,0x1f8c + .short 0x02c7,0xd161, 0xd1f2,0x3dfc, 0xa912,0x1edc + .short 0x0471,0xd094, 0xd178,0x3e15, 0xa963,0x1e2b + .short 0x061b,0xcfcc, 0xd0fe,0x3e2d, 0xa9b7,0x1d79 + .short 0x07c4,0xcf07, 0xd085,0x3e45, 0xaa0f,0x1cc6 + .short 0x096d,0xce47, 0xd00c,0x3e5c, 0xaa6a,0x1c12 + .short 0x0b14,0xcd8c, 0xcf94,0x3e72, 0xaac8,0x1b5d + .short 0x0cbb,0xccd4, 0xcf1c,0x3e88, 0xab29,0x1aa7 + .short 0x0e61,0xcc21, 0xcea5,0x3e9d, 0xab8e,0x19ef + .short 0x1005,0xcb73, 0xce2e,0x3eb1, 0xabf6,0x1937 + .short 0x11a8,0xcac9, 0xcdb7,0x3ec5, 0xac61,0x187e + .short 0x134a,0xca24, 0xcd41,0x3ed8, 0xacd0,0x17c4 + .short 0x14ea,0xc983, 0xcccc,0x3eeb, 0xad41,0x1709 + .short 0x1688,0xc8e8, 0xcc57,0x3efd, 0xadb6,0x164c + .short 0x1824,0xc850, 0xcbe2,0x3f0f, 0xae2e,0x1590 + .short 0x19be,0xc7be, 0xcb6e,0x3f20, 0xaea9,0x14d2 + .short 0x1b56,0xc731, 0xcafb,0x3f30, 0xaf28,0x1413 + .short 0x1ceb,0xc6a8, 0xca88,0x3f40, 0xafa9,0x1354 + .short 0x1e7e,0xc625, 0xca15,0x3f4f, 0xb02d,0x1294 + .short 0x200e,0xc5a7, 0xc9a3,0x3f5d, 0xb0b5,0x11d3 + .short 0x219c,0xc52d, 0xc932,0x3f6b, 0xb140,0x1112 + .short 0x2326,0xc4b9, 0xc8c1,0x3f78, 0xb1cd,0x1050 + .short 0x24ae,0xc44a, 0xc851,0x3f85, 0xb25e,0x0f8d + .short 0x2632,0xc3e0, 0xc7e1,0x3f91, 0xb2f2,0x0eca + .short 0x27b3,0xc37b, 0xc772,0x3f9c, 0xb388,0x0e06 + .short 0x2931,0xc31c, 0xc703,0x3fa7, 0xb422,0x0d41 + .short 0x2aaa,0xc2c1, 0xc695,0x3fb1, 0xb4be,0x0c7c + .short 0x2c21,0xc26d, 0xc627,0x3fbb, 0xb55e,0x0bb7 + .short 0x2d93,0xc21d, 0xc5ba,0x3fc4, 0xb600,0x0af1 + .short 0x2f02,0xc1d3, 0xc54e,0x3fcc, 0xb6a5,0x0a2b + .short 0x306c,0xc18e, 0xc4e2,0x3fd4, 0xb74d,0x0964 + .short 0x31d2,0xc14f, 0xc476,0x3fdb, 0xb7f8,0x089d + .short 0x3334,0xc115, 0xc40c,0x3fe1, 0xb8a6,0x07d6 + .short 0x3492,0xc0e0, 0xc3a1,0x3fe7, 0xb956,0x070e + .short 0x35eb,0xc0b1, 0xc338,0x3fec, 0xba09,0x0646 + .short 0x373f,0xc088, 0xc2cf,0x3ff1, 0xbabf,0x057e + .short 0x388e,0xc064, 0xc266,0x3ff5, 0xbb77,0x04b5 + .short 0x39d9,0xc045, 0xc1fe,0x3ff8, 0xbc32,0x03ed + .short 0x3b1e,0xc02c, 0xc197,0x3ffb, 0xbcf0,0x0324 + .short 0x3c5f,0xc019, 0xc130,0x3ffd, 0xbdb0,0x025b + .short 0x3d9a,0xc00b, 0xc0ca,0x3fff, 0xbe73,0x0192 + .short 0x3ed0,0xc003, 0xc065,0x4000, 0xbf38,0x00c9 + + +.end +/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F1/libraries/stm_fft/cr4_fft_16_stm33.asm b/STM32F1/libraries/stm_fft/cr4_fft_16_stm33.asm new file mode 100644 index 000000000..1d60179e5 --- /dev/null +++ b/STM32F1/libraries/stm_fft/cr4_fft_16_stm33.asm @@ -0,0 +1,250 @@ +/*;******************** (C) COPYRIGHT 2009 STMicroelectronics ******************** +;* File Name : cr4_fft_64_stm32.s +;* Author : MCD Application Team +;* Version : V2.0.0 +;* Date : 04/27/2009 +;* Description : Optimized 64-point radix-4 complex FFT for Cortex-M3 +;******************************************************************************** +;* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +;* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +;* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +;* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +;* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +;* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +;*******************************************************************************/ + +.cpu cortex-m3 +.fpu softvfp +.syntax unified +.thumb +.text + +.global cr4_fft_16_stm32 +.extern TableFFT + +.equ NPT, 16 + + +/*;******************************************************************************* +;* Function Name : cr4_fft_16_stm32 +;* Description : complex radix-4 16 points FFT +;* Input : - R0 = pssOUT: Output array . +;* - R1 = pssIN: Input array +;* - R2 = Nbin: = 16 number of points, this optimized FFT function +;* can only convert 16 points. +;* Output : None +;* Return : None +;********************************************************************************/ +.thumb_func +cr4_fft_16_stm32: + + STMFD SP!, {R4-R11, LR} + + MOV r12, #0 + MOV r3, r0 + MOV r0,#0 + +preloop_v7: + ADD r14, r1, r12, LSR#28 + + LDRSH r5, [r14, #2] + LDRSH r4, [r14],#NPT + LDRSH r9, [r14, #2] + LDRSH r8, [r14],#NPT + LDRSH r7, [r14, #2] + LDRSH r6, [r14],#NPT + LDRSH r11, [r14, #2] + LDRSH r10, [r14],#NPT + + ADD r8, r8, r10 + ADD r9, r9, r11 + SUB r10, r8, r10, LSL#1 + SUB r11, r9, r11, LSL#1 + + MOV r4, r4, ASR#2 + MOV r5, r5, ASR#2 + ADD r4, r4, r6, ASR#2 + ADD r5, r5, r7, ASR#2 + SUB r6, r4, r6, ASR#1 + SUB r7, r5, r7, ASR#1 + + ADD r4, r4, r8, ASR#2 + ADD r5, r5, r9, ASR#2 + SUB r8, r4, r8, ASR#1 + SUB r9, r5, r9, ASR#1 + + ADD r6, r6, r11, ASR#2 + SUB r7, r7, r10, ASR#2 + SUB r11, r6, r11, ASR#1 + ADD r10, r7, r10, ASR#1 + + STRH r5, [r3, #2] + STRH r4, [r3], #4 + STRH r7, [r3, #2] + STRH r6, [r3], #4 + STRH r9, [r3, #2] + STRH r8, [r3], #4 + STRH r10, [r3, #2] + STRH r11, [r3], #4 + + ADD r0, r0, #1 + + RBIT r12, r0 + + CMP r0,#4 + BNE preloop_v7 + + SUB r1, r3, r2, LSL#2 + MOV r0, #16 + MOVS r2, r2, LSR#4 + +/*;------------------------------------------------------------------------------ +; The FFT coefficients table can be stored into Flash or RAM. +; The following two lines of code allow selecting the method for coefficients +; storage. +; In the case of choosing coefficients in RAM, you have to: +; 1. Include the file table_fft.h, which is a part of the DSP library, +; in your main file. +; 2. Decomment the line LDR.W pssK, =TableFFT and comment the line +; ADRL pssK, TableFFT_V7 +; 3. Comment all the TableFFT_V7 data. +;------------------------------------------------------------------------------*/ + ADR r3, TableFFT_V7 + /*LDR.W r3, =TableFFT*/ + + +passloop_v7: + STMFD SP!, {r1,r2} + ADD r12, r0, r0, LSL#1 + ADD r1, r1, r12 + SUB r2, r2, #1<<16 + +grouploop_v7: + ADD r2,r2,r0,LSL#(16-2) + +butterloop_v7: + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r11, [r3, #2] + LDRSH r10, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r11 + ADD r14, r10, r11, LSL#1 + MLA r11, r5, r10, r12 + MLA r10, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r9, [r3, #2] + LDRSH r8, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r9 + ADD r14, r8, r9, LSL#1 + MLA r9, r5, r8, r12 + MLA r8, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r7, [r3, #2] + LDRSH r6, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r7 + ADD r14, r6, r7, LSL#1 + MLA r7, r5, r6, r12 + MLA r6, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + + ADD r8, r8, r10 + ADD r9, r9, r11 + SUB r10, r8, r10, LSL#1 + SUB r11, r9, r11, LSL#1 + + MOV r4, r4, ASR#2 + MOV r5, r5, ASR#2 + ADD r4, r4, r6, ASR#(2+14) + ADD r5, r5, r7, ASR#(2+14) + SUB r6, r4, r6, ASR#(1+14) + SUB r7, r5, r7, ASR#(1+14) + + ADD r4, r4, r8, ASR#(2+14) + ADD r5, r5, r9, ASR#(2+14) + SUB r8, r4, r8, ASR#(1+14) + SUB r9, r5, r9, ASR#(1+14) + + ADD r6, r6, r11, ASR#(2+14) + SUB r7, r7, r10, ASR#(2+14) + SUB r11, r6, r11, ASR#(1+14) + ADD r10, r7, r10, ASR#(1+14) + + STRH r5, [r1, #2] + STRH r4, [r1] + ADD r1, r1, r0 + STRH r7, [r1, #2] + STRH r6, [r1] + ADD r1, r1, r0 + STRH r9, [r1, #2] + STRH r8, [r1] + ADD r1, r1, r0 + STRH r10, [r1, #2] + STRH r11, [r1], #4 + SUBS r2,r2, #1<<16 + BGE butterloop_v7 + ADD r12, r0, r0, LSL#1 + ADD r1, r1, r12 + + SUB r2, r2, #1 + MOVS r14, r2, LSL#16 + IT ne + SUBNE r3, r3, r12 + BNE grouploop_v7 + + LDMFD sp!, {r1, r2} + MOV r0,r0,LSL#2 + MOVS r2, r2, LSR#2 + BNE passloop_v7 + LDMFD SP!, {R4-R11, PC} + + +TableFFT_V7: + /*N=16*/ + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + /*N=64*/ + /* + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0x2aaa,0x1294, 0x396b,0x0646, 0x3249,0x0c7c + .short 0x11a8,0x238e, 0x3249,0x0c7c, 0x22a3,0x187e + .short 0xf721,0x3179, 0x2aaa,0x1294, 0x11a8,0x238e + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xc695,0x3fb1, 0x1a46,0x1e2b, 0xee58,0x3537 + .short 0xb4be,0x3ec5, 0x11a8,0x238e, 0xdd5d,0x3b21 + .short 0xa963,0x3871, 0x08df,0x289a, 0xcdb7,0x3ec5 + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xa963,0x1e2b, 0xf721,0x3179, 0xb4be,0x3ec5 + .short 0xb4be,0x0c7c, 0xee58,0x3537, 0xac61,0x3b21 + .short 0xc695,0xf9ba, 0xe5ba,0x3871, 0xa73b,0x3537 + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + .short 0xf721,0xd766, 0xd556,0x3d3f, 0xa73b,0x238e + .short 0x11a8,0xcac9, 0xcdb7,0x3ec5, 0xac61,0x187e + .short 0x2aaa,0xc2c1, 0xc695,0x3fb1, 0xb4be,0x0c7c + */ + +.end +/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F1/libraries/stm_fft/cr4_fft_256_stm32.asm b/STM32F1/libraries/stm_fft/cr4_fft_256_stm32.asm new file mode 100644 index 000000000..15e4b0c8c --- /dev/null +++ b/STM32F1/libraries/stm_fft/cr4_fft_256_stm32.asm @@ -0,0 +1,318 @@ +/*;******************** (C) COPYRIGHT 2009 STMicroelectronics ******************** +;* File Name : cr4_fft_256_stm32.s +;* Author : MCD Application Team +;* Version : V2.0.0 +;* Date : 04/27/2009 +;* Description : Optimized 256-point radix-4 complex FFT for Cortex-M3 +;******************************************************************************** +;* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +;* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +;* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +;* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +;* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +;* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +;*******************************************************************************/ + +.cpu cortex-m3 +.fpu softvfp +.syntax unified +.thumb +.text + +.global cr4_fft_256_stm32 +.extern TableFFT + +.equ NPT, 256 + + +/*;******************************************************************************* +;* Function Name : cr4_fft_256_stm32 +;* Description : complex radix-4 256 points FFT +;* Input : - R0 = pssOUT: Output array . +;* - R1 = pssIN: Input array +;* - R2 = Nbin: =256 number of points, this optimized FFT function +;* can only convert 256 points. +;* Output : None +;* Return : None +;********************************************************************************/ +.thumb_func +cr4_fft_256_stm32: + + STMFD SP!, {R4-R11, LR} + + MOV r12, #0 + MOV r3, r0 + MOV r0,#0 + +preloop_v7: + ADD r14, r1, r12, LSR#24 /*256pts*/ + + LDRSH r5, [r14, #2] + LDRSH r4, [r14] + ADD r14, #NPT + LDRSH r9, [r14, #2] + LDRSH r8, [r14] + ADD r14, #NPT + LDRSH r7, [r14, #2] + LDRSH r6, [r14] + ADD r14, #NPT + LDRSH r11, [r14, #2] + LDRSH r10, [r14] + ADD r14, #NPT + + ADD r8, r8, r10 + ADD r9, r9, r11 + SUB r10, r8, r10, LSL#1 + SUB r11, r9, r11, LSL#1 + + MOV r4, r4, ASR#2 + MOV r5, r5, ASR#2 + ADD r4, r4, r6, ASR#2 + ADD r5, r5, r7, ASR#2 + SUB r6, r4, r6, ASR#1 + SUB r7, r5, r7, ASR#1 + + ADD r4, r4, r8, ASR#2 + ADD r5, r5, r9, ASR#2 + SUB r8, r4, r8, ASR#1 + SUB r9, r5, r9, ASR#1 + + ADD r6, r6, r11, ASR#2 + SUB r7, r7, r10, ASR#2 + SUB r11, r6, r11, ASR#1 + ADD r10, r7, r10, ASR#1 + + STRH r5, [r3, #2] + STRH r4, [r3], #4 + STRH r7, [r3, #2] + STRH r6, [r3], #4 + STRH r9, [r3, #2] + STRH r8, [r3], #4 + STRH r10, [r3, #2] + STRH r11, [r3], #4 + + ADD r0, r0, #1 + + RBIT r12, r0 + + CMP r0,#64 /*256pts*/ + BNE preloop_v7 + + SUB r1, r3, r2, LSL#2 + MOV r0, #16 + MOVS r2, r2, LSR#4 + +/*;------------------------------------------------------------------------------ +; The FFT coefficients table can be stored into Flash or RAM. +; The following two lines of code allow selecting the method for coefficients +; storage. +; In the case of choosing coefficients in RAM, you have to: +; 1. Include the file table_fft.h, which is a part of the DSP library, +; in your main file. +; 2. Decomment the line LDR.W pssK, =TableFFT and comment the line +; ADRL pssK, TableFFT_V7 +; 3. Comment all the TableFFT_V7 data. +;------------------------------------------------------------------------------*/ + ADR r3, TableFFT_V7 + /*LDR.W r3, =TableFFT*/ + + +passloop_v7: + STMFD SP!, {r1,r2} + ADD r12, r0, r0, LSL#1 + ADD r1, r1, r12 + SUB r2, r2, #1<<16 + +grouploop_v7: + ADD r2,r2,r0,LSL#(16-2) + +butterloop_v7: + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r11, [r3, #2] + LDRSH r10, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r11 + ADD r14, r10, r11, LSL#1 + MLA r11, r5, r10, r12 + MLA r10, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r9, [r3, #2] + LDRSH r8, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r9 + ADD r14, r8, r9, LSL#1 + MLA r9, r5, r8, r12 + MLA r8, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r7, [r3, #2] + LDRSH r6, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r7 + ADD r14, r6, r7, LSL#1 + MLA r7, r5, r6, r12 + MLA r6, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + + ADD r8, r8, r10 + ADD r9, r9, r11 + SUB r10, r8, r10, LSL#1 + SUB r11, r9, r11, LSL#1 + + MOV r4, r4, ASR#2 + MOV r5, r5, ASR#2 + ADD r4, r4, r6, ASR#(2+14) + ADD r5, r5, r7, ASR#(2+14) + SUB r6, r4, r6, ASR#(1+14) + SUB r7, r5, r7, ASR#(1+14) + + ADD r4, r4, r8, ASR#(2+14) + ADD r5, r5, r9, ASR#(2+14) + SUB r8, r4, r8, ASR#(1+14) + SUB r9, r5, r9, ASR#(1+14) + + ADD r6, r6, r11, ASR#(2+14) + SUB r7, r7, r10, ASR#(2+14) + SUB r11, r6, r11, ASR#(1+14) + ADD r10, r7, r10, ASR#(1+14) + + STRH r5, [r1, #2] + STRH r4, [r1] + ADD r1, r1, r0 + STRH r7, [r1, #2] + STRH r6, [r1] + ADD r1, r1, r0 + STRH r9, [r1, #2] + STRH r8, [r1] + ADD r1, r1, r0 + STRH r10, [r1, #2] + STRH r11, [r1], #4 + SUBS r2,r2, #1<<16 + BGE butterloop_v7 + ADD r12, r0, r0, LSL#1 + ADD r1, r1, r12 + + SUB r2, r2, #1 + MOVS r14, r2, LSL#16 + IT ne + SUBNE r3, r3, r12 + BNE grouploop_v7 + + LDMFD sp!, {r1, r2} + MOV r0,r0,LSL#2 + MOVS r2, r2, LSR#2 + BNE passloop_v7 + LDMFD SP!, {R4-R11, PC} + + +TableFFT_V7: + /*N=16*/ + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + /*N=64*/ + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0x2aaa,0x1294, 0x396b,0x0646, 0x3249,0x0c7c + .short 0x11a8,0x238e, 0x3249,0x0c7c, 0x22a3,0x187e + .short 0xf721,0x3179, 0x2aaa,0x1294, 0x11a8,0x238e + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xc695,0x3fb1, 0x1a46,0x1e2b, 0xee58,0x3537 + .short 0xb4be,0x3ec5, 0x11a8,0x238e, 0xdd5d,0x3b21 + .short 0xa963,0x3871, 0x08df,0x289a, 0xcdb7,0x3ec5 + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xa963,0x1e2b, 0xf721,0x3179, 0xb4be,0x3ec5 + .short 0xb4be,0x0c7c, 0xee58,0x3537, 0xac61,0x3b21 + .short 0xc695,0xf9ba, 0xe5ba,0x3871, 0xa73b,0x3537 + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + .short 0xf721,0xd766, 0xd556,0x3d3f, 0xa73b,0x238e + .short 0x11a8,0xcac9, 0xcdb7,0x3ec5, 0xac61,0x187e + .short 0x2aaa,0xc2c1, 0xc695,0x3fb1, 0xb4be,0x0c7c + /*N=256*/ + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0x3b1e,0x04b5, 0x3e69,0x0192, 0x3cc8,0x0324 + .short 0x35eb,0x0964, 0x3cc8,0x0324, 0x396b,0x0646 + .short 0x306c,0x0e06, 0x3b1e,0x04b5, 0x35eb,0x0964 + .short 0x2aaa,0x1294, 0x396b,0x0646, 0x3249,0x0c7c + .short 0x24ae,0x1709, 0x37af,0x07d6, 0x2e88,0x0f8d + .short 0x1e7e,0x1b5d, 0x35eb,0x0964, 0x2aaa,0x1294 + .short 0x1824,0x1f8c, 0x341e,0x0af1, 0x26b3,0x1590 + .short 0x11a8,0x238e, 0x3249,0x0c7c, 0x22a3,0x187e + .short 0x0b14,0x2760, 0x306c,0x0e06, 0x1e7e,0x1b5d + .short 0x0471,0x2afb, 0x2e88,0x0f8d, 0x1a46,0x1e2b + .short 0xfdc7,0x2e5a, 0x2c9d,0x1112, 0x15fe,0x20e7 + .short 0xf721,0x3179, 0x2aaa,0x1294, 0x11a8,0x238e + .short 0xf087,0x3453, 0x28b2,0x1413, 0x0d48,0x2620 + .short 0xea02,0x36e5, 0x26b3,0x1590, 0x08df,0x289a + .short 0xe39c,0x392b, 0x24ae,0x1709, 0x0471,0x2afb + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xd74e,0x3cc5, 0x2093,0x19ef, 0xfb8f,0x2f6c + .short 0xd178,0x3e15, 0x1e7e,0x1b5d, 0xf721,0x3179 + .short 0xcbe2,0x3f0f, 0x1c64,0x1cc6, 0xf2b8,0x3368 + .short 0xc695,0x3fb1, 0x1a46,0x1e2b, 0xee58,0x3537 + .short 0xc197,0x3ffb, 0x1824,0x1f8c, 0xea02,0x36e5 + .short 0xbcf0,0x3fec, 0x15fe,0x20e7, 0xe5ba,0x3871 + .short 0xb8a6,0x3f85, 0x13d5,0x223d, 0xe182,0x39db + .short 0xb4be,0x3ec5, 0x11a8,0x238e, 0xdd5d,0x3b21 + .short 0xb140,0x3daf, 0x0f79,0x24da, 0xd94d,0x3c42 + .short 0xae2e,0x3c42, 0x0d48,0x2620, 0xd556,0x3d3f + .short 0xab8e,0x3a82, 0x0b14,0x2760, 0xd178,0x3e15 + .short 0xa963,0x3871, 0x08df,0x289a, 0xcdb7,0x3ec5 + .short 0xa7b1,0x3612, 0x06a9,0x29ce, 0xca15,0x3f4f + .short 0xa678,0x3368, 0x0471,0x2afb, 0xc695,0x3fb1 + .short 0xa5bc,0x3076, 0x0239,0x2c21, 0xc338,0x3fec + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xa5bc,0x29ce, 0xfdc7,0x2e5a, 0xbcf0,0x3fec + .short 0xa678,0x2620, 0xfb8f,0x2f6c, 0xba09,0x3fb1 + .short 0xa7b1,0x223d, 0xf957,0x3076, 0xb74d,0x3f4f + .short 0xa963,0x1e2b, 0xf721,0x3179, 0xb4be,0x3ec5 + .short 0xab8e,0x19ef, 0xf4ec,0x3274, 0xb25e,0x3e15 + .short 0xae2e,0x1590, 0xf2b8,0x3368, 0xb02d,0x3d3f + .short 0xb140,0x1112, 0xf087,0x3453, 0xae2e,0x3c42 + .short 0xb4be,0x0c7c, 0xee58,0x3537, 0xac61,0x3b21 + .short 0xb8a6,0x07d6, 0xec2b,0x3612, 0xaac8,0x39db + .short 0xbcf0,0x0324, 0xea02,0x36e5, 0xa963,0x3871 + .short 0xc197,0xfe6e, 0xe7dc,0x37b0, 0xa834,0x36e5 + .short 0xc695,0xf9ba, 0xe5ba,0x3871, 0xa73b,0x3537 + .short 0xcbe2,0xf50f, 0xe39c,0x392b, 0xa678,0x3368 + .short 0xd178,0xf073, 0xe182,0x39db, 0xa5ed,0x3179 + .short 0xd74e,0xebed, 0xdf6d,0x3a82, 0xa599,0x2f6c + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + .short 0xe39c,0xe33a, 0xdb52,0x3bb6, 0xa599,0x2afb + .short 0xea02,0xdf19, 0xd94d,0x3c42, 0xa5ed,0x289a + .short 0xf087,0xdb26, 0xd74e,0x3cc5, 0xa678,0x2620 + .short 0xf721,0xd766, 0xd556,0x3d3f, 0xa73b,0x238e + .short 0xfdc7,0xd3df, 0xd363,0x3daf, 0xa834,0x20e7 + .short 0x0471,0xd094, 0xd178,0x3e15, 0xa963,0x1e2b + .short 0x0b14,0xcd8c, 0xcf94,0x3e72, 0xaac8,0x1b5d + .short 0x11a8,0xcac9, 0xcdb7,0x3ec5, 0xac61,0x187e + .short 0x1824,0xc850, 0xcbe2,0x3f0f, 0xae2e,0x1590 + .short 0x1e7e,0xc625, 0xca15,0x3f4f, 0xb02d,0x1294 + .short 0x24ae,0xc44a, 0xc851,0x3f85, 0xb25e,0x0f8d + .short 0x2aaa,0xc2c1, 0xc695,0x3fb1, 0xb4be,0x0c7c + .short 0x306c,0xc18e, 0xc4e2,0x3fd4, 0xb74d,0x0964 + .short 0x35eb,0xc0b1, 0xc338,0x3fec, 0xba09,0x0646 + .short 0x3b1e,0xc02c, 0xc197,0x3ffb, 0xbcf0,0x0324 + + +.end +/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F1/libraries/stm_fft/cr4_fft_64_stm32.asm b/STM32F1/libraries/stm_fft/cr4_fft_64_stm32.asm new file mode 100644 index 000000000..bff454847 --- /dev/null +++ b/STM32F1/libraries/stm_fft/cr4_fft_64_stm32.asm @@ -0,0 +1,249 @@ +/*;******************** (C) COPYRIGHT 2009 STMicroelectronics ******************** +;* File Name : cr4_fft_64_stm32.s +;* Author : MCD Application Team +;* Version : V2.0.0 +;* Date : 04/27/2009 +;* Description : Optimized 64-point radix-4 complex FFT for Cortex-M3 +;******************************************************************************** +;* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +;* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +;* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +;* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +;* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +;* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +;*******************************************************************************/ + +.cpu cortex-m3 +.fpu softvfp +.syntax unified +.thumb +.text + +.global cr4_fft_64_stm32 +.extern TableFFT + +.equ NPT, 64 + + +/*;******************************************************************************* +;* Function Name : cr4_fft_64_stm32 +;* Description : complex radix-4 64 points FFT +;* Input : - R0 = pssOUT: Output array . +;* - R1 = pssIN: Input array +;* - R2 = Nbin: =64 number of points, this optimized FFT function +;* can only convert 64 points. +;* Output : None +;* Return : None +;********************************************************************************/ +.thumb_func +cr4_fft_64_stm32: + + STMFD SP!, {R4-R11, LR} + + MOV r12, #0 + MOV r3, r0 + MOV r0,#0 + +preloop_v7: + ADD r14, r1, r12, LSR#26 + + LDRSH r5, [r14, #2] + LDRSH r4, [r14],#NPT + LDRSH r9, [r14, #2] + LDRSH r8, [r14],#NPT + LDRSH r7, [r14, #2] + LDRSH r6, [r14],#NPT + LDRSH r11, [r14, #2] + LDRSH r10, [r14],#NPT + + ADD r8, r8, r10 + ADD r9, r9, r11 + SUB r10, r8, r10, LSL#1 + SUB r11, r9, r11, LSL#1 + + MOV r4, r4, ASR#2 + MOV r5, r5, ASR#2 + ADD r4, r4, r6, ASR#2 + ADD r5, r5, r7, ASR#2 + SUB r6, r4, r6, ASR#1 + SUB r7, r5, r7, ASR#1 + + ADD r4, r4, r8, ASR#2 + ADD r5, r5, r9, ASR#2 + SUB r8, r4, r8, ASR#1 + SUB r9, r5, r9, ASR#1 + + ADD r6, r6, r11, ASR#2 + SUB r7, r7, r10, ASR#2 + SUB r11, r6, r11, ASR#1 + ADD r10, r7, r10, ASR#1 + + STRH r5, [r3, #2] + STRH r4, [r3], #4 + STRH r7, [r3, #2] + STRH r6, [r3], #4 + STRH r9, [r3, #2] + STRH r8, [r3], #4 + STRH r10, [r3, #2] + STRH r11, [r3], #4 + + ADD r0, r0, #1 + + RBIT r12, r0 + + CMP r0,#16 + BNE preloop_v7 + + SUB r1, r3, r2, LSL#2 + MOV r0, #16 + MOVS r2, r2, LSR#4 + +/*;------------------------------------------------------------------------------ +; The FFT coefficients table can be stored into Flash or RAM. +; The following two lines of code allow selecting the method for coefficients +; storage. +; In the case of choosing coefficients in RAM, you have to: +; 1. Include the file table_fft.h, which is a part of the DSP library, +; in your main file. +; 2. Decomment the line LDR.W pssK, =TableFFT and comment the line +; ADRL pssK, TableFFT_V7 +; 3. Comment all the TableFFT_V7 data. +;------------------------------------------------------------------------------*/ + ADR r3, TableFFT_V7 + /*LDR.W r3, =TableFFT*/ + + +passloop_v7: + STMFD SP!, {r1,r2} + ADD r12, r0, r0, LSL#1 + ADD r1, r1, r12 + SUB r2, r2, #1<<16 + +grouploop_v7: + ADD r2,r2,r0,LSL#(16-2) + +butterloop_v7: + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r11, [r3, #2] + LDRSH r10, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r11 + ADD r14, r10, r11, LSL#1 + MLA r11, r5, r10, r12 + MLA r10, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r9, [r3, #2] + LDRSH r8, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r9 + ADD r14, r8, r9, LSL#1 + MLA r9, r5, r8, r12 + MLA r8, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + SUB r1, r1, r0 + + LDRSH r7, [r3, #2] + LDRSH r6, [r3] + ADD r3, r3, #4 + + SUB r14, r5, r4 + MUL r12, r14, r7 + ADD r14, r6, r7, LSL#1 + MLA r7, r5, r6, r12 + MLA r6, r4, r14, r12 + + LDRSH r5, [r1, #2] + LDRSH r4, [r1] + + ADD r8, r8, r10 + ADD r9, r9, r11 + SUB r10, r8, r10, LSL#1 + SUB r11, r9, r11, LSL#1 + + MOV r4, r4, ASR#2 + MOV r5, r5, ASR#2 + ADD r4, r4, r6, ASR#(2+14) + ADD r5, r5, r7, ASR#(2+14) + SUB r6, r4, r6, ASR#(1+14) + SUB r7, r5, r7, ASR#(1+14) + + ADD r4, r4, r8, ASR#(2+14) + ADD r5, r5, r9, ASR#(2+14) + SUB r8, r4, r8, ASR#(1+14) + SUB r9, r5, r9, ASR#(1+14) + + ADD r6, r6, r11, ASR#(2+14) + SUB r7, r7, r10, ASR#(2+14) + SUB r11, r6, r11, ASR#(1+14) + ADD r10, r7, r10, ASR#(1+14) + + STRH r5, [r1, #2] + STRH r4, [r1] + ADD r1, r1, r0 + STRH r7, [r1, #2] + STRH r6, [r1] + ADD r1, r1, r0 + STRH r9, [r1, #2] + STRH r8, [r1] + ADD r1, r1, r0 + STRH r10, [r1, #2] + STRH r11, [r1], #4 + SUBS r2,r2, #1<<16 + BGE butterloop_v7 + ADD r12, r0, r0, LSL#1 + ADD r1, r1, r12 + + SUB r2, r2, #1 + MOVS r14, r2, LSL#16 + IT ne + SUBNE r3, r3, r12 + BNE grouploop_v7 + + LDMFD sp!, {r1, r2} + MOV r0,r0,LSL#2 + MOVS r2, r2, LSR#2 + BNE passloop_v7 + LDMFD SP!, {R4-R11, PC} + + +TableFFT_V7: + + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + + .short 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000 + .short 0x2aaa,0x1294, 0x396b,0x0646, 0x3249,0x0c7c + .short 0x11a8,0x238e, 0x3249,0x0c7c, 0x22a3,0x187e + .short 0xf721,0x3179, 0x2aaa,0x1294, 0x11a8,0x238e + .short 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41 + .short 0xc695,0x3fb1, 0x1a46,0x1e2b, 0xee58,0x3537 + .short 0xb4be,0x3ec5, 0x11a8,0x238e, 0xdd5d,0x3b21 + .short 0xa963,0x3871, 0x08df,0x289a, 0xcdb7,0x3ec5 + .short 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000 + .short 0xa963,0x1e2b, 0xf721,0x3179, 0xb4be,0x3ec5 + .short 0xb4be,0x0c7c, 0xee58,0x3537, 0xac61,0x3b21 + .short 0xc695,0xf9ba, 0xe5ba,0x3871, 0xa73b,0x3537 + .short 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41 + .short 0xf721,0xd766, 0xd556,0x3d3f, 0xa73b,0x238e + .short 0x11a8,0xcac9, 0xcdb7,0x3ec5, 0xac61,0x187e + .short 0x2aaa,0xc2c1, 0xc695,0x3fb1, 0xb4be,0x0c7c + + +.end +/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F1/libraries/stm_fft/cr4_fft_stm32.h b/STM32F1/libraries/stm_fft/cr4_fft_stm32.h new file mode 100644 index 000000000..a8994306f --- /dev/null +++ b/STM32F1/libraries/stm_fft/cr4_fft_stm32.h @@ -0,0 +1,39 @@ +/* + +x[N] be the time signal samples. To use the FFT functions of the DSP library, the +following conditions must be satisfied: +? All the signal samples must be 32-bit data containing the 16-bit real part followed by the +16-bit imaginary part (in the little Endian order: imaginary_real). + + +*/ + +#ifndef __STM32F10x_DSP_H +#define __STM32F10x_DSP_H +/* + * The assembly files can be modified to use a table in RAM rather than ROM. + * Check the assembly files comments. + * + * #include "table_fft.h" + */ + + +extern "C" { + +/* Radix-4 complex FFT for STM32, in assembly */ +/* 16 points*/ +void cr4_fft_16_stm32(void *pssOUT, void *pssIN, uint16_t Nbin); + +/* 64 points*/ +void cr4_fft_64_stm32(void *pssOUT, void *pssIN, uint16_t Nbin); + +/* 256 points */ +void cr4_fft_256_stm32(void *pssOUT, void *pssIN, uint16_t Nbin); + +/* 1024 points */ +void cr4_fft_1024_stm32(void *pssOUT, void *pssIN, uint16_t Nbin); + + +} + +#endif /* __STM32F10x_DSP_H */ diff --git a/STM32F1/libraries/stm_fft/stm32f10x_DSP_lib.chm b/STM32F1/libraries/stm_fft/stm32f10x_DSP_lib.chm new file mode 100644 index 000000000..a27742dfd Binary files /dev/null and b/STM32F1/libraries/stm_fft/stm32f10x_DSP_lib.chm differ diff --git a/STM32F1/libraries/stm_fft/table_fft.h b/STM32F1/libraries/stm_fft/table_fft.h new file mode 100644 index 000000000..27d3d39cc --- /dev/null +++ b/STM32F1/libraries/stm_fft/table_fft.h @@ -0,0 +1,377 @@ +/** + ****************************************************************************** + * @file STM32F10x_DSP_Lib/inc/table_fft.h + * @author MCD Application Team + * @version V2.0.0 + * @date 04/27/2009 + * @brief Contains the coefficients required for FFT computation. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2009 STMicroelectronics

+ */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TABLE_FFT_H +#define __TABLE_FFT_H + +/* Includes ------------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +uint16_t TableFFT[]= {0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000, + 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41, + 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000, + 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41, + 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000, /* N=64 */ + 0x2aaa,0x1294, 0x396b,0x0646, 0x3249,0x0c7c, + 0x11a8,0x238e, 0x3249,0x0c7c, 0x22a3,0x187e, + 0xf721,0x3179, 0x2aaa,0x1294, 0x11a8,0x238e, + 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41, + 0xc695,0x3fb1, 0x1a46,0x1e2b, 0xee58,0x3537, + 0xb4be,0x3ec5, 0x11a8,0x238e, 0xdd5d,0x3b21, + 0xa963,0x3871, 0x08df,0x289a, 0xcdb7,0x3ec5, + 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000, + 0xa963,0x1e2b, 0xf721,0x3179, 0xb4be,0x3ec5, + 0xb4be,0x0c7c, 0xee58,0x3537, 0xac61,0x3b21, + 0xc695,0xf9ba, 0xe5ba,0x3871, 0xa73b,0x3537, + 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41, + 0xf721,0xd766, 0xd556,0x3d3f, 0xa73b,0x238e, + 0x11a8,0xcac9, 0xcdb7,0x3ec5, 0xac61,0x187e, + 0x2aaa,0xc2c1, 0xc695,0x3fb1, 0xb4be,0x0c7c, + 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000, /* N=256 */ + 0x3b1e,0x04b5, 0x3e69,0x0192, 0x3cc8,0x0324, + 0x35eb,0x0964, 0x3cc8,0x0324, 0x396b,0x0646, + 0x306c,0x0e06, 0x3b1e,0x04b5, 0x35eb,0x0964, + 0x2aaa,0x1294, 0x396b,0x0646, 0x3249,0x0c7c, + 0x24ae,0x1709, 0x37af,0x07d6, 0x2e88,0x0f8d, + 0x1e7e,0x1b5d, 0x35eb,0x0964, 0x2aaa,0x1294, + 0x1824,0x1f8c, 0x341e,0x0af1, 0x26b3,0x1590, + 0x11a8,0x238e, 0x3249,0x0c7c, 0x22a3,0x187e, + 0x0b14,0x2760, 0x306c,0x0e06, 0x1e7e,0x1b5d, + 0x0471,0x2afb, 0x2e88,0x0f8d, 0x1a46,0x1e2b, + 0xfdc7,0x2e5a, 0x2c9d,0x1112, 0x15fe,0x20e7, + 0xf721,0x3179, 0x2aaa,0x1294, 0x11a8,0x238e, + 0xf087,0x3453, 0x28b2,0x1413, 0x0d48,0x2620, + 0xea02,0x36e5, 0x26b3,0x1590, 0x08df,0x289a, + 0xe39c,0x392b, 0x24ae,0x1709, 0x0471,0x2afb, + 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41, + 0xd74e,0x3cc5, 0x2093,0x19ef, 0xfb8f,0x2f6c, + 0xd178,0x3e15, 0x1e7e,0x1b5d, 0xf721,0x3179, + 0xcbe2,0x3f0f, 0x1c64,0x1cc6, 0xf2b8,0x3368, + 0xc695,0x3fb1, 0x1a46,0x1e2b, 0xee58,0x3537, + 0xc197,0x3ffb, 0x1824,0x1f8c, 0xea02,0x36e5, + 0xbcf0,0x3fec, 0x15fe,0x20e7, 0xe5ba,0x3871, + 0xb8a6,0x3f85, 0x13d5,0x223d, 0xe182,0x39db, + 0xb4be,0x3ec5, 0x11a8,0x238e, 0xdd5d,0x3b21, + 0xb140,0x3daf, 0x0f79,0x24da, 0xd94d,0x3c42, + 0xae2e,0x3c42, 0x0d48,0x2620, 0xd556,0x3d3f, + 0xab8e,0x3a82, 0x0b14,0x2760, 0xd178,0x3e15, + 0xa963,0x3871, 0x08df,0x289a, 0xcdb7,0x3ec5, + 0xa7b1,0x3612, 0x06a9,0x29ce, 0xca15,0x3f4f, + 0xa678,0x3368, 0x0471,0x2afb, 0xc695,0x3fb1, + 0xa5bc,0x3076, 0x0239,0x2c21, 0xc338,0x3fec, + 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000, + 0xa5bc,0x29ce, 0xfdc7,0x2e5a, 0xbcf0,0x3fec, + 0xa678,0x2620, 0xfb8f,0x2f6c, 0xba09,0x3fb1, + 0xa7b1,0x223d, 0xf957,0x3076, 0xb74d,0x3f4f, + 0xa963,0x1e2b, 0xf721,0x3179, 0xb4be,0x3ec5, + 0xab8e,0x19ef, 0xf4ec,0x3274, 0xb25e,0x3e15, + 0xae2e,0x1590, 0xf2b8,0x3368, 0xb02d,0x3d3f, + 0xb140,0x1112, 0xf087,0x3453, 0xae2e,0x3c42, + 0xb4be,0x0c7c, 0xee58,0x3537, 0xac61,0x3b21, + 0xb8a6,0x07d6, 0xec2b,0x3612, 0xaac8,0x39db, + 0xbcf0,0x0324, 0xea02,0x36e5, 0xa963,0x3871, + 0xc197,0xfe6e, 0xe7dc,0x37b0, 0xa834,0x36e5, + 0xc695,0xf9ba, 0xe5ba,0x3871, 0xa73b,0x3537, + 0xcbe2,0xf50f, 0xe39c,0x392b, 0xa678,0x3368, + 0xd178,0xf073, 0xe182,0x39db, 0xa5ed,0x3179, + 0xd74e,0xebed, 0xdf6d,0x3a82, 0xa599,0x2f6c, + 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41, + 0xe39c,0xe33a, 0xdb52,0x3bb6, 0xa599,0x2afb, + 0xea02,0xdf19, 0xd94d,0x3c42, 0xa5ed,0x289a, + 0xf087,0xdb26, 0xd74e,0x3cc5, 0xa678,0x2620, + 0xf721,0xd766, 0xd556,0x3d3f, 0xa73b,0x238e, + 0xfdc7,0xd3df, 0xd363,0x3daf, 0xa834,0x20e7, + 0x0471,0xd094, 0xd178,0x3e15, 0xa963,0x1e2b, + 0x0b14,0xcd8c, 0xcf94,0x3e72, 0xaac8,0x1b5d, + 0x11a8,0xcac9, 0xcdb7,0x3ec5, 0xac61,0x187e, + 0x1824,0xc850, 0xcbe2,0x3f0f, 0xae2e,0x1590, + 0x1e7e,0xc625, 0xca15,0x3f4f, 0xb02d,0x1294, + 0x24ae,0xc44a, 0xc851,0x3f85, 0xb25e,0x0f8d, + 0x2aaa,0xc2c1, 0xc695,0x3fb1, 0xb4be,0x0c7c, + 0x306c,0xc18e, 0xc4e2,0x3fd4, 0xb74d,0x0964, + 0x35eb,0xc0b1, 0xc338,0x3fec, 0xba09,0x0646, + 0x3b1e,0xc02c, 0xc197,0x3ffb, 0xbcf0,0x0324, + 0x4000,0x0000, 0x4000,0x0000, 0x4000,0x0000, /* N=1024*/ + 0x3ed0,0x012e, 0x3f9b,0x0065, 0x3f36,0x00c9, + 0x3d9a,0x025b, 0x3f36,0x00c9, 0x3e69,0x0192, + 0x3c5f,0x0388, 0x3ed0,0x012e, 0x3d9a,0x025b, + 0x3b1e,0x04b5, 0x3e69,0x0192, 0x3cc8,0x0324, + 0x39d9,0x05e2, 0x3e02,0x01f7, 0x3bf4,0x03ed, + 0x388e,0x070e, 0x3d9a,0x025b, 0x3b1e,0x04b5, + 0x373f,0x0839, 0x3d31,0x02c0, 0x3a46,0x057e, + 0x35eb,0x0964, 0x3cc8,0x0324, 0x396b,0x0646, + 0x3492,0x0a8e, 0x3c5f,0x0388, 0x388e,0x070e, + 0x3334,0x0bb7, 0x3bf4,0x03ed, 0x37af,0x07d6, + 0x31d2,0x0cdf, 0x3b8a,0x0451, 0x36ce,0x089d, + 0x306c,0x0e06, 0x3b1e,0x04b5, 0x35eb,0x0964, + 0x2f02,0x0f2b, 0x3ab2,0x051a, 0x3505,0x0a2b, + 0x2d93,0x1050, 0x3a46,0x057e, 0x341e,0x0af1, + 0x2c21,0x1173, 0x39d9,0x05e2, 0x3334,0x0bb7, + 0x2aaa,0x1294, 0x396b,0x0646, 0x3249,0x0c7c, + 0x2931,0x13b4, 0x38fd,0x06aa, 0x315b,0x0d41, + 0x27b3,0x14d2, 0x388e,0x070e, 0x306c,0x0e06, + 0x2632,0x15ee, 0x381f,0x0772, 0x2f7b,0x0eca, + 0x24ae,0x1709, 0x37af,0x07d6, 0x2e88,0x0f8d, + 0x2326,0x1821, 0x373f,0x0839, 0x2d93,0x1050, + 0x219c,0x1937, 0x36ce,0x089d, 0x2c9d,0x1112, + 0x200e,0x1a4b, 0x365d,0x0901, 0x2ba4,0x11d3, + 0x1e7e,0x1b5d, 0x35eb,0x0964, 0x2aaa,0x1294, + 0x1ceb,0x1c6c, 0x3578,0x09c7, 0x29af,0x1354, + 0x1b56,0x1d79, 0x3505,0x0a2b, 0x28b2,0x1413, + 0x19be,0x1e84, 0x3492,0x0a8e, 0x27b3,0x14d2, + 0x1824,0x1f8c, 0x341e,0x0af1, 0x26b3,0x1590, + 0x1688,0x2091, 0x33a9,0x0b54, 0x25b1,0x164c, + 0x14ea,0x2193, 0x3334,0x0bb7, 0x24ae,0x1709, + 0x134a,0x2292, 0x32bf,0x0c1a, 0x23a9,0x17c4, + 0x11a8,0x238e, 0x3249,0x0c7c, 0x22a3,0x187e, + 0x1005,0x2488, 0x31d2,0x0cdf, 0x219c,0x1937, + 0x0e61,0x257e, 0x315b,0x0d41, 0x2093,0x19ef, + 0x0cbb,0x2671, 0x30e4,0x0da4, 0x1f89,0x1aa7, + 0x0b14,0x2760, 0x306c,0x0e06, 0x1e7e,0x1b5d, + 0x096d,0x284c, 0x2ff4,0x0e68, 0x1d72,0x1c12, + 0x07c4,0x2935, 0x2f7b,0x0eca, 0x1c64,0x1cc6, + 0x061b,0x2a1a, 0x2f02,0x0f2b, 0x1b56,0x1d79, + 0x0471,0x2afb, 0x2e88,0x0f8d, 0x1a46,0x1e2b, + 0x02c7,0x2bd8, 0x2e0e,0x0fee, 0x1935,0x1edc, + 0x011c,0x2cb2, 0x2d93,0x1050, 0x1824,0x1f8c, + 0xff72,0x2d88, 0x2d18,0x10b1, 0x1711,0x203a, + 0xfdc7,0x2e5a, 0x2c9d,0x1112, 0x15fe,0x20e7, + 0xfc1d,0x2f28, 0x2c21,0x1173, 0x14ea,0x2193, + 0xfa73,0x2ff2, 0x2ba4,0x11d3, 0x13d5,0x223d, + 0xf8ca,0x30b8, 0x2b28,0x1234, 0x12bf,0x22e7, + 0xf721,0x3179, 0x2aaa,0x1294, 0x11a8,0x238e, + 0xf579,0x3236, 0x2a2d,0x12f4, 0x1091,0x2435, + 0xf3d2,0x32ef, 0x29af,0x1354, 0x0f79,0x24da, + 0xf22c,0x33a3, 0x2931,0x13b4, 0x0e61,0x257e, + 0xf087,0x3453, 0x28b2,0x1413, 0x0d48,0x2620, + 0xeee3,0x34ff, 0x2833,0x1473, 0x0c2e,0x26c1, + 0xed41,0x35a5, 0x27b3,0x14d2, 0x0b14,0x2760, + 0xeba1,0x3648, 0x2733,0x1531, 0x09fa,0x27fe, + 0xea02,0x36e5, 0x26b3,0x1590, 0x08df,0x289a, + 0xe865,0x377e, 0x2632,0x15ee, 0x07c4,0x2935, + 0xe6cb,0x3812, 0x25b1,0x164c, 0x06a9,0x29ce, + 0xe532,0x38a1, 0x252f,0x16ab, 0x058d,0x2a65, + 0xe39c,0x392b, 0x24ae,0x1709, 0x0471,0x2afb, + 0xe208,0x39b0, 0x242b,0x1766, 0x0355,0x2b8f, + 0xe077,0x3a30, 0x23a9,0x17c4, 0x0239,0x2c21, + 0xdee9,0x3aab, 0x2326,0x1821, 0x011c,0x2cb2, + 0xdd5d,0x3b21, 0x22a3,0x187e, 0x0000,0x2d41, + 0xdbd5,0x3b92, 0x221f,0x18db, 0xfee4,0x2dcf, + 0xda4f,0x3bfd, 0x219c,0x1937, 0xfdc7,0x2e5a, + 0xd8cd,0x3c64, 0x2117,0x1993, 0xfcab,0x2ee4, + 0xd74e,0x3cc5, 0x2093,0x19ef, 0xfb8f,0x2f6c, + 0xd5d3,0x3d21, 0x200e,0x1a4b, 0xfa73,0x2ff2, + 0xd45c,0x3d78, 0x1f89,0x1aa7, 0xf957,0x3076, + 0xd2e8,0x3dc9, 0x1f04,0x1b02, 0xf83c,0x30f9, + 0xd178,0x3e15, 0x1e7e,0x1b5d, 0xf721,0x3179, + 0xd00c,0x3e5c, 0x1df8,0x1bb8, 0xf606,0x31f8, + 0xcea5,0x3e9d, 0x1d72,0x1c12, 0xf4ec,0x3274, + 0xcd41,0x3ed8, 0x1ceb,0x1c6c, 0xf3d2,0x32ef, + 0xcbe2,0x3f0f, 0x1c64,0x1cc6, 0xf2b8,0x3368, + 0xca88,0x3f40, 0x1bdd,0x1d20, 0xf19f,0x33df, + 0xc932,0x3f6b, 0x1b56,0x1d79, 0xf087,0x3453, + 0xc7e1,0x3f91, 0x1ace,0x1dd3, 0xef6f,0x34c6, + 0xc695,0x3fb1, 0x1a46,0x1e2b, 0xee58,0x3537, + 0xc54e,0x3fcc, 0x19be,0x1e84, 0xed41,0x35a5, + 0xc40c,0x3fe1, 0x1935,0x1edc, 0xec2b,0x3612, + 0xc2cf,0x3ff1, 0x18ad,0x1f34, 0xeb16,0x367d, + 0xc197,0x3ffb, 0x1824,0x1f8c, 0xea02,0x36e5, + 0xc065,0x4000, 0x179b,0x1fe3, 0xe8ef,0x374b, + 0xbf38,0x3fff, 0x1711,0x203a, 0xe7dc,0x37b0, + 0xbe11,0x3ff8, 0x1688,0x2091, 0xe6cb,0x3812, + 0xbcf0,0x3fec, 0x15fe,0x20e7, 0xe5ba,0x3871, + 0xbbd4,0x3fdb, 0x1574,0x213d, 0xe4aa,0x38cf, + 0xbabf,0x3fc4, 0x14ea,0x2193, 0xe39c,0x392b, + 0xb9af,0x3fa7, 0x145f,0x21e8, 0xe28e,0x3984, + 0xb8a6,0x3f85, 0x13d5,0x223d, 0xe182,0x39db, + 0xb7a2,0x3f5d, 0x134a,0x2292, 0xe077,0x3a30, + 0xb6a5,0x3f30, 0x12bf,0x22e7, 0xdf6d,0x3a82, + 0xb5af,0x3efd, 0x1234,0x233b, 0xde64,0x3ad3, + 0xb4be,0x3ec5, 0x11a8,0x238e, 0xdd5d,0x3b21, + 0xb3d5,0x3e88, 0x111d,0x23e2, 0xdc57,0x3b6d, + 0xb2f2,0x3e45, 0x1091,0x2435, 0xdb52,0x3bb6, + 0xb215,0x3dfc, 0x1005,0x2488, 0xda4f,0x3bfd, + 0xb140,0x3daf, 0x0f79,0x24da, 0xd94d,0x3c42, + 0xb071,0x3d5b, 0x0eed,0x252c, 0xd84d,0x3c85, + 0xafa9,0x3d03, 0x0e61,0x257e, 0xd74e,0x3cc5, + 0xaee8,0x3ca5, 0x0dd4,0x25cf, 0xd651,0x3d03, + 0xae2e,0x3c42, 0x0d48,0x2620, 0xd556,0x3d3f, + 0xad7b,0x3bda, 0x0cbb,0x2671, 0xd45c,0x3d78, + 0xacd0,0x3b6d, 0x0c2e,0x26c1, 0xd363,0x3daf, + 0xac2b,0x3afa, 0x0ba1,0x2711, 0xd26d,0x3de3, + 0xab8e,0x3a82, 0x0b14,0x2760, 0xd178,0x3e15, + 0xaaf8,0x3a06, 0x0a87,0x27af, 0xd085,0x3e45, + 0xaa6a,0x3984, 0x09fa,0x27fe, 0xcf94,0x3e72, + 0xa9e3,0x38fd, 0x096d,0x284c, 0xcea5,0x3e9d, + 0xa963,0x3871, 0x08df,0x289a, 0xcdb7,0x3ec5, + 0xa8eb,0x37e1, 0x0852,0x28e7, 0xcccc,0x3eeb, + 0xa87b,0x374b, 0x07c4,0x2935, 0xcbe2,0x3f0f, + 0xa812,0x36b1, 0x0736,0x2981, 0xcafb,0x3f30, + 0xa7b1,0x3612, 0x06a9,0x29ce, 0xca15,0x3f4f, + 0xa757,0x356e, 0x061b,0x2a1a, 0xc932,0x3f6b, + 0xa705,0x34c6, 0x058d,0x2a65, 0xc851,0x3f85, + 0xa6bb,0x3419, 0x04ff,0x2ab0, 0xc772,0x3f9c, + 0xa678,0x3368, 0x0471,0x2afb, 0xc695,0x3fb1, + 0xa63e,0x32b2, 0x03e3,0x2b45, 0xc5ba,0x3fc4, + 0xa60b,0x31f8, 0x0355,0x2b8f, 0xc4e2,0x3fd4, + 0xa5e0,0x3139, 0x02c7,0x2bd8, 0xc40c,0x3fe1, + 0xa5bc,0x3076, 0x0239,0x2c21, 0xc338,0x3fec, + 0xa5a1,0x2faf, 0x01aa,0x2c6a, 0xc266,0x3ff5, + 0xa58d,0x2ee4, 0x011c,0x2cb2, 0xc197,0x3ffb, + 0xa581,0x2e15, 0x008e,0x2cfa, 0xc0ca,0x3fff, + 0xa57e,0x2d41, 0x0000,0x2d41, 0xc000,0x4000, + 0xa581,0x2c6a, 0xff72,0x2d88, 0xbf38,0x3fff, + 0xa58d,0x2b8f, 0xfee4,0x2dcf, 0xbe73,0x3ffb, + 0xa5a1,0x2ab0, 0xfe56,0x2e15, 0xbdb0,0x3ff5, + 0xa5bc,0x29ce, 0xfdc7,0x2e5a, 0xbcf0,0x3fec, + 0xa5e0,0x28e7, 0xfd39,0x2e9f, 0xbc32,0x3fe1, + 0xa60b,0x27fe, 0xfcab,0x2ee4, 0xbb77,0x3fd4, + 0xa63e,0x2711, 0xfc1d,0x2f28, 0xbabf,0x3fc4, + 0xa678,0x2620, 0xfb8f,0x2f6c, 0xba09,0x3fb1, + 0xa6bb,0x252c, 0xfb01,0x2faf, 0xb956,0x3f9c, + 0xa705,0x2435, 0xfa73,0x2ff2, 0xb8a6,0x3f85, + 0xa757,0x233b, 0xf9e5,0x3034, 0xb7f8,0x3f6b, + 0xa7b1,0x223d, 0xf957,0x3076, 0xb74d,0x3f4f, + 0xa812,0x213d, 0xf8ca,0x30b8, 0xb6a5,0x3f30, + 0xa87b,0x203a, 0xf83c,0x30f9, 0xb600,0x3f0f, + 0xa8eb,0x1f34, 0xf7ae,0x3139, 0xb55e,0x3eeb, + 0xa963,0x1e2b, 0xf721,0x3179, 0xb4be,0x3ec5, + 0xa9e3,0x1d20, 0xf693,0x31b9, 0xb422,0x3e9d, + 0xaa6a,0x1c12, 0xf606,0x31f8, 0xb388,0x3e72, + 0xaaf8,0x1b02, 0xf579,0x3236, 0xb2f2,0x3e45, + 0xab8e,0x19ef, 0xf4ec,0x3274, 0xb25e,0x3e15, + 0xac2b,0x18db, 0xf45f,0x32b2, 0xb1cd,0x3de3, + 0xacd0,0x17c4, 0xf3d2,0x32ef, 0xb140,0x3daf, + 0xad7b,0x16ab, 0xf345,0x332c, 0xb0b5,0x3d78, + 0xae2e,0x1590, 0xf2b8,0x3368, 0xb02d,0x3d3f, + 0xaee8,0x1473, 0xf22c,0x33a3, 0xafa9,0x3d03, + 0xafa9,0x1354, 0xf19f,0x33df, 0xaf28,0x3cc5, + 0xb071,0x1234, 0xf113,0x3419, 0xaea9,0x3c85, + 0xb140,0x1112, 0xf087,0x3453, 0xae2e,0x3c42, + 0xb215,0x0fee, 0xeffb,0x348d, 0xadb6,0x3bfd, + 0xb2f2,0x0eca, 0xef6f,0x34c6, 0xad41,0x3bb6, + 0xb3d5,0x0da4, 0xeee3,0x34ff, 0xacd0,0x3b6d, + 0xb4be,0x0c7c, 0xee58,0x3537, 0xac61,0x3b21, + 0xb5af,0x0b54, 0xedcc,0x356e, 0xabf6,0x3ad3, + 0xb6a5,0x0a2b, 0xed41,0x35a5, 0xab8e,0x3a82, + 0xb7a2,0x0901, 0xecb6,0x35dc, 0xab29,0x3a30, + 0xb8a6,0x07d6, 0xec2b,0x3612, 0xaac8,0x39db, + 0xb9af,0x06aa, 0xeba1,0x3648, 0xaa6a,0x3984, + 0xbabf,0x057e, 0xeb16,0x367d, 0xaa0f,0x392b, + 0xbbd4,0x0451, 0xea8c,0x36b1, 0xa9b7,0x38cf, + 0xbcf0,0x0324, 0xea02,0x36e5, 0xa963,0x3871, + 0xbe11,0x01f7, 0xe978,0x3718, 0xa912,0x3812, + 0xbf38,0x00c9, 0xe8ef,0x374b, 0xa8c5,0x37b0, + 0xc065,0xff9b, 0xe865,0x377e, 0xa87b,0x374b, + 0xc197,0xfe6e, 0xe7dc,0x37b0, 0xa834,0x36e5, + 0xc2cf,0xfd40, 0xe753,0x37e1, 0xa7f1,0x367d, + 0xc40c,0xfc13, 0xe6cb,0x3812, 0xa7b1,0x3612, + 0xc54e,0xfae6, 0xe642,0x3842, 0xa774,0x35a5, + 0xc695,0xf9ba, 0xe5ba,0x3871, 0xa73b,0x3537, + 0xc7e1,0xf88e, 0xe532,0x38a1, 0xa705,0x34c6, + 0xc932,0xf763, 0xe4aa,0x38cf, 0xa6d3,0x3453, + 0xca88,0xf639, 0xe423,0x38fd, 0xa6a4,0x33df, + 0xcbe2,0xf50f, 0xe39c,0x392b, 0xa678,0x3368, + 0xcd41,0xf3e6, 0xe315,0x3958, 0xa650,0x32ef, + 0xcea5,0xf2bf, 0xe28e,0x3984, 0xa62c,0x3274, + 0xd00c,0xf198, 0xe208,0x39b0, 0xa60b,0x31f8, + 0xd178,0xf073, 0xe182,0x39db, 0xa5ed,0x3179, + 0xd2e8,0xef4f, 0xe0fc,0x3a06, 0xa5d3,0x30f9, + 0xd45c,0xee2d, 0xe077,0x3a30, 0xa5bc,0x3076, + 0xd5d3,0xed0c, 0xdff2,0x3a59, 0xa5a9,0x2ff2, + 0xd74e,0xebed, 0xdf6d,0x3a82, 0xa599,0x2f6c, + 0xd8cd,0xeacf, 0xdee9,0x3aab, 0xa58d,0x2ee4, + 0xda4f,0xe9b4, 0xde64,0x3ad3, 0xa585,0x2e5a, + 0xdbd5,0xe89a, 0xdde1,0x3afa, 0xa57f,0x2dcf, + 0xdd5d,0xe782, 0xdd5d,0x3b21, 0xa57e,0x2d41, + 0xdee9,0xe66d, 0xdcda,0x3b47, 0xa57f,0x2cb2, + 0xe077,0xe559, 0xdc57,0x3b6d, 0xa585,0x2c21, + 0xe208,0xe448, 0xdbd5,0x3b92, 0xa58d,0x2b8f, + 0xe39c,0xe33a, 0xdb52,0x3bb6, 0xa599,0x2afb, + 0xe532,0xe22d, 0xdad1,0x3bda, 0xa5a9,0x2a65, + 0xe6cb,0xe124, 0xda4f,0x3bfd, 0xa5bc,0x29ce, + 0xe865,0xe01d, 0xd9ce,0x3c20, 0xa5d3,0x2935, + 0xea02,0xdf19, 0xd94d,0x3c42, 0xa5ed,0x289a, + 0xeba1,0xde18, 0xd8cd,0x3c64, 0xa60b,0x27fe, + 0xed41,0xdd19, 0xd84d,0x3c85, 0xa62c,0x2760, + 0xeee3,0xdc1e, 0xd7cd,0x3ca5, 0xa650,0x26c1, + 0xf087,0xdb26, 0xd74e,0x3cc5, 0xa678,0x2620, + 0xf22c,0xda31, 0xd6cf,0x3ce4, 0xa6a4,0x257e, + 0xf3d2,0xd93f, 0xd651,0x3d03, 0xa6d3,0x24da, + 0xf579,0xd851, 0xd5d3,0x3d21, 0xa705,0x2435, + 0xf721,0xd766, 0xd556,0x3d3f, 0xa73b,0x238e, + 0xf8ca,0xd67f, 0xd4d8,0x3d5b, 0xa774,0x22e7, + 0xfa73,0xd59b, 0xd45c,0x3d78, 0xa7b1,0x223d, + 0xfc1d,0xd4bb, 0xd3df,0x3d93, 0xa7f1,0x2193, + 0xfdc7,0xd3df, 0xd363,0x3daf, 0xa834,0x20e7, + 0xff72,0xd306, 0xd2e8,0x3dc9, 0xa87b,0x203a, + 0x011c,0xd231, 0xd26d,0x3de3, 0xa8c5,0x1f8c, + 0x02c7,0xd161, 0xd1f2,0x3dfc, 0xa912,0x1edc, + 0x0471,0xd094, 0xd178,0x3e15, 0xa963,0x1e2b, + 0x061b,0xcfcc, 0xd0fe,0x3e2d, 0xa9b7,0x1d79, + 0x07c4,0xcf07, 0xd085,0x3e45, 0xaa0f,0x1cc6, + 0x096d,0xce47, 0xd00c,0x3e5c, 0xaa6a,0x1c12, + 0x0b14,0xcd8c, 0xcf94,0x3e72, 0xaac8,0x1b5d, + 0x0cbb,0xccd4, 0xcf1c,0x3e88, 0xab29,0x1aa7, + 0x0e61,0xcc21, 0xcea5,0x3e9d, 0xab8e,0x19ef, + 0x1005,0xcb73, 0xce2e,0x3eb1, 0xabf6,0x1937, + 0x11a8,0xcac9, 0xcdb7,0x3ec5, 0xac61,0x187e, + 0x134a,0xca24, 0xcd41,0x3ed8, 0xacd0,0x17c4, + 0x14ea,0xc983, 0xcccc,0x3eeb, 0xad41,0x1709, + 0x1688,0xc8e8, 0xcc57,0x3efd, 0xadb6,0x164c, + 0x1824,0xc850, 0xcbe2,0x3f0f, 0xae2e,0x1590, + 0x19be,0xc7be, 0xcb6e,0x3f20, 0xaea9,0x14d2, + 0x1b56,0xc731, 0xcafb,0x3f30, 0xaf28,0x1413, + 0x1ceb,0xc6a8, 0xca88,0x3f40, 0xafa9,0x1354, + 0x1e7e,0xc625, 0xca15,0x3f4f, 0xb02d,0x1294, + 0x200e,0xc5a7, 0xc9a3,0x3f5d, 0xb0b5,0x11d3, + 0x219c,0xc52d, 0xc932,0x3f6b, 0xb140,0x1112, + 0x2326,0xc4b9, 0xc8c1,0x3f78, 0xb1cd,0x1050, + 0x24ae,0xc44a, 0xc851,0x3f85, 0xb25e,0x0f8d, + 0x2632,0xc3e0, 0xc7e1,0x3f91, 0xb2f2,0x0eca, + 0x27b3,0xc37b, 0xc772,0x3f9c, 0xb388,0x0e06, + 0x2931,0xc31c, 0xc703,0x3fa7, 0xb422,0x0d41, + 0x2aaa,0xc2c1, 0xc695,0x3fb1, 0xb4be,0x0c7c, + 0x2c21,0xc26d, 0xc627,0x3fbb, 0xb55e,0x0bb7, + 0x2d93,0xc21d, 0xc5ba,0x3fc4, 0xb600,0x0af1, + 0x2f02,0xc1d3, 0xc54e,0x3fcc, 0xb6a5,0x0a2b, + 0x306c,0xc18e, 0xc4e2,0x3fd4, 0xb74d,0x0964, + 0x31d2,0xc14f, 0xc476,0x3fdb, 0xb7f8,0x089d, + 0x3334,0xc115, 0xc40c,0x3fe1, 0xb8a6,0x07d6, + 0x3492,0xc0e0, 0xc3a1,0x3fe7, 0xb956,0x070e, + 0x35eb,0xc0b1, 0xc338,0x3fec, 0xba09,0x0646, + 0x373f,0xc088, 0xc2cf,0x3ff1, 0xbabf,0x057e, + 0x388e,0xc064, 0xc266,0x3ff5, 0xbb77,0x04b5, + 0x39d9,0xc045, 0xc1fe,0x3ff8, 0xbc32,0x03ed, + 0x3b1e,0xc02c, 0xc197,0x3ffb, 0xbcf0,0x0324, + 0x3c5f,0xc019, 0xc130,0x3ffd, 0xbdb0,0x025b, + 0x3d9a,0xc00b, 0xc0ca,0x3fff, 0xbe73,0x0192, + 0x3ed0,0xc003, 0xc065,0x4000, 0xbf38,0x00c9 +}; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* __TABLE_FFT_H */ + +/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb.c b/STM32F1/libraries/usb.c similarity index 95% rename from STM32F3/cores/maple/libmaple/usb/usb.c rename to STM32F1/libraries/usb.c index f694f04f9..f7965351a 100644 --- a/STM32F3/cores/maple/libmaple/usb/usb.c +++ b/STM32F1/libraries/usb.c @@ -183,10 +183,25 @@ static void usb_resume(RESUME_STATE eResumeSetVal) { } } +// JMD : default ISRs of CAN, to be overridden if HardwareCAN library is used in sketch +void __attribute__((weak)) USB_HP_CAN_TX_IRQHandler(void) +{ ; } // Dummy ISR + +void __irq_usb_hp_can_tx(void) +{ + USB_HP_CAN_TX_IRQHandler () ; +} + +uint8 __attribute__((weak)) CAN_RX0_IRQ_Handler(void) +{ return 0 ; } // Dummy ISR + #define SUSPEND_ENABLED 1 void __irq_usb_lp_can_rx0(void) { uint16 istr = USB_BASE->ISTR; + if (CAN_RX0_IRQ_Handler()) //! JMD : Call to CAN ISR, returns 1 CAN is active + return; //! JMD + /* Use USB_ISR_MSK to only include code for bits we care about. */ #if (USB_ISR_MSK & USB_ISTR_RESET) @@ -210,7 +225,7 @@ void __irq_usb_lp_can_rx0(void) { #if (USB_ISR_MSK & USB_ISTR_WKUP) if (istr & USB_ISTR_WKUP & USBLIB->irq_mask) { - USB_BASE->ISTR = ~USB_ISTR_WKUP; + USB_BASE->ISTR = ~(USB_ISTR_WKUP | USB_ISTR_SUSP); usb_resume(RESUME_EXTERNAL); } #endif @@ -225,7 +240,7 @@ void __irq_usb_lp_can_rx0(void) { usb_resume(RESUME_LATER); } /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ - USB_BASE->ISTR = ~USB_ISTR_SUSP; + USB_BASE->ISTR = ~(USB_ISTR_WKUP | USB_ISTR_SUSP); } #endif diff --git a/STM32F1/platform.txt b/STM32F1/platform.txt index de1f206dc..cb5c43c1a 100644 --- a/STM32F1/platform.txt +++ b/STM32F1/platform.txt @@ -3,7 +3,7 @@ # For more info: # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification -name=STM32 Boards (STM32duino.com) +name=STM32F1 Boards (Arduino_STM32) version=0.1.2 compiler.warning_flags=-w -DDEBUG_LEVEL=DEBUG_NONE @@ -22,7 +22,7 @@ compiler.c.elf.flags={build.flags.optimize} -Wl,--gc-sections {build.flags.ldspe compiler.S.cmd=arm-none-eabi-gcc compiler.S.flags=-c -g -x assembler-with-cpp -MMD compiler.cpp.cmd=arm-none-eabi-g++ -compiler.cpp.flags=-c -g {build.flags.optimize} {compiler.warning_flags} -std=gnu++11 -MMD -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -DBOARD_{build.variant} -D{build.vect} -DERROR_LED_PORT={build.error_led_port} -DERROR_LED_PIN={build.error_led_pin} +compiler.cpp.flags=-c -g {build.flags.optimize} {compiler.warning_flags} -std=gnu++11 -MMD -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -fno-use-cxa-atexit -DBOARD_{build.variant} -D{build.vect} -DERROR_LED_PORT={build.error_led_port} -DERROR_LED_PIN={build.error_led_pin} compiler.ar.cmd=arm-none-eabi-ar compiler.ar.flags=rcs compiler.objcopy.cmd=arm-none-eabi-objcopy @@ -36,7 +36,7 @@ compiler.define=-DARDUINO= # this can be overriden in boards.txt build.f_cpu=72000000L build.mcu=cortex-m3 -build.common_flags=-mthumb -march=armv7-m -D__STM32F1__ +build.common_flags=-mthumb -march=armv7-m -D__STM32F1__ build.variant_system_lib=libmaple.a ## LED stuff is not really used but is still required in the code build.error_led_port=GPIOB @@ -44,6 +44,8 @@ build.error_led_pin=1 build.cpu_flags= build.hs_flag= build.upload_flags= +build.flags.optimize=-Os +build.flags.ldspecs=--specs=nano.specs build.extra_flags= {build.upload_flags} {build.cpu_flags} {build.hs_flag} {build.common_flags} @@ -57,7 +59,7 @@ compiler.ar.extra_flags= compiler.elf2hex.extra_flags= -compiler.libs.c.flags="-I{build.system.path}/libmaple" "-I{build.system.path}/libmaple/include" "-I{build.system.path}/libmaple/stm32f1/include" "-I{build.system.path}/libmaple/usb/stm32f1" "-I{build.system.path}/libmaple/usb/usb_lib" +compiler.libs.c.flags="-I{build.system.path}/libmaple" "-I{build.system.path}/libmaple/include" "-I{build.system.path}/libmaple/stm32f1/include" "-I{build.system.path}/libmaple/usb/stm32f1" "-I{build.system.path}/libmaple/usb/usb_lib" @@ -87,7 +89,7 @@ recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mcpu={b recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} "{build.path}/{archive_file}" -Wl,--end-group +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} "{archive_file_path}" -Wl,--end-group ## Create eeprom recipe.objcopy.eep.pattern= @@ -116,7 +118,7 @@ tools.maple_upload.path.linux={runtime.hardware.path}/tools/linux tools.maple_upload.path.linux64={runtime.hardware.path}/tools/linux64 tools.maple_upload.upload.params.verbose=-d tools.maple_upload.upload.params.quiet= -tools.maple_upload.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}.bin" +tools.maple_upload.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}.bin" "{runtime.ide.path}" #Added tool for generic STM32 upload via serial to Serial Port 1 (pins PA9 and PA10) - note. Boot0 line needs to high on board reset to enable upload via serial # at the end up the upload the program is automatically run, without the board being reset @@ -141,7 +143,7 @@ tools.stlink_upload.path.linux={runtime.hardware.path}/tools/linux tools.stlink_upload.path.linux64={runtime.hardware.path}/tools/linux64 tools.stlink_upload.upload.params.verbose=-d tools.stlink_upload.upload.params.quiet= -tools.stlink_upload.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}.bin" +tools.stlink_upload.upload.pattern="{path}/{cmd}" "{build.path}/{build.project_name}.bin" # blackmagic probe upload tools.bmp_upload.cmd=arm-none-eabi-gdb @@ -160,4 +162,16 @@ tools.jlink_upload.path.linux={runtime.hardware.path}/tools/linux tools.jlink_upload.path.linux64={runtime.hardware.path}/tools/linux64 tools.jlink_upload.upload.params.verbose=-d tools.jlink_upload.upload.params.quiet=n -tools.jlink_upload.upload.pattern="{path}/{cmd}" "{build.path}/{build.project_name}.bin" \ No newline at end of file +tools.jlink_upload.upload.pattern="{path}/{cmd}" "{build.path}/{build.project_name}.bin" + +# HID upload 2.0 +tools.hid_upload.cmd=hid_upload +tools.hid_upload.cmd.windows=hid-flash.exe +tools.hid_upload.cmd.macosx=hid_flash +tools.hid_upload.path={runtime.hardware.path}/tools/win +tools.hid_upload.path.macosx={runtime.hardware.path}/tools/macosx +tools.hid_upload.path.linux={runtime.hardware.path}/tools/linux +tools.hid_upload.path.linux64={runtime.hardware.path}/tools/linux64 +tools.hid_upload.upload.params.verbose=-d +tools.hid_upload.upload.params.quiet=n +tools.hid_upload.upload.pattern="{path}/{cmd}" "{build.path}/{build.project_name}.bin" {serial.port.file} diff --git a/STM32F1/system/libmaple/dma_private.h b/STM32F1/system/libmaple/dma_private.h index f3765fcff..80a8ce459 100644 --- a/STM32F1/system/libmaple/dma_private.h +++ b/STM32F1/system/libmaple/dma_private.h @@ -37,13 +37,13 @@ /* Wrap this in an ifdef to shut up GCC. (We provide DMA_GET_HANDLER * in the series support files, which need dma_irq_handler().) */ #ifdef DMA_GET_HANDLER -static inline __always_inline void dma_irq_handler(dma_dev *dev, dma_tube tube) { - +static inline void dma_irq_handler(dma_dev *dev, dma_tube tube) +{ void (*handler)(void) = DMA_GET_HANDLER(dev, tube); if (handler) { handler(); - dma_clear_isr_bits(dev, tube); /* in case handler doesn't */ } + dma_clear_isr_bits(dev, tube); /* in case handler doesn't */ } #endif @@ -57,6 +57,6 @@ enum dma_atype { DMA_ATYPE_OTHER, }; -enum dma_atype _dma_addr_type(__io void *addr); +enum dma_atype _dma_addr_type(__IO void *addr); #endif diff --git a/STM32F1/system/libmaple/exti_private.h b/STM32F1/system/libmaple/exti_private.h index 4f0a4cf9c..221cae454 100644 --- a/STM32F1/system/libmaple/exti_private.h +++ b/STM32F1/system/libmaple/exti_private.h @@ -29,6 +29,6 @@ #include -void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port); +void exti_do_select(__IO uint32 *exti_cr, exti_num num, exti_cfg port); #endif diff --git a/STM32F1/system/libmaple/i2c_private.h b/STM32F1/system/libmaple/i2c_private.h index 5b79516c2..ef811bd03 100644 --- a/STM32F1/system/libmaple/i2c_private.h +++ b/STM32F1/system/libmaple/i2c_private.h @@ -33,30 +33,48 @@ #define I2C_DEV_OLD(num, port, sda, scl) \ { \ .regs = I2C##num##_BASE, \ + .msg = NULL, \ + .error_flags = 0, \ + .timestamp = 0, \ .gpio_port = port, \ - .scl_port = NULL, \ .sda_port = NULL, \ + .scl_port = NULL, \ + .msgs_left = 0, \ .sda_pin = sda, \ .scl_pin = scl, \ .clk_id = RCC_I2C##num, \ .ev_nvic_line = NVIC_I2C##num##_EV, \ .er_nvic_line = NVIC_I2C##num##_ER, \ .state = I2C_STATE_DISABLED, \ + .config_flags = 0, \ + .i2c_slave_xmit_callback = NULL, \ + .i2c_slave_recv_callback = NULL, \ + .i2c_slave_xmit_msg = NULL, \ + .i2c_slave_recv_msg = NULL, \ } /* For new-style definitions (SDA/SCL may be on different GPIO devices) */ #define I2C_DEV_NEW(num, sdaport, sdabit, sclport, sclbit) \ { \ .regs = I2C##num##_BASE, \ + .msg = NULL, \ + .error_flags = 0, \ + .timestamp = 0, \ .gpio_port = NULL, \ - .scl_port = sclport, \ - .scl_pin = sclbit, \ .sda_port = sdaport, \ + .scl_port = sclport, \ + .msgs_left = 0, \ .sda_pin = sdabit, \ + .scl_pin = sclbit, \ .clk_id = RCC_I2C##num, \ .ev_nvic_line = NVIC_I2C##num##_EV, \ .er_nvic_line = NVIC_I2C##num##_ER, \ .state = I2C_STATE_DISABLED, \ + .config_flags = 0, \ + .i2c_slave_xmit_callback = NULL, \ + .i2c_slave_recv_callback = NULL, \ + .i2c_slave_xmit_msg = NULL, \ + .i2c_slave_recv_msg = NULL, \ } void _i2c_irq_handler(i2c_dev *dev); @@ -72,8 +90,4 @@ static inline struct gpio_dev* sda_port(const i2c_dev *dev) { return (dev->gpio_port == NULL) ? dev->sda_port : dev->gpio_port; } -/* Auxiliary procedure for enabling an I2C peripheral; `flags' as for - * i2c_master_enable(). */ -void _i2c_set_ccr_trise(i2c_dev *dev, uint32 flags); - #endif /* _LIBMAPLE_I2C_PRIVATE_H_ */ diff --git a/STM32F1/system/libmaple/include/libmaple/adc.h b/STM32F1/system/libmaple/include/libmaple/adc.h index 21efaf55b..9190099cd 100644 --- a/STM32F1/system/libmaple/include/libmaple/adc.h +++ b/STM32F1/system/libmaple/include/libmaple/adc.h @@ -52,26 +52,26 @@ extern "C"{ /** ADC register map type. */ typedef struct adc_reg_map { - __io uint32 SR; ///< Status register - __io uint32 CR1; ///< Control register 1 - __io uint32 CR2; ///< Control register 2 - __io uint32 SMPR1; ///< Sample time register 1 - __io uint32 SMPR2; ///< Sample time register 2 - __io uint32 JOFR1; ///< Injected channel data offset register 1 - __io uint32 JOFR2; ///< Injected channel data offset register 2 - __io uint32 JOFR3; ///< Injected channel data offset register 3 - __io uint32 JOFR4; ///< Injected channel data offset register 4 - __io uint32 HTR; ///< Watchdog high threshold register - __io uint32 LTR; ///< Watchdog low threshold register - __io uint32 SQR1; ///< Regular sequence register 1 - __io uint32 SQR2; ///< Regular sequence register 2 - __io uint32 SQR3; ///< Regular sequence register 3 - __io uint32 JSQR; ///< Injected sequence register - __io uint32 JDR1; ///< Injected data register 1 - __io uint32 JDR2; ///< Injected data register 2 - __io uint32 JDR3; ///< Injected data register 3 - __io uint32 JDR4; ///< Injected data register 4 - __io uint32 DR; ///< Regular data register + __IO uint32 SR; ///< Status register + __IO uint32 CR1; ///< Control register 1 + __IO uint32 CR2; ///< Control register 2 + __IO uint32 SMPR1; ///< Sample time register 1 + __IO uint32 SMPR2; ///< Sample time register 2 + __IO uint32 JOFR1; ///< Injected channel data offset register 1 + __IO uint32 JOFR2; ///< Injected channel data offset register 2 + __IO uint32 JOFR3; ///< Injected channel data offset register 3 + __IO uint32 JOFR4; ///< Injected channel data offset register 4 + __IO uint32 HTR; ///< Watchdog high threshold register + __IO uint32 LTR; ///< Watchdog low threshold register + __IO uint32 SQR1; ///< Regular sequence register 1 + __IO uint32 SQR2; ///< Regular sequence register 2 + __IO uint32 SQR3; ///< Regular sequence register 3 + __IO uint32 JSQR; ///< Injected sequence register + __IO uint32 JDR1; ///< Injected data register 1 + __IO uint32 JDR2; ///< Injected data register 2 + __IO uint32 JDR3; ///< Injected data register 3 + __IO uint32 JDR4; ///< Injected data register 4 + __IO uint32 DR; ///< Regular data register } adc_reg_map; diff --git a/STM32F1/system/libmaple/include/libmaple/atomic.h b/STM32F1/system/libmaple/include/libmaple/atomic.h deleted file mode 100644 index db5e48975..000000000 --- a/STM32F1/system/libmaple/include/libmaple/atomic.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -* This is port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3 -* v1.0 -* Mark Pendrith, Nov 27, 2012. -* -* From Mark: -* >When I ported the macros I emailed Dean to ask what attribution would be -* >appropriate, and here is his response: -* > -* >>Mark, -* >>I think it's great that you've ported the macros; consider them -* >>public domain, to do with whatever you wish. I hope you find them useful. -* >> -* >>Cheers! -* >>- Dean -*/ - -#ifndef _CORTEX_M3_ATOMIC_H_ -#define _CORTEX_M3_ATOMIC_H_ - -static __inline__ uint32_t __get_primask(void) \ -{ uint32_t primask = 0; \ - __asm__ volatile ("MRS %[result], PRIMASK\n\t":[result]"=r"(primask)::); \ - return primask; } // returns 0 if interrupts enabled, 1 if disabled - -static __inline__ void __set_primask(uint32_t setval) \ -{ __asm__ volatile ("MSR PRIMASK, %[value]\n\t""dmb\n\t""dsb\n\t""isb\n\t"::[value]"r"(setval):); \ - __asm__ volatile ("" ::: "memory");} - -static __inline__ uint32_t __iSeiRetVal(void) \ -{ __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ - __asm__ volatile ("" ::: "memory"); return 1; } - -static __inline__ uint32_t __iCliRetVal(void) \ -{ __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ - __asm__ volatile ("" ::: "memory"); return 1; } - -static __inline__ void __iSeiParam(const uint32_t *__s) \ -{ __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ - __asm__ volatile ("" ::: "memory"); (void)__s; } - -static __inline__ void __iCliParam(const uint32_t *__s) \ -{ __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ - __asm__ volatile ("" ::: "memory"); (void)__s; } - -static __inline__ void __iRestore(const uint32_t *__s) \ -{ __set_primask(*__s); __asm__ volatile ("dmb\n\t""dsb\n\t""isb\n\t"); \ - __asm__ volatile ("" ::: "memory"); } - - -#define ATOMIC_BLOCK(type) \ -for ( type, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 ) - -#define ATOMIC_RESTORESTATE \ -uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask() - -#define ATOMIC_FORCEON \ -uint32_t primask_save __attribute__((__cleanup__(__iSeiParam))) = 0 - -#define NONATOMIC_BLOCK(type) \ -for ( type, __ToDo = __iSeiRetVal(); __ToDo ; __ToDo = 0 ) - -#define NONATOMIC_RESTORESTATE \ -uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask() - -#define NONATOMIC_FORCEOFF \ -uint32_t primask_save __attribute__((__cleanup__(__iCliParam))) = 0 - -#endif diff --git a/STM32F1/system/libmaple/include/libmaple/bkp.h b/STM32F1/system/libmaple/include/libmaple/bkp.h index bb63a2ffd..f57235a6a 100644 --- a/STM32F1/system/libmaple/include/libmaple/bkp.h +++ b/STM32F1/system/libmaple/include/libmaple/bkp.h @@ -47,54 +47,54 @@ extern "C" { /** Backup peripheral register map type. */ typedef struct bkp_reg_map { const uint32 RESERVED1; ///< Reserved - __io uint32 DR1; ///< Data register 1 - __io uint32 DR2; ///< Data register 2 - __io uint32 DR3; ///< Data register 3 - __io uint32 DR4; ///< Data register 4 - __io uint32 DR5; ///< Data register 5 - __io uint32 DR6; ///< Data register 6 - __io uint32 DR7; ///< Data register 7 - __io uint32 DR8; ///< Data register 8 - __io uint32 DR9; ///< Data register 9 - __io uint32 DR10; ///< Data register 10 - __io uint32 RTCCR; ///< RTC control register - __io uint32 CR; ///< Control register - __io uint32 CSR; ///< Control and status register + __IO uint32 DR1; ///< Data register 1 + __IO uint32 DR2; ///< Data register 2 + __IO uint32 DR3; ///< Data register 3 + __IO uint32 DR4; ///< Data register 4 + __IO uint32 DR5; ///< Data register 5 + __IO uint32 DR6; ///< Data register 6 + __IO uint32 DR7; ///< Data register 7 + __IO uint32 DR8; ///< Data register 8 + __IO uint32 DR9; ///< Data register 9 + __IO uint32 DR10; ///< Data register 10 + __IO uint32 RTCCR; ///< RTC control register + __IO uint32 CR; ///< Control register + __IO uint32 CSR; ///< Control and status register #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) const uint32 RESERVED2; ///< Reserved const uint32 RESERVED3; ///< Reserved - __io uint32 DR11; ///< Data register 11 - __io uint32 DR12; ///< Data register 12 - __io uint32 DR13; ///< Data register 13 - __io uint32 DR14; ///< Data register 14 - __io uint32 DR15; ///< Data register 15 - __io uint32 DR16; ///< Data register 16 - __io uint32 DR17; ///< Data register 17 - __io uint32 DR18; ///< Data register 18 - __io uint32 DR19; ///< Data register 19 - __io uint32 DR20; ///< Data register 20 - __io uint32 DR21; ///< Data register 21 - __io uint32 DR22; ///< Data register 22 - __io uint32 DR23; ///< Data register 23 - __io uint32 DR24; ///< Data register 24 - __io uint32 DR25; ///< Data register 25 - __io uint32 DR26; ///< Data register 26 - __io uint32 DR27; ///< Data register 27 - __io uint32 DR28; ///< Data register 28 - __io uint32 DR29; ///< Data register 29 - __io uint32 DR30; ///< Data register 30 - __io uint32 DR31; ///< Data register 31 - __io uint32 DR32; ///< Data register 32 - __io uint32 DR33; ///< Data register 33 - __io uint32 DR34; ///< Data register 34 - __io uint32 DR35; ///< Data register 35 - __io uint32 DR36; ///< Data register 36 - __io uint32 DR37; ///< Data register 37 - __io uint32 DR38; ///< Data register 38 - __io uint32 DR39; ///< Data register 39 - __io uint32 DR40; ///< Data register 40 - __io uint32 DR41; ///< Data register 41 - __io uint32 DR42; ///< Data register 42 + __IO uint32 DR11; ///< Data register 11 + __IO uint32 DR12; ///< Data register 12 + __IO uint32 DR13; ///< Data register 13 + __IO uint32 DR14; ///< Data register 14 + __IO uint32 DR15; ///< Data register 15 + __IO uint32 DR16; ///< Data register 16 + __IO uint32 DR17; ///< Data register 17 + __IO uint32 DR18; ///< Data register 18 + __IO uint32 DR19; ///< Data register 19 + __IO uint32 DR20; ///< Data register 20 + __IO uint32 DR21; ///< Data register 21 + __IO uint32 DR22; ///< Data register 22 + __IO uint32 DR23; ///< Data register 23 + __IO uint32 DR24; ///< Data register 24 + __IO uint32 DR25; ///< Data register 25 + __IO uint32 DR26; ///< Data register 26 + __IO uint32 DR27; ///< Data register 27 + __IO uint32 DR28; ///< Data register 28 + __IO uint32 DR29; ///< Data register 29 + __IO uint32 DR30; ///< Data register 30 + __IO uint32 DR31; ///< Data register 31 + __IO uint32 DR32; ///< Data register 32 + __IO uint32 DR33; ///< Data register 33 + __IO uint32 DR34; ///< Data register 34 + __IO uint32 DR35; ///< Data register 35 + __IO uint32 DR36; ///< Data register 36 + __IO uint32 DR37; ///< Data register 37 + __IO uint32 DR38; ///< Data register 38 + __IO uint32 DR39; ///< Data register 39 + __IO uint32 DR40; ///< Data register 40 + __IO uint32 DR41; ///< Data register 41 + __IO uint32 DR42; ///< Data register 42 #endif } bkp_reg_map; diff --git a/STM32F1/system/libmaple/include/libmaple/delay.h b/STM32F1/system/libmaple/include/libmaple/delay.h index 472a208aa..64bb51005 100644 --- a/STM32F1/system/libmaple/include/libmaple/delay.h +++ b/STM32F1/system/libmaple/include/libmaple/delay.h @@ -46,6 +46,10 @@ extern "C" { * @param us Number of microseconds to delay. */ static inline void delay_us(uint32 us) { + if (us==0) + { + return; + } us *= STM32_DELAY_US_MULT; /* fudge for function call overhead */ diff --git a/STM32F1/system/libmaple/include/libmaple/dma.h b/STM32F1/system/libmaple/include/libmaple/dma.h index a75b3140b..87e184010 100644 --- a/STM32F1/system/libmaple/include/libmaple/dma.h +++ b/STM32F1/system/libmaple/include/libmaple/dma.h @@ -139,12 +139,12 @@ void dma_init(dma_dev *dev); */ typedef struct dma_tube_config { /** Source of data */ - __io void *tube_src; + __IO void *tube_src; /** Source transfer size */ dma_xfer_size tube_src_size; /** Destination of data */ - __io void *tube_dst; + __IO void *tube_dst; /** Destination transfer size */ dma_xfer_size tube_dst_size; @@ -283,7 +283,7 @@ extern void dma_set_num_transfers(dma_dev *dev, dma_tube tube, * @param tube Tube whose base memory address to set. * @param address Memory base address to use. */ -extern void dma_set_mem_addr(dma_dev *dev, dma_tube tube, __io void *address); +extern void dma_set_mem_addr(dma_dev *dev, dma_tube tube, __IO void *address); /** * @brief Set the base peripheral address where data will be read from @@ -299,7 +299,7 @@ extern void dma_set_mem_addr(dma_dev *dev, dma_tube tube, __io void *address); * @param tube Tube whose peripheral data register base address to set. * @param address Peripheral memory base address to use. */ -extern void dma_set_per_addr(dma_dev *dev, dma_tube tube, __io void *address); +extern void dma_set_per_addr(dma_dev *dev, dma_tube tube, __IO void *address); /* Interrupt handling */ diff --git a/STM32F1/system/libmaple/include/libmaple/exti.h b/STM32F1/system/libmaple/include/libmaple/exti.h index 69362d689..3e914be0b 100644 --- a/STM32F1/system/libmaple/include/libmaple/exti.h +++ b/STM32F1/system/libmaple/include/libmaple/exti.h @@ -48,12 +48,12 @@ extern "C"{ /** EXTI register map type */ typedef struct exti_reg_map { - __io uint32 IMR; /**< Interrupt mask register */ - __io uint32 EMR; /**< Event mask register */ - __io uint32 RTSR; /**< Rising trigger selection register */ - __io uint32 FTSR; /**< Falling trigger selection register */ - __io uint32 SWIER; /**< Software interrupt event register */ - __io uint32 PR; /**< Pending register */ + __IO uint32 IMR; /**< Interrupt mask register */ + __IO uint32 EMR; /**< Event mask register */ + __IO uint32 RTSR; /**< Rising trigger selection register */ + __IO uint32 FTSR; /**< Falling trigger selection register */ + __IO uint32 SWIER; /**< Software interrupt event register */ + __IO uint32 PR; /**< Pending register */ } exti_reg_map; /* diff --git a/STM32F1/system/libmaple/include/libmaple/fsmc.h b/STM32F1/system/libmaple/include/libmaple/fsmc.h index 6225feedc..9dd8a7255 100644 --- a/STM32F1/system/libmaple/include/libmaple/fsmc.h +++ b/STM32F1/system/libmaple/include/libmaple/fsmc.h @@ -53,42 +53,42 @@ extern "C"{ /** FSMC register map type */ typedef struct fsmc_reg_map { - __io uint32 BCR1; /**< SRAM/NOR-Flash chip-select control register 1 */ - __io uint32 BTR1; /**< SRAM/NOR-Flash chip-select timing register 1 */ - __io uint32 BCR2; /**< SRAM/NOR-Flash chip-select control register 2 */ - __io uint32 BTR2; /**< SRAM/NOR-Flash chip-select timing register 2 */ - __io uint32 BCR3; /**< SRAM/NOR-Flash chip-select control register 3 */ - __io uint32 BTR3; /**< SRAM/NOR-Flash chip-select timing register 3 */ - __io uint32 BCR4; /**< SRAM/NOR-Flash chip-select control register 4 */ - __io uint32 BTR4; /**< SRAM/NOR-Flash chip-select timing register 4 */ + __IO uint32 BCR1; /**< SRAM/NOR-Flash chip-select control register 1 */ + __IO uint32 BTR1; /**< SRAM/NOR-Flash chip-select timing register 1 */ + __IO uint32 BCR2; /**< SRAM/NOR-Flash chip-select control register 2 */ + __IO uint32 BTR2; /**< SRAM/NOR-Flash chip-select timing register 2 */ + __IO uint32 BCR3; /**< SRAM/NOR-Flash chip-select control register 3 */ + __IO uint32 BTR3; /**< SRAM/NOR-Flash chip-select timing register 3 */ + __IO uint32 BCR4; /**< SRAM/NOR-Flash chip-select control register 4 */ + __IO uint32 BTR4; /**< SRAM/NOR-Flash chip-select timing register 4 */ const uint8 RESERVED1[64]; /**< Reserved */ - __io uint32 PCR2; /**< PC Card/NAND Flash control register 2 */ - __io uint32 SR2; /**< FIFO status and interrupt register 2 */ - __io uint32 PMEM2; /**< Common memory space timing register 2 */ - __io uint32 PATT2; /**< Attribute memory space timing register 2 */ + __IO uint32 PCR2; /**< PC Card/NAND Flash control register 2 */ + __IO uint32 SR2; /**< FIFO status and interrupt register 2 */ + __IO uint32 PMEM2; /**< Common memory space timing register 2 */ + __IO uint32 PATT2; /**< Attribute memory space timing register 2 */ const uint8 RESERVED2[4]; /**< Reserved */ - __io uint32 ECCR2; /**< ECC result register 2 */ + __IO uint32 ECCR2; /**< ECC result register 2 */ const uint8 RESERVED3[2]; - __io uint32 PCR3; /**< PC Card/NAND Flash control register 3 */ - __io uint32 SR3; /**< FIFO status and interrupt register 3 */ - __io uint32 PMEM3; /**< Common memory space timing register 3 */ - __io uint32 PATT3; /**< Attribute memory space timing register 3 */ + __IO uint32 PCR3; /**< PC Card/NAND Flash control register 3 */ + __IO uint32 SR3; /**< FIFO status and interrupt register 3 */ + __IO uint32 PMEM3; /**< Common memory space timing register 3 */ + __IO uint32 PATT3; /**< Attribute memory space timing register 3 */ const uint32 RESERVED4; /**< Reserved */ - __io uint32 ECCR3; /**< ECC result register 3 */ + __IO uint32 ECCR3; /**< ECC result register 3 */ const uint8 RESERVED5[8]; /**< Reserved */ - __io uint32 PCR4; /**< PC Card/NAND Flash control register 4 */ - __io uint32 SR4; /**< FIFO status and interrupt register 4 */ - __io uint32 PMEM4; /**< Common memory space timing register 4 */ - __io uint32 PATT4; /**< Attribute memory space timing register 4 */ - __io uint32 PIO4; /**< I/O space timing register 4 */ + __IO uint32 PCR4; /**< PC Card/NAND Flash control register 4 */ + __IO uint32 SR4; /**< FIFO status and interrupt register 4 */ + __IO uint32 PMEM4; /**< Common memory space timing register 4 */ + __IO uint32 PATT4; /**< Attribute memory space timing register 4 */ + __IO uint32 PIO4; /**< I/O space timing register 4 */ const uint8 RESERVED6[80]; /**< Reserved */ - __io uint32 BWTR1; /**< SRAM/NOR-Flash write timing register 1 */ + __IO uint32 BWTR1; /**< SRAM/NOR-Flash write timing register 1 */ const uint32 RESERVED7; /**< Reserved */ - __io uint32 BWTR2; /**< SRAM/NOR-Flash write timing register 2 */ + __IO uint32 BWTR2; /**< SRAM/NOR-Flash write timing register 2 */ const uint32 RESERVED8; /**< Reserved */ - __io uint32 BWTR3; /**< SRAM/NOR-Flash write timing register 3 */ + __IO uint32 BWTR3; /**< SRAM/NOR-Flash write timing register 3 */ const uint32 RESERVED9; /**< Reserved */ - __io uint32 BWTR4; /**< SRAM/NOR-Flash write timing register 4 */ + __IO uint32 BWTR4; /**< SRAM/NOR-Flash write timing register 4 */ } __attribute__((packed)) fsmc_reg_map; #define __FSMCB 0xA0000000 @@ -98,10 +98,10 @@ typedef struct fsmc_reg_map { /** FSMC NOR/PSRAM register map type */ typedef struct fsmc_nor_psram_reg_map { - __io uint32 BCR; /**< Chip-select control register */ - __io uint32 BTR; /**< Chip-select timing register */ + __IO uint32 BCR; /**< Chip-select control register */ + __IO uint32 BTR; /**< Chip-select timing register */ const uint8 RESERVED[252]; /**< Reserved */ - __io uint32 BWTR; /**< Write timing register */ + __IO uint32 BWTR; /**< Write timing register */ } fsmc_nor_psram_reg_map; /** FSMC NOR/PSRAM base pointer 1 */ diff --git a/STM32F1/system/libmaple/include/libmaple/i2c.h b/STM32F1/system/libmaple/include/libmaple/i2c.h index 92ec29e36..660815bdb 100644 --- a/STM32F1/system/libmaple/include/libmaple/i2c.h +++ b/STM32F1/system/libmaple/include/libmaple/i2c.h @@ -29,12 +29,26 @@ * @file libmaple/include/libmaple/i2c.h * @brief Inter-Integrated Circuit (I2C) peripheral support * - * Currently master-only. Usage notes: + * Supports Master and Slave. + * Master Usage notes: * * - Enable an I2C device with i2c_master_enable(). * - Initialize an array of struct i2c_msg to suit the bus * transactions (reads/writes) you wish to perform. * - Call i2c_master_xfer() to do the work. + * + * Slave Usage notes: + * - Enable I2C slave by calling i2c_slave_enable(). + * Check flags for usage. Enabling master also enabled slave. + * - initialise the i2c_msg struct and the data buffer + * - initialise the callback functions + * + * I2C slave support added 2012 by Barry Carter. barry.carter@gmail.com, headfuzz.co.uk + * + * Modified 2019 by Donna Whisnant to merge WireSlave changes with the core to + * make slave mode work and without having conflicting data type defintions, + * and rewrote logic to function better. + * */ #ifndef _LIBMAPLE_I2C_H_ @@ -51,6 +65,7 @@ extern "C" { * MHz. (This is for internal use only). * * - (optional) _I2C_HAVE_IRQ_FIXUP: Leave undefined, or define to 1. + * Or define to 0 to completely disable the workaround. * This is for internal use only. It's a hack to work around a * silicon bug related to I2C IRQ pre-emption on some targets. If 1, * the series header must also declare and implement a routine with @@ -64,8 +79,7 @@ extern "C" { * - Reg. map base pointers, device pointer declarations. */ - /* Roger clark. Replaced with line below #include */ -#include "stm32f1/include/series/i2c.h" +#include #include #include @@ -75,15 +89,15 @@ extern "C" { /** I2C register map type */ typedef struct i2c_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 OAR1; /**< Own address register 1 */ - __io uint32 OAR2; /**< Own address register 2 */ - __io uint32 DR; /**< Data register */ - __io uint32 SR1; /**< Status register 1 */ - __io uint32 SR2; /**< Status register 2 */ - __io uint32 CCR; /**< Clock control register */ - __io uint32 TRISE; /**< TRISE (rise time) register */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ + __IO uint32 OAR1; /**< Own address register 1 */ + __IO uint32 OAR2; /**< Own address register 2 */ + __IO uint32 DR; /**< Data register */ + __IO uint32 SR1; /**< Status register 1 */ + __IO uint32 SR2; /**< Status register 2 */ + __IO uint32 CCR; /**< Clock control register */ + __IO uint32 TRISE; /**< TRISE (rise time) register */ } i2c_reg_map; /** @@ -94,6 +108,8 @@ typedef struct i2c_msg { #define I2C_MSG_READ 0x1 #define I2C_MSG_10BIT_ADDR 0x2 +#define I2C_MSG_NOSTOP 0x4 + /** * Bitwise OR of: * - I2C_MSG_READ (write is default) @@ -196,68 +212,32 @@ typedef struct i2c_msg { /* I2C enable options */ #define I2C_FAST_MODE 0x1 // 400 khz #define I2C_DUTY_16_9 0x2 // 16/9 duty ratio -/* Flag 0x4 is reserved; DO NOT USE. */ +#define I2C_REMAP 0x4 // Deprecated: I2C_REMAP for I2C1 #define I2C_BUS_RESET 0x8 // Perform a bus reset -void i2c_master_enable(i2c_dev *dev, uint32 flags); +#define I2C_10BIT_ADDRESSING 0x10 // Enable 10-bit address mode +#define I2C_SLAVE_MODE 0x20 // Set if configured for slave mode instead of master mode +#define I2C_SLAVE_DUAL_ADDRESS 0x40 // Enable the dual slave address scheme +#define I2C_SLAVE_GENERAL_CALL 0x80 // Enable the general call on address 0x00 +#define I2C_PUP_RESET 0x100 // Power-Up Reset + +void i2c_master_enable(i2c_dev *dev, uint32 flags, uint32 freq); +void i2c_slave_enable(i2c_dev *dev, uint32 flags, uint32 freq); #define I2C_ERROR_PROTOCOL (-1) #define I2C_ERROR_TIMEOUT (-2) int32 i2c_master_xfer(i2c_dev *dev, i2c_msg *msgs, uint16 num, uint32 timeout); +int32 wait_for_state_change(i2c_dev *dev, i2c_state state, uint32 timeout); void i2c_bus_reset(const i2c_dev *dev); -/** - * @brief Disable an I2C device - * - * This function disables the corresponding peripheral and marks dev's - * state as I2C_STATE_DISABLED. - * - * @param dev Device to disable. - */ -static inline void i2c_disable(i2c_dev *dev) { - dev->regs->CR1 &= ~I2C_CR1_PE; - dev->state = I2C_STATE_DISABLED; -} - -/* Start/stop conditions */ - -/** - * @brief Generate a start condition on the bus. - * @param dev I2C device - */ -static inline void i2c_start_condition(i2c_dev *dev) { - uint32 cr1; - while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | - I2C_CR1_STOP | - I2C_CR1_PEC)) { - ; - } - dev->regs->CR1 |= I2C_CR1_START; -} +/* Auxiliary procedure for enabling an I2C peripheral; `flags' as for + * i2c_master_enable(). */ +void i2c_set_ccr_trise(i2c_dev *dev, uint32 flags, uint32 freq); -/** - * @brief Generate a stop condition on the bus - * @param dev I2C device - */ -static inline void i2c_stop_condition(i2c_dev *dev) { - uint32 cr1; - while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | - I2C_CR1_STOP | - I2C_CR1_PEC)) { - ; - } - dev->regs->CR1 |= I2C_CR1_STOP; - while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | - I2C_CR1_STOP | - I2C_CR1_PEC)) { - ; - } - -} /* IRQ enable/disable */ -#ifndef _I2C_HAVE_IRQ_FIXUP +#if !defined(_I2C_HAVE_IRQ_FIXUP) || (_I2C_HAVE_IRQ_FIXUP == 0) /* The series header provides this if _I2C_HAVE_IRQ_FIXUP is defined, * but we need it either way. */ #define _i2c_irq_priority_fixup(dev) ((void)0) @@ -275,7 +255,6 @@ static inline void i2c_stop_condition(i2c_dev *dev) { * I2C_IRQ_BUFFER (buffer interrupt). */ static inline void i2c_enable_irq(i2c_dev *dev, uint32 irqs) { - _i2c_irq_priority_fixup(dev); dev->regs->CR2 |= irqs; } @@ -291,22 +270,18 @@ static inline void i2c_disable_irq(i2c_dev *dev, uint32 irqs) { dev->regs->CR2 &= ~irqs; } -/* ACK/NACK */ - /** - * @brief Enable I2C acknowledgment - * @param dev I2C device - */ -static inline void i2c_enable_ack(i2c_dev *dev) { - dev->regs->CR1 |= I2C_CR1_ACK; -} - -/** - * @brief Disable I2C acknowledgment - * @param dev I2C device + * @brief Disable an I2C device + * + * This function disables the corresponding peripheral and marks dev's + * state as I2C_STATE_DISABLED. + * + * @param dev Device to disable. */ -static inline void i2c_disable_ack(i2c_dev *dev) { - dev->regs->CR1 &= ~I2C_CR1_ACK; +static inline void i2c_disable(i2c_dev *dev) { + i2c_disable_irq(dev, I2C_IRQ_BUFFER | I2C_IRQ_EVENT | I2C_IRQ_ERROR); // Make sure IRQs are disabled in case we are switching master<->slave modes + dev->regs->CR1 &= ~I2C_CR1_PE; + dev->state = I2C_STATE_DISABLED; } /* GPIO control */ @@ -338,42 +313,20 @@ extern void i2c_master_release_bus(const i2c_dev *dev); void i2c_init(i2c_dev *dev); -/** - * @brief Turn on an I2C peripheral - * @param dev Device to enable - */ -static inline void i2c_peripheral_enable(i2c_dev *dev) { - dev->regs->CR1 |= I2C_CR1_PE; -} - -/** - * @brief Turn off an I2C peripheral - * @param dev Device to turn off - */ -static inline void i2c_peripheral_disable(i2c_dev *dev) { - dev->regs->CR1 &= ~I2C_CR1_PE; -} - -/** - * @brief Fill transmit register - * @param dev I2C device - * @param byte Byte to write - */ -static inline void i2c_write(i2c_dev *dev, uint8 byte) { - dev->regs->DR = byte; -} - /** * @brief Set input clock frequency, in MHz * @param dev I2C device * @param freq Frequency, in MHz. This must be at least 2, and at most * the APB frequency of dev's bus. (For example, if * rcc_dev_clk(dev) == RCC_APB1, freq must be at most - * PCLK1, in MHz). There is an additional limit of 46 MHz. + * PCLK1, in MHz). There is an additional limit of 36 MHz. */ static inline void i2c_set_input_clk(i2c_dev *dev, uint32 freq) { -#define I2C_MAX_FREQ_MHZ 46 - ASSERT(2 <= freq && freq <= _i2c_bus_clk(dev) && freq <= I2C_MAX_FREQ_MHZ); +// TODO : I2C_MAX_FREQ_MHZ should be in the series header, as it's different on STM32F4 and others! +#define I2C_MAX_FREQ_MHZ 36 // Limit on STM32F1 is 36 MHz (See ST Spec, which says: Higher than 0b100100 not allowed) + if (freq < 2) freq = 2; + if (freq > _i2c_bus_clk(dev)) freq = _i2c_bus_clk(dev); + if (freq > I2C_MAX_FREQ_MHZ) freq = I2C_MAX_FREQ_MHZ; uint32 cr2 = dev->regs->CR2; cr2 &= ~I2C_CR2_FREQ; cr2 |= freq; @@ -391,10 +344,7 @@ static inline void i2c_set_input_clk(i2c_dev *dev, uint32 freq) { * Fast/Standard mode) */ static inline void i2c_set_clk_control(i2c_dev *dev, uint32 val) { - uint32 ccr = dev->regs->CCR; - ccr &= ~I2C_CCR_CCR; - ccr |= val; - dev->regs->CCR = ccr; + dev->regs->CCR = val; } /** @@ -407,6 +357,42 @@ static inline void i2c_set_trise(i2c_dev *dev, uint32 trise) { dev->regs->TRISE = trise; } + +/* + * Slave support + */ + +/* callback functions */ +/* Callback handler for data received over the bus */ +void i2c_slave_attach_recv_handler(i2c_dev *dev, i2c_msg *msg, i2c_slave_recv_callback_func func); + +/* Callback handler for data being requested over the bus + * The callback function must call i2c_write to get the data over the bus + */ +void i2c_slave_attach_transmit_handler(i2c_dev *dev, i2c_msg *msg, i2c_slave_xmit_callback_func func); + +/** + * @brief Set the primary I2c slave address + * @param dev I2C device + * @param address the 7 or 10 bit i2c address + */ +static inline void i2c_slave_set_own_address(i2c_dev *dev, uint16 address) +{ + // TODO : Add support for 10-bit addresses + dev->regs->OAR1 = (address << 1) | 0x4000; // According to ST Docs: Note: Bit 14 should always be kept at 1 by software! +} + +/** + * @brief Set the secondary I2c slave address + * @param dev I2C device + * @param address the 7 or 10 bit i2c address + */ +static inline void i2c_slave_set_own_address2(i2c_dev *dev, uint16 address) +{ + // TODO : Add support for 10-bit addresses + dev->regs->OAR2 = (address << 1) | I2C_OAR2_ENDUAL; +} + #ifdef __cplusplus } #endif diff --git a/STM32F1/system/libmaple/include/libmaple/i2c_common.h b/STM32F1/system/libmaple/include/libmaple/i2c_common.h index 17cabe344..d7be98a53 100644 --- a/STM32F1/system/libmaple/include/libmaple/i2c_common.h +++ b/STM32F1/system/libmaple/include/libmaple/i2c_common.h @@ -33,6 +33,12 @@ * CONTENTS UNSTABLE. The existence of this file is an implementation * detail. Never include it directly. If you need something from * here, include instead. + * + * I2C slave support added 2012 by Barry Carter. barry.carter@gmail.com, headfuzz.co.uk + * + * Modified 2019 by Donna Whisnant to merge WireSlave changes with the core to + * make slave mode work and without having conflicting data type defintions + * */ #ifndef _LIBMAPLE_I2C_COMMON_H_ @@ -55,6 +61,9 @@ typedef enum i2c_state { I2C_STATE_ERROR = -1 /**< Error occurred */ } i2c_state; +typedef void (*i2c_slave_recv_callback_func)(struct i2c_msg *); +typedef void (*i2c_slave_xmit_callback_func)(struct i2c_msg *); + /** * @brief I2C device type. */ @@ -88,6 +97,20 @@ typedef struct i2c_dev { nvic_irq_num ev_nvic_line; /**< Event IRQ number */ nvic_irq_num er_nvic_line; /**< Error IRQ number */ volatile i2c_state state; /**< Device state */ + + // -------------------- + + uint32 config_flags; /**< Configuration flags */ + + /* + * Slave implementation. Callback functions in this struct allow + * for a separate callback function for each I2C unit available onboard + */ + i2c_slave_xmit_callback_func i2c_slave_xmit_callback; + i2c_slave_recv_callback_func i2c_slave_recv_callback; + + struct i2c_msg *i2c_slave_xmit_msg; /* the message that the i2c slave will use for transmitting */ + struct i2c_msg *i2c_slave_recv_msg; /* the message that the i2c slave will use for receiving */ } i2c_dev; #endif diff --git a/STM32F1/system/libmaple/include/libmaple/iwdg.h b/STM32F1/system/libmaple/include/libmaple/iwdg.h index 3a16c5500..f99943986 100644 --- a/STM32F1/system/libmaple/include/libmaple/iwdg.h +++ b/STM32F1/system/libmaple/include/libmaple/iwdg.h @@ -53,10 +53,10 @@ extern "C"{ /** Independent watchdog register map type. */ typedef struct iwdg_reg_map { - __io uint32 KR; /**< Key register. */ - __io uint32 PR; /**< Prescaler register. */ - __io uint32 RLR; /**< Reload register. */ - __io uint32 SR; /**< Status register */ + __IO uint32 KR; /**< Key register. */ + __IO uint32 PR; /**< Prescaler register. */ + __IO uint32 RLR; /**< Reload register. */ + __IO uint32 SR; /**< Status register */ } iwdg_reg_map; /** Independent watchdog base pointer */ diff --git a/STM32F1/system/libmaple/include/libmaple/libmaple_types.h b/STM32F1/system/libmaple/include/libmaple/libmaple_types.h index 398b7052f..be8a8cca1 100644 --- a/STM32F1/system/libmaple/include/libmaple/libmaple_types.h +++ b/STM32F1/system/libmaple/include/libmaple/libmaple_types.h @@ -52,14 +52,11 @@ typedef long long int64; typedef void (*voidFuncPtr)(void); typedef void (*voidArgumentFuncPtr)(void *); -#define __io volatile +#define __IO volatile #define __attr_flash __attribute__((section (".USER_FLASH"))) #define __packed __attribute__((__packed__)) #define __deprecated __attribute__((__deprecated__)) #define __weak __attribute__((weak)) -#ifndef __always_inline -#define __always_inline __attribute__((always_inline)) -#endif #ifndef __unused #define __unused __attribute__((unused)) #endif diff --git a/STM32F1/system/libmaple/include/libmaple/nvic.h b/STM32F1/system/libmaple/include/libmaple/nvic.h index 69d9a9124..8915f0129 100644 --- a/STM32F1/system/libmaple/include/libmaple/nvic.h +++ b/STM32F1/system/libmaple/include/libmaple/nvic.h @@ -55,31 +55,31 @@ extern "C"{ /** NVIC register map type. */ typedef struct nvic_reg_map { - __io uint32 ISER[8]; /**< Interrupt Set Enable Registers */ + __IO uint32 ISER[8]; /**< Interrupt Set Enable Registers */ /** Reserved */ uint32 RESERVED0[24]; - __io uint32 ICER[8]; /**< Interrupt Clear Enable Registers */ + __IO uint32 ICER[8]; /**< Interrupt Clear Enable Registers */ /** Reserved */ uint32 RESERVED1[24]; - __io uint32 ISPR[8]; /**< Interrupt Set Pending Registers */ + __IO uint32 ISPR[8]; /**< Interrupt Set Pending Registers */ /** Reserved */ uint32 RESERVED2[24]; - __io uint32 ICPR[8]; /**< Interrupt Clear Pending Registers */ + __IO uint32 ICPR[8]; /**< Interrupt Clear Pending Registers */ /** Reserved */ uint32 RESERVED3[24]; - __io uint32 IABR[8]; /**< Interrupt Active bit Registers */ + __IO uint32 IABR[8]; /**< Interrupt Active bit Registers */ /** Reserved */ uint32 RESERVED4[56]; - __io uint8 IP[240]; /**< Interrupt Priority Registers */ + __IO uint8 IP[240]; /**< Interrupt Priority Registers */ /** Reserved */ uint32 RESERVED5[644]; - __io uint32 STIR; /**< Software Trigger Interrupt Registers */ + __IO uint32 STIR; /**< Software Trigger Interrupt Registers */ } nvic_reg_map; /** NVIC register map base pointer. */ @@ -109,14 +109,14 @@ void nvic_sys_reset(); /** * Enables interrupts and configurable fault handlers (clear PRIMASK). */ -static inline __always_inline void nvic_globalirq_enable() { +inline void nvic_globalirq_enable() { asm volatile("cpsie i"); } /** * Disable interrupts and configurable fault handlers (set PRIMASK). */ -static inline __always_inline void nvic_globalirq_disable() { +inline void nvic_globalirq_disable() { asm volatile("cpsid i"); } diff --git a/STM32F1/system/libmaple/include/libmaple/pwr.h b/STM32F1/system/libmaple/include/libmaple/pwr.h index f711c7c95..fada6df76 100644 --- a/STM32F1/system/libmaple/include/libmaple/pwr.h +++ b/STM32F1/system/libmaple/include/libmaple/pwr.h @@ -43,8 +43,8 @@ extern "C" { /** Power interface register map. */ typedef struct pwr_reg_map { - __io uint32 CR; /**< Control register */ - __io uint32 CSR; /**< Control and status register */ + __IO uint32 CR; /**< Control register */ + __IO uint32 CSR; /**< Control and status register */ } pwr_reg_map; /** Power peripheral register map base pointer. */ diff --git a/STM32F1/system/libmaple/include/libmaple/ring_buffer.h b/STM32F1/system/libmaple/include/libmaple/ring_buffer.h index e99fe6266..854d58937 100644 --- a/STM32F1/system/libmaple/include/libmaple/ring_buffer.h +++ b/STM32F1/system/libmaple/include/libmaple/ring_buffer.h @@ -81,7 +81,7 @@ static inline void rb_init(ring_buffer *rb, uint16 size, uint8 *buf) { * @param rb Buffer whose elements to count. */ static inline uint16 rb_full_count(ring_buffer *rb) { - __io ring_buffer *arb = rb; + __IO ring_buffer *arb = rb; int32 size = arb->tail - arb->head; if (arb->tail < arb->head) { size += arb->size + 1; diff --git a/STM32F1/system/libmaple/include/libmaple/scb.h b/STM32F1/system/libmaple/include/libmaple/scb.h index c42a0f2a0..d58434ca2 100644 --- a/STM32F1/system/libmaple/include/libmaple/scb.h +++ b/STM32F1/system/libmaple/include/libmaple/scb.h @@ -49,37 +49,37 @@ extern "C" { /** System control block register map type */ typedef struct scb_reg_map { - __io uint32 CPUID; /**< CPU ID Base Register */ - __io uint32 ICSR; /**< Interrupt Control State Register */ - __io uint32 VTOR; /**< Vector Table Offset Register */ - __io uint32 AIRCR; /**< Application Interrupt / Reset Control Register */ - __io uint32 SCR; /**< System Control Register */ - __io uint32 CCR; /**< Configuration and Control Register */ - __io uint8 SHP[12]; /**< System Handler Priority Registers + __IO uint32 CPUID; /**< CPU ID Base Register */ + __IO uint32 ICSR; /**< Interrupt Control State Register */ + __IO uint32 VTOR; /**< Vector Table Offset Register */ + __IO uint32 AIRCR; /**< Application Interrupt / Reset Control Register */ + __IO uint32 SCR; /**< System Control Register */ + __IO uint32 CCR; /**< Configuration and Control Register */ + __IO uint8 SHP[12]; /**< System Handler Priority Registers (4-7, 8-11, 12-15) */ - __io uint32 SHCSR; /**< System Handler Control and State Register */ - __io uint32 CFSR; /**< Configurable Fault Status Register */ - __io uint32 HFSR; /**< Hard Fault Status Register */ + __IO uint32 SHCSR; /**< System Handler Control and State Register */ + __IO uint32 CFSR; /**< Configurable Fault Status Register */ + __IO uint32 HFSR; /**< Hard Fault Status Register */ /* DFSR is not documented by ST in PM0056 (as of Revision 4), but * there's a 4 byte hole in the SCB register map docs right where * it belongs. Since it's specified as "always implemented" in * the ARM v7-M ARM, I'm assuming its absence is a bug in the ST * doc, but I haven't proven it. [mbolivar] */ - __io uint32 DFSR; /**< Debug Fault Status Register */ - __io uint32 MMFAR; /**< Mem Manage Address Register */ - __io uint32 BFAR; /**< Bus Fault Address Register */ + __IO uint32 DFSR; /**< Debug Fault Status Register */ + __IO uint32 MMFAR; /**< Mem Manage Address Register */ + __IO uint32 BFAR; /**< Bus Fault Address Register */ #if 0 /* The following registers are implementation-defined according to * ARM v7-M, and I can't find evidence of their existence in ST's * docs. I'm removing them. Feel free to yell at me if they do * exist. [mbolivar] */ - __io uint32 AFSR; /**< Auxiliary Fault Status Register */ - __io uint32 PFR[2]; /**< Processor Feature Register */ - __io uint32 DFR; /**< Debug Feature Register */ - __io uint32 AFR; /**< Auxiliary Feature Register */ - __io uint32 MMFR[4]; /**< Memory Model Feature Register */ - __io uint32 ISAR[5]; /**< ISA Feature Register */ + __IO uint32 AFSR; /**< Auxiliary Fault Status Register */ + __IO uint32 PFR[2]; /**< Processor Feature Register */ + __IO uint32 DFR; /**< Debug Feature Register */ + __IO uint32 AFR; /**< Auxiliary Feature Register */ + __IO uint32 MMFR[4]; /**< Memory Model Feature Register */ + __IO uint32 ISAR[5]; /**< ISA Feature Register */ #endif } scb_reg_map; @@ -122,7 +122,7 @@ typedef struct scb_reg_map { #define SCB_AIRCR_VECTKEYSTAT (0x5FA << 16) #define SCB_AIRCR_VECTKEY (0x5FA << 16) #define SCB_AIRCR_ENDIANNESS (1U << 15) -#define SCB_AIRCR_PRIGROUP (0x3 << 8) +#define SCB_AIRCR_PRIGROUP (0x7 << 8) #define SCB_AIRCR_SYSRESETREQ (1U << 2) #define SCB_AIRCR_VECTCLRACTIVE (1U << 1) #define SCB_AIRCR_VECTRESET (1U << 0) diff --git a/STM32F1/system/libmaple/include/libmaple/sdio.h b/STM32F1/system/libmaple/include/libmaple/sdio.h index dec31c8b7..11ec98608 100644 --- a/STM32F1/system/libmaple/include/libmaple/sdio.h +++ b/STM32F1/system/libmaple/include/libmaple/sdio.h @@ -52,23 +52,23 @@ extern "C" { // SDIO register map type typedef struct sdio_reg_map { - __io uint32 POWER; // 0x00 - __io uint32 CLKCR; // 0x04 - __io uint32 ARG; // 0x08 - __io uint32 CMD; // 0x0C - __io uint32 RESPCMD; // 0x10 (0x3F) - const uint32 RESP[4]; // 0x14 - contain the card status, which is part of the received response. - __io uint32 DTIMER; // 0x24 - contains the data timeout period, in card bus clock periods. - __io uint32 DLEN; // 0x28 (0x01FF FFFF) - contains the number of data bytes to be transferred - __io uint32 DCTRL; // 0x2C - __io uint32 DCOUNT; // 0x30 (0x01FF FFFF) - __io uint32 STA; // 0x34 - __io uint32 ICR; // 0x38 - __io uint32 MASK; // 0x3C + __IO uint32 POWER; // 0x00 + __IO uint32 CLKCR; // 0x04 + __IO uint32 ARG; // 0x08 + __IO uint32 CMD; // 0x0C + __IO uint32 RESPCMD; // 0x10 (0x3F) + __IO const uint32 RESP[4]; // 0x14 - contain the card status, which is part of the received response. + __IO uint32 DTIMER; // 0x24 - contains the data timeout period, in card bus clock periods. + __IO uint32 DLEN; // 0x28 (0x01FF FFFF) - contains the number of data bytes to be transferred + __IO uint32 DCTRL; // 0x2C + __IO uint32 DCOUNT; // 0x30 (0x01FF FFFF) + __IO uint32 STA; // 0x34 + __IO uint32 ICR; // 0x38 + __IO uint32 MASK; // 0x3C const uint32 RESERVED1[2]; - __io uint32 FIFOCNT; // 0x48 (0x01FF FFFF) + __IO uint32 FIFOCNT; // 0x48 (0x01FF FFFF) const uint32 RESERVED2[13]; - __io uint32 FIFO; // 0x80 + __IO uint32 FIFO; // 0x80 } sdio_reg_map; #define sdio_dev sdio_reg_map @@ -95,7 +95,7 @@ extern sdio_dev * SDIO; // After a data write, data cannot be written to this register for three SDIOCLK clock periods // plus two PCLK2 clock periods. SDIO_CK can also be stopped during the read wait interval // for SD I/O cards: in this case the SDIO_CLKCR register does not control SDIO_CK. -#define SDIO_CLKCR_HWFC_EN (1<<14) // HW Flow Control enable - DON'T USE!!! (see errata sheet 2.12.1) +#define SDIO_CLKCR_HWFC_EN (1<<14) // HW Flow Control enable - DON'T USE in F4!!! (see errata sheet 2.12.1) // Overrun errors (Rx mode) and FIFO underrun (Tx mode) // should be managed by the application software. #define SDIO_CLKCR_NEGEDGE (1<<13) // SDIO_CK de-phasing selection bit - DON'T USE!!! (see errata sheet 2.12.4) @@ -106,7 +106,7 @@ extern sdio_dev * SDIO; #define SDIO_CLKCR_PWRSAV (1<<9) // 0: SDIO_CK clock is always enabled, 1: SDIO_CK is only enabled when the bus is active #define SDIO_CLKCR_CLKEN (1<<8) // Clock enable #define SDIO_CLKCR_CLKDIV (0xFF) // SDIO_CK = SDIOCLK / [CLKDIV + 2] -#define SDIOCLK 72000000UL // SDIO master clock frequency +#define SDIOCLK PCLK2 // SDIO master clock frequency // SDIO_CMD register bits // After a data write, data cannot be written to this register for three SDIOCLK clock periods diff --git a/STM32F1/system/libmaple/include/libmaple/spi.h b/STM32F1/system/libmaple/include/libmaple/spi.h index 0da4129f8..5d295bbb4 100644 --- a/STM32F1/system/libmaple/include/libmaple/spi.h +++ b/STM32F1/system/libmaple/include/libmaple/spi.h @@ -54,15 +54,15 @@ extern "C" { /** SPI register map type. */ typedef struct spi_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SR; /**< Status register */ - __io uint32 DR; /**< Data register */ - __io uint32 CRCPR; /**< CRC polynomial register */ - __io uint32 RXCRCR; /**< RX CRC register */ - __io uint32 TXCRCR; /**< TX CRC register */ - __io uint32 I2SCFGR; /**< I2S configuration register */ - __io uint32 I2SPR; /**< I2S prescaler register */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ + __IO uint32 SR; /**< Status register */ + __IO uint32 DR; /**< Data register */ + __IO uint32 CRCPR; /**< CRC polynomial register */ + __IO uint32 RXCRCR; /**< RX CRC register */ + __IO uint32 TXCRCR; /**< TX CRC register */ + __IO uint32 I2SCFGR; /**< I2S configuration register */ + __IO uint32 I2SPR; /**< I2S prescaler register */ } spi_reg_map; /* diff --git a/STM32F1/system/libmaple/include/libmaple/syscfg.h b/STM32F1/system/libmaple/include/libmaple/syscfg.h index 6b375d346..e39d0b7f3 100644 --- a/STM32F1/system/libmaple/include/libmaple/syscfg.h +++ b/STM32F1/system/libmaple/include/libmaple/syscfg.h @@ -48,12 +48,12 @@ extern "C" { * @brief SYSCFG register map type. */ typedef struct syscfg_reg_map { - __io uint32 MEMRMP; /**< Memory remap register */ - __io uint32 PMC; /**< Peripheral mode configuration */ - __io uint32 EXTICR[4]; /**< External interrupt configuration registers */ + __IO uint32 MEMRMP; /**< Memory remap register */ + __IO uint32 PMC; /**< Peripheral mode configuration */ + __IO uint32 EXTICR[4]; /**< External interrupt configuration registers */ const uint32 RESERVED1; const uint32 RESERVED2; - __io uint32 CMPCR; /**< Compensation cell control register */ + __IO uint32 CMPCR; /**< Compensation cell control register */ } syscfg_reg_map; /** SYSCFG register map base pointer */ diff --git a/STM32F1/system/libmaple/include/libmaple/systick.h b/STM32F1/system/libmaple/include/libmaple/systick.h index 51d0c567f..3f6bd5f59 100644 --- a/STM32F1/system/libmaple/include/libmaple/systick.h +++ b/STM32F1/system/libmaple/include/libmaple/systick.h @@ -41,10 +41,10 @@ extern "C"{ /** SysTick register map type */ typedef struct systick_reg_map { - __io uint32 CSR; /**< Control and status register */ - __io uint32 RVR; /**< Reload value register */ - __io uint32 CNT; /**< Current value register ("count") */ - __io uint32 CVR; /**< Calibration value register */ + __IO uint32 CSR; /**< Control and status register */ + __IO uint32 RVR; /**< Reload value register */ + __IO uint32 CNT; /**< Current value register ("count") */ + __IO uint32 CVR; /**< Calibration value register */ } systick_reg_map; /** SysTick register map base pointer */ diff --git a/STM32F1/system/libmaple/include/libmaple/timer.h b/STM32F1/system/libmaple/include/libmaple/timer.h index 2c83e5e81..87b83e551 100644 --- a/STM32F1/system/libmaple/include/libmaple/timer.h +++ b/STM32F1/system/libmaple/include/libmaple/timer.h @@ -50,26 +50,26 @@ extern "C"{ /** Advanced control timer register map type */ typedef struct timer_adv_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SMCR; /**< Slave mode control register */ - __io uint32 DIER; /**< DMA/interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - __io uint32 CCMR1; /**< Capture/compare mode register 1 */ - __io uint32 CCMR2; /**< Capture/compare mode register 2 */ - __io uint32 CCER; /**< Capture/compare enable register */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ - __io uint32 RCR; /**< Repetition counter register */ - __io uint32 CCR1; /**< Capture/compare register 1 */ - __io uint32 CCR2; /**< Capture/compare register 2 */ - __io uint32 CCR3; /**< Capture/compare register 3 */ - __io uint32 CCR4; /**< Capture/compare register 4 */ - __io uint32 BDTR; /**< Break and dead-time register */ - __io uint32 DCR; /**< DMA control register */ - __io uint32 DMAR; /**< DMA address for full transfer */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ + __IO uint32 SMCR; /**< Slave mode control register */ + __IO uint32 DIER; /**< DMA/interrupt enable register */ + __IO uint32 SR; /**< Status register */ + __IO uint32 EGR; /**< Event generation register */ + __IO uint32 CCMR1; /**< Capture/compare mode register 1 */ + __IO uint32 CCMR2; /**< Capture/compare mode register 2 */ + __IO uint32 CCER; /**< Capture/compare enable register */ + __IO uint32 CNT; /**< Counter */ + __IO uint32 PSC; /**< Prescaler */ + __IO uint32 ARR; /**< Auto-reload register */ + __IO uint32 RCR; /**< Repetition counter register */ + __IO uint32 CCR1; /**< Capture/compare register 1 */ + __IO uint32 CCR2; /**< Capture/compare register 2 */ + __IO uint32 CCR3; /**< Capture/compare register 3 */ + __IO uint32 CCR4; /**< Capture/compare register 4 */ + __IO uint32 BDTR; /**< Break and dead-time register */ + __IO uint32 DCR; /**< DMA control register */ + __IO uint32 DMAR; /**< DMA address for full transfer */ } timer_adv_reg_map; /* General purpose timer register map type: intentionally omitted. @@ -79,18 +79,18 @@ typedef struct timer_adv_reg_map { /** Basic timer register map type */ typedef struct timer_bas_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ const uint32 RESERVED1; /**< Reserved */ - __io uint32 DIER; /**< DMA/interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ + __IO uint32 DIER; /**< DMA/interrupt enable register */ + __IO uint32 SR; /**< Status register */ + __IO uint32 EGR; /**< Event generation register */ const uint32 RESERVED2; /**< Reserved */ const uint32 RESERVED3; /**< Reserved */ const uint32 RESERVED4; /**< Reserved */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ + __IO uint32 CNT; /**< Counter */ + __IO uint32 PSC; /**< Prescaler */ + __IO uint32 ARR; /**< Auto-reload register */ } timer_bas_reg_map; /* @@ -372,7 +372,6 @@ extern timer_dev timer14; /* Capture/compare mode registers, common values */ -#define TIMER_CCMR_CCS_OUTPUT 0x0 #define TIMER_CCMR_CCS_INPUT_TI1 0x1 #define TIMER_CCMR_CCS_INPUT_TI2 0x2 #define TIMER_CCMR_CCS_INPUT_TRC 0x3 @@ -387,27 +386,27 @@ extern timer_dev timer14; #define TIMER_CCMR1_OC1FE_BIT 2 #define TIMER_CCMR1_OC2CE (1U << TIMER_CCMR1_OC2CE_BIT) -#define TIMER_CCMR1_OC2M (0x3 << 12) +#define TIMER_CCMR1_OC2M (0x7 << 12) #define TIMER_CCMR1_IC2F (0xF << 12) #define TIMER_CCMR1_OC2PE (1U << TIMER_CCMR1_OC2PE_BIT) #define TIMER_CCMR1_OC2FE (1U << TIMER_CCMR1_OC2FE_BIT) #define TIMER_CCMR1_IC2PSC (0x3 << 10) #define TIMER_CCMR1_CC2S (0x3 << 8) -#define TIMER_CCMR1_CC2S_OUTPUT (TIMER_CCMR_CCS_OUTPUT << 8) -#define TIMER_CCMR1_CC2S_INPUT_TI1 (TIMER_CCMR_CCS_INPUT_TI1 << 8) -#define TIMER_CCMR1_CC2S_INPUT_TI2 (TIMER_CCMR_CCS_INPUT_TI2 << 8) -#define TIMER_CCMR1_CC2S_INPUT_TRC (TIMER_CCMR_CCS_INPUT_TRC << 8) +#define TIMER_CCMR1_CC2S_OUTPUT (0x0 << 8) +#define TIMER_CCMR1_CC2S_INPUT_TI2 (0x1 << 8) +#define TIMER_CCMR1_CC2S_INPUT_TI1 (0x2 << 8) +#define TIMER_CCMR1_CC2S_INPUT_TRC (0x3 << 8) #define TIMER_CCMR1_OC1CE (1U << TIMER_CCMR1_OC1CE_BIT) -#define TIMER_CCMR1_OC1M (0x3 << 4) +#define TIMER_CCMR1_OC1M (0x7 << 4) #define TIMER_CCMR1_IC1F (0xF << 4) #define TIMER_CCMR1_OC1PE (1U << TIMER_CCMR1_OC1PE_BIT) #define TIMER_CCMR1_OC1FE (1U << TIMER_CCMR1_OC1FE_BIT) #define TIMER_CCMR1_IC1PSC (0x3 << 2) #define TIMER_CCMR1_CC1S 0x3 -#define TIMER_CCMR1_CC1S_OUTPUT TIMER_CCMR_CCS_OUTPUT -#define TIMER_CCMR1_CC1S_INPUT_TI1 TIMER_CCMR_CCS_INPUT_TI1 -#define TIMER_CCMR1_CC1S_INPUT_TI2 TIMER_CCMR_CCS_INPUT_TI2 -#define TIMER_CCMR1_CC1S_INPUT_TRC TIMER_CCMR_CCS_INPUT_TRC +#define TIMER_CCMR1_CC1S_OUTPUT 0x0 +#define TIMER_CCMR1_CC1S_INPUT_TI1 0x1 +#define TIMER_CCMR1_CC1S_INPUT_TI2 0x2 +#define TIMER_CCMR1_CC1S_INPUT_TRC 0x3 /* Capture/compare mode register 2 (CCMR2) */ @@ -419,27 +418,27 @@ extern timer_dev timer14; #define TIMER_CCMR2_OC3FE_BIT 2 #define TIMER_CCMR2_OC4CE (1U << TIMER_CCMR2_OC4CE_BIT) -#define TIMER_CCMR2_OC4M (0x3 << 12) +#define TIMER_CCMR2_OC4M (0x7 << 12) #define TIMER_CCMR2_IC4F (0xF << 12) #define TIMER_CCMR2_OC4PE (1U << TIMER_CCMR2_OC4PE_BIT) #define TIMER_CCMR2_OC4FE (1U << TIMER_CCMR2_OC4FE_BIT) #define TIMER_CCMR2_IC4PSC (0x3 << 10) #define TIMER_CCMR2_CC4S (0x3 << 8) -#define TIMER_CCMR2_CC4S_OUTPUT (TIMER_CCMR_CCS_OUTPUT << 8) -#define TIMER_CCMR2_CC4S_INPUT_TI1 (TIMER_CCMR_CCS_INPUT_TI1 << 8) -#define TIMER_CCMR2_CC4S_INPUT_TI2 (TIMER_CCMR_CCS_INPUT_TI2 << 8) -#define TIMER_CCMR2_CC4S_INPUT_TRC (TIMER_CCMR_CCS_INPUT_TRC << 8) +#define TIMER_CCMR2_CC4S_OUTPUT (0x0 << 8) +#define TIMER_CCMR2_CC4S_INPUT_TI4 (0x1 << 8) +#define TIMER_CCMR2_CC4S_INPUT_TI3 (0x2 << 8) +#define TIMER_CCMR2_CC4S_INPUT_TRC (0x3 << 8) #define TIMER_CCMR2_OC3CE (1U << TIMER_CCMR2_OC3CE_BIT) -#define TIMER_CCMR2_OC3M (0x3 << 4) +#define TIMER_CCMR2_OC3M (0x7 << 4) #define TIMER_CCMR2_IC3F (0xF << 4) #define TIMER_CCMR2_OC3PE (1U << TIMER_CCMR2_OC3PE_BIT) #define TIMER_CCMR2_OC3FE (1U << TIMER_CCMR2_OC3FE_BIT) #define TIMER_CCMR2_IC3PSC (0x3 << 2) #define TIMER_CCMR2_CC3S 0x3 -#define TIMER_CCMR2_CC3S_OUTPUT TIMER_CCMR_CCS_OUTPUT -#define TIMER_CCMR2_CC3S_INPUT_TI1 TIMER_CCMR_CCS_INPUT_TI1 -#define TIMER_CCMR2_CC3S_INPUT_TI2 TIMER_CCMR_CCS_INPUT_TI2 -#define TIMER_CCMR2_CC3S_INPUT_TRC TIMER_CCMR_CCS_INPUT_TRC +#define TIMER_CCMR2_CC3S_OUTPUT 0x0 +#define TIMER_CCMR2_CC3S_INPUT_TI3 0x1 +#define TIMER_CCMR2_CC3S_INPUT_TI4 0x2 +#define TIMER_CCMR2_CC3S_INPUT_TRC 0x3 /* Capture/compare enable register (CCER) */ @@ -564,13 +563,15 @@ typedef enum timer_mode { * values, the corresponding interrupt is fired. */ TIMER_OUTPUT_COMPARE, - /* TIMER_INPUT_CAPTURE, TODO: In this mode, the timer can measure the + + /* TIMER_INPUT_CAPTURE, UNDER DEVELOPMENT: In this mode, the timer can measure the * pulse lengths of input signals */ /* TIMER_ONE_PULSE, TODO: In this mode, the timer can generate a single * pulse on a GPIO pin for a specified amount of * time. */ TIMER_ENCODER, //CARLOS Change + TIMER_INPUT_CAPTURE,// code from @cesco } timer_mode; /** Timer channel numbers */ @@ -663,6 +664,19 @@ static inline void timer_resume(timer_dev *dev) { *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 1; } +/** + * @brief Get the status register. + * @param dev Timer device + * @return Status register value (16bits). + */ +static inline uint16 timer_get_status(timer_dev *dev) { + return (dev->regs).gen->SR; +} + +static inline void timer_reset_status_bit(timer_dev *dev, uint8 bit) { + *bb_perip(&(dev->regs).gen->SR, bit) = 0; +} + /** * @brief Returns the timer's counter value. * @@ -738,7 +752,7 @@ static inline void timer_set_reload(timer_dev *dev, uint16 arr) { * @param channel Channel whose compare value to get. */ static inline uint16 timer_get_compare(timer_dev *dev, uint8 channel) { - __io uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); + __IO uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); return *ccr; } @@ -751,7 +765,7 @@ static inline uint16 timer_get_compare(timer_dev *dev, uint8 channel) { static inline void timer_set_compare(timer_dev *dev, uint8 channel, uint16 value) { - __io uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); + __IO uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); *ccr = value; } @@ -828,7 +842,9 @@ static inline void timer_dma_disable_req(timer_dev *dev, uint8 channel) { * @see timer_channel */ static inline void timer_enable_irq(timer_dev *dev, uint8 interrupt) { - *bb_perip(&(dev->regs).adv->SR, interrupt) = 0; // clear interrupt flag + // clear interrupt flag, use different masks for reserved bits + (dev->regs).adv->SR = (~BIT(interrupt)) & ( (dev->type==TIMER_ADVANCED) ? 0x1EFF : + ( (dev->type==TIMER_GENERAL) ? 0x1E5F : 0x0001) ); *bb_perip(&(dev->regs).adv->DIER, interrupt) = 1; } @@ -1065,82 +1081,27 @@ static inline void timer_oc_set_mode(timer_dev *dev, timer_oc_mode mode, uint8 flags) { /* channel == 1,2 -> CCMR1; channel == 3,4 -> CCMR2 */ - __io uint32 *ccmr = &(dev->regs).gen->CCMR1 + (((channel - 1) >> 1) & 1); + __IO uint32 *ccmr = &(dev->regs).gen->CCMR1 + (((channel - 1) >> 1) & 1); /* channel == 1,3 -> shift = 0, channel == 2,4 -> shift = 8 */ uint8 shift = 8 * (1 - (channel & 1)); uint32 tmp = *ccmr; tmp &= ~(0xFF << shift); - tmp |= (mode | flags | TIMER_CCMR_CCS_OUTPUT) << shift; + tmp |= (mode | flags) << shift; *ccmr = tmp; } -/* - * Old, erroneous bit definitions from previous releases, kept for - * backwards compatibility: +/** + * Timer output compare modes. */ +typedef enum timer_ic_input_select { + TIMER_IC_INPUT_DEFAULT = TIMER_CCMR_CCS_INPUT_TI1, + TIMER_IC_INPUT_SWITCH = TIMER_CCMR_CCS_INPUT_TI2, + TIMER_IC_INPUT_TRC = TIMER_CCMR_CCS_INPUT_TRC, +} timer_ic_input_select; + +extern void input_capture_mode(timer_dev *dev, uint8 channel, timer_ic_input_select input); -/** Deprecated. Use TIMER_CCMR1_CC4S_OUTPUT instead. */ -#define TIMER_CCMR1_CC4S_OUTPUT TIMER_CCMR2_CC4S_OUTPUT -/** Deprecated. Use TIMER_CCMR1_CC4S_INPUT_TI1 instead. */ -#define TIMER_CCMR1_CC4S_INPUT_TI1 TIMER_CCMR2_CC4S_INPUT_TI1 -/** Deprecated. Use TIMER_CCMR1_CC4S_INPUT_TI2 instead. */ -#define TIMER_CCMR1_CC4S_INPUT_TI2 TIMER_CCMR2_CC4S_INPUT_TI2 -/** Deprecated. Use TIMER_CCMR1_CC4S_INPUT_TRC instead. */ -#define TIMER_CCMR1_CC4S_INPUT_TRC TIMER_CCMR2_CC4S_INPUT_TRC -/** Deprecated. Use TIMER_CCMR2_IC4F instead. */ -#define TIMER_CCMR2_IC2F TIMER_CCMR2_IC4F -/** Deprecated. Use TIMER_CCMR2_IC4PSC instead. */ -#define TIMER_CCMR2_IC2PSC TIMER_CCMR2_IC4PSC -/** Deprecated. Use TIMER_CCMR2_IC3F instead. */ -#define TIMER_CCMR2_IC1F TIMER_CCMR2_IC3F -/** Deprecated. Use TIMER_CCMR2_IC3PSC instead. */ -#define TIMER_CCMR2_IC1PSC TIMER_CCMR2_IC3PSC -/** Deprecated. Use TIMER_CCMR1_CC3S_OUTPUT instead. */ -#define TIMER_CCMR1_CC3S_OUTPUT TIMER_CCMR2_CC3S_OUTPUT -/** Deprecated. Use TIMER_CCMR1_CC3S_INPUT_TI1 instead. */ -#define TIMER_CCMR1_CC3S_INPUT_TI1 TIMER_CCMR2_CC3S_INPUT_TI1 -/** Deprecated. Use TIMER_CCMR1_CC3S_INPUT_TI2 instead. */ -#define TIMER_CCMR1_CC3S_INPUT_TI2 TIMER_CCMR2_CC3S_INPUT_TI2 -/** Deprecated. Use TIMER_CCMR1_CC3S_INPUT_TRC instead. */ -#define TIMER_CCMR1_CC3S_INPUT_TRC TIMER_CCMR2_CC3S_INPUT_TRC - -/** Deprecated. Use TIMER_DCR_DBL_1_XFER instead. */ -#define TIMER_DCR_DBL_1BYTE TIMER_DCR_DBL_1_XFER -/** Deprecated. Use TIMER_DCR_DBL_2_XFER instead. */ -#define TIMER_DCR_DBL_2BYTE TIMER_DCR_DBL_2_XFER -/** Deprecated. Use TIMER_DCR_DBL_3_XFER instead. */ -#define TIMER_DCR_DBL_3BYTE TIMER_DCR_DBL_3_XFER -/** Deprecated. Use TIMER_DCR_DBL_4_XFER instead. */ -#define TIMER_DCR_DBL_4BYTE TIMER_DCR_DBL_4_XFER -/** Deprecated. Use TIMER_DCR_DBL_5_XFER instead. */ -#define TIMER_DCR_DBL_5BYTE TIMER_DCR_DBL_5_XFER -/** Deprecated. Use TIMER_DCR_DBL_6_XFER instead. */ -#define TIMER_DCR_DBL_6BYTE TIMER_DCR_DBL_6_XFER -/** Deprecated. Use TIMER_DCR_DBL_7_XFER instead. */ -#define TIMER_DCR_DBL_7BYTE TIMER_DCR_DBL_7_XFER -/** Deprecated. Use TIMER_DCR_DBL_8_XFER instead. */ -#define TIMER_DCR_DBL_8BYTE TIMER_DCR_DBL_8_XFER -/** Deprecated. Use TIMER_DCR_DBL_9_XFER instead. */ -#define TIMER_DCR_DBL_9BYTE TIMER_DCR_DBL_9_XFER -/** Deprecated. Use TIMER_DCR_DBL_10_XFER instead. */ -#define TIMER_DCR_DBL_10BYTE TIMER_DCR_DBL_10_XFER -/** Deprecated. Use TIMER_DCR_DBL_11_XFER instead. */ -#define TIMER_DCR_DBL_11BYTE TIMER_DCR_DBL_11_XFER -/** Deprecated. Use TIMER_DCR_DBL_12_XFER instead. */ -#define TIMER_DCR_DBL_12BYTE TIMER_DCR_DBL_12_XFER -/** Deprecated. Use TIMER_DCR_DBL_13_XFER instead. */ -#define TIMER_DCR_DBL_13BYTE TIMER_DCR_DBL_13_XFER -/** Deprecated. Use TIMER_DCR_DBL_14_XFER instead. */ -#define TIMER_DCR_DBL_14BYTE TIMER_DCR_DBL_14_XFER -/** Deprecated. Use TIMER_DCR_DBL_15_XFER instead. */ -#define TIMER_DCR_DBL_15BYTE TIMER_DCR_DBL_15_XFER -/** Deprecated. Use TIMER_DCR_DBL_16_XFER instead. */ -#define TIMER_DCR_DBL_16BYTE TIMER_DCR_DBL_16_XFER -/** Deprecated. Use TIMER_DCR_DBL_17_XFER instead. */ -#define TIMER_DCR_DBL_17BYTE TIMER_DCR_DBL_17_XFER -/** Deprecated. Use TIMER_DCR_DBL_18_XFER instead. */ -#define TIMER_DCR_DBL_18BYTE TIMER_DCR_DBL_18_XFER #ifdef __cplusplus } // extern "C" diff --git a/STM32F1/system/libmaple/include/libmaple/usart.h b/STM32F1/system/libmaple/include/libmaple/usart.h index 245ddab16..9a868df43 100644 --- a/STM32F1/system/libmaple/include/libmaple/usart.h +++ b/STM32F1/system/libmaple/include/libmaple/usart.h @@ -53,13 +53,13 @@ extern "C"{ /** USART register map type */ typedef struct usart_reg_map { - __io uint32 SR; /**< Status register */ - __io uint32 DR; /**< Data register */ - __io uint32 BRR; /**< Baud rate register */ - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 CR3; /**< Control register 3 */ - __io uint32 GTPR; /**< Guard time and prescaler register */ + __IO uint32 SR; /**< Status register */ + __IO uint32 DR; /**< Data register */ + __IO uint32 BRR; /**< Baud rate register */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ + __IO uint32 CR3; /**< Control register 3 */ + __IO uint32 GTPR; /**< Guard time and prescaler register */ } usart_reg_map; /* diff --git a/STM32F1/system/libmaple/include/libmaple/usb.h b/STM32F1/system/libmaple/include/libmaple/usb.h index ea24030d4..3dea0e2d8 100644 --- a/STM32F1/system/libmaple/include/libmaple/usb.h +++ b/STM32F1/system/libmaple/include/libmaple/usb.h @@ -123,6 +123,7 @@ typedef struct usb_descriptor_string { #define USB_EP_TYPE_INTERRUPT 0x03 #define USB_EP_TYPE_BULK 0x02 +#define USB_EP_TYPE_ISO 0x01 #define USB_DESCRIPTOR_ENDPOINT_IN 0x80 #define USB_DESCRIPTOR_ENDPOINT_OUT 0x00 @@ -157,6 +158,8 @@ typedef struct usblib_dev { extern usblib_dev *USBLIB; +void usb_power_off(void); + void usb_init_usblib(usblib_dev *dev, void (**ep_int_in)(void), void (**ep_int_out)(void)); diff --git a/STM32F1/system/libmaple/include/libmaple/usb_cdcacm.h b/STM32F1/system/libmaple/include/libmaple/usb_cdcacm.h index 62c9181cd..8099ac43b 100644 --- a/STM32F1/system/libmaple/include/libmaple/usb_cdcacm.h +++ b/STM32F1/system/libmaple/include/libmaple/usb_cdcacm.h @@ -129,10 +129,13 @@ uint32 usb_cdcacm_peek_ex(uint8* buf, uint32 offset, uint32 len); uint32 usb_cdcacm_data_available(void); /* in RX buffer */ uint16 usb_cdcacm_get_pending(void); uint8 usb_cdcacm_is_transmitting(void); +int usb_cdcacm_tx_available(); uint8 usb_cdcacm_get_dtr(void); uint8 usb_cdcacm_get_rts(void); + + typedef struct usb_cdcacm_line_coding { uint32 dwDTERate; /* Baud rate */ @@ -169,7 +172,7 @@ int usb_cdcacm_get_n_data_bits(void); /* bDataBits */ void usb_cdcacm_set_hooks(unsigned hook_flags, void (*hook)(unsigned, void*)); -static inline __always_inline void usb_cdcacm_remove_hooks(unsigned hook_flags) { +inline void usb_cdcacm_remove_hooks(unsigned hook_flags) { usb_cdcacm_set_hooks(hook_flags, 0); } diff --git a/STM32F1/system/libmaple/rcc_private.h b/STM32F1/system/libmaple/rcc_private.h index afb8a3145..a47afca1a 100644 --- a/STM32F1/system/libmaple/rcc_private.h +++ b/STM32F1/system/libmaple/rcc_private.h @@ -40,16 +40,16 @@ struct rcc_dev_info { extern const struct rcc_dev_info rcc_dev_table[]; -static inline void rcc_do_clk_enable(__io uint32** enable_regs, +static inline void rcc_do_clk_enable(__IO uint32** enable_regs, rcc_clk_id id) { - __io uint32 *enable_reg = enable_regs[rcc_dev_clk(id)]; + __IO uint32 *enable_reg = enable_regs[rcc_dev_clk(id)]; uint8 line_num = rcc_dev_table[id].line_num; bb_peri_set_bit(enable_reg, line_num, 1); } -static inline void rcc_do_reset_dev(__io uint32** reset_regs, +static inline void rcc_do_reset_dev(__IO uint32** reset_regs, rcc_clk_id id) { - __io uint32 *reset_reg = reset_regs[rcc_dev_clk(id)]; + __IO uint32 *reset_reg = reset_regs[rcc_dev_clk(id)]; uint8 line_num = rcc_dev_table[id].line_num; bb_peri_set_bit(reset_reg, line_num, 1); bb_peri_set_bit(reset_reg, line_num, 0); @@ -64,9 +64,9 @@ static inline void rcc_do_set_prescaler(const uint32 *masks, RCC_BASE->CFGR = cfgr; } -static inline void rcc_do_clk_disable(__io uint32** enable_regs, +static inline void rcc_do_clk_disable(__IO uint32** enable_regs, rcc_clk_id id) { - __io uint32 *enable_reg = enable_regs[rcc_dev_clk(id)]; + __IO uint32 *enable_reg = enable_regs[rcc_dev_clk(id)]; uint8 line_num = rcc_dev_table[id].line_num; bb_peri_set_bit(enable_reg, line_num, 0); } diff --git a/STM32F1/system/libmaple/stm32f1/include/series/dac.h b/STM32F1/system/libmaple/stm32f1/include/series/dac.h index c0d026b4a..5bf4b9e08 100644 --- a/STM32F1/system/libmaple/stm32f1/include/series/dac.h +++ b/STM32F1/system/libmaple/stm32f1/include/series/dac.h @@ -40,28 +40,28 @@ extern "C"{ /** STM32F1 DAC register map type. */ typedef struct dac_reg_map { - __io uint32 CR; /**< Control register */ - __io uint32 SWTRIGR; /**< Software trigger register */ - __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data + __IO uint32 CR; /**< Control register */ + __IO uint32 SWTRIGR; /**< Software trigger register */ + __IO uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data holding register */ - __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data + __IO uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data holding register */ - __io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data + __IO uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data holding register */ - __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data + __IO uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data holding register */ - __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data + __IO uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data holding register */ - __io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data + __IO uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data holding register */ - __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data + __IO uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data holding register */ - __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data + __IO uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data holding register */ - __io uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding + __IO uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding register */ - __io uint32 DOR1; /**< Channel 1 data output register */ - __io uint32 DOR2; /**< Channel 2 data output register */ + __IO uint32 DOR1; /**< Channel 1 data output register */ + __IO uint32 DOR2; /**< Channel 2 data output register */ } dac_reg_map; #ifdef __cplusplus diff --git a/STM32F1/system/libmaple/stm32f1/include/series/dma.h b/STM32F1/system/libmaple/stm32f1/include/series/dma.h index 56e559ba9..5260f8e16 100644 --- a/STM32F1/system/libmaple/stm32f1/include/series/dma.h +++ b/STM32F1/system/libmaple/stm32f1/include/series/dma.h @@ -57,42 +57,42 @@ extern "C"{ * only supports channels 1--5. */ typedef struct dma_reg_map { - __io uint32 ISR; /**< Interrupt status register */ - __io uint32 IFCR; /**< Interrupt flag clear register */ - __io uint32 CCR1; /**< Channel 1 configuration register */ - __io uint32 CNDTR1; /**< Channel 1 number of data register */ - __io uint32 CPAR1; /**< Channel 1 peripheral address register */ - __io uint32 CMAR1; /**< Channel 1 memory address register */ + __IO uint32 ISR; /**< Interrupt status register */ + __IO uint32 IFCR; /**< Interrupt flag clear register */ + __IO uint32 CCR1; /**< Channel 1 configuration register */ + __IO uint32 CNDTR1; /**< Channel 1 number of data register */ + __IO uint32 CPAR1; /**< Channel 1 peripheral address register */ + __IO uint32 CMAR1; /**< Channel 1 memory address register */ const uint32 RESERVED1; /**< Reserved. */ - __io uint32 CCR2; /**< Channel 2 configuration register */ - __io uint32 CNDTR2; /**< Channel 2 number of data register */ - __io uint32 CPAR2; /**< Channel 2 peripheral address register */ - __io uint32 CMAR2; /**< Channel 2 memory address register */ + __IO uint32 CCR2; /**< Channel 2 configuration register */ + __IO uint32 CNDTR2; /**< Channel 2 number of data register */ + __IO uint32 CPAR2; /**< Channel 2 peripheral address register */ + __IO uint32 CMAR2; /**< Channel 2 memory address register */ const uint32 RESERVED2; /**< Reserved. */ - __io uint32 CCR3; /**< Channel 3 configuration register */ - __io uint32 CNDTR3; /**< Channel 3 number of data register */ - __io uint32 CPAR3; /**< Channel 3 peripheral address register */ - __io uint32 CMAR3; /**< Channel 3 memory address register */ + __IO uint32 CCR3; /**< Channel 3 configuration register */ + __IO uint32 CNDTR3; /**< Channel 3 number of data register */ + __IO uint32 CPAR3; /**< Channel 3 peripheral address register */ + __IO uint32 CMAR3; /**< Channel 3 memory address register */ const uint32 RESERVED3; /**< Reserved. */ - __io uint32 CCR4; /**< Channel 4 configuration register */ - __io uint32 CNDTR4; /**< Channel 4 number of data register */ - __io uint32 CPAR4; /**< Channel 4 peripheral address register */ - __io uint32 CMAR4; /**< Channel 4 memory address register */ + __IO uint32 CCR4; /**< Channel 4 configuration register */ + __IO uint32 CNDTR4; /**< Channel 4 number of data register */ + __IO uint32 CPAR4; /**< Channel 4 peripheral address register */ + __IO uint32 CMAR4; /**< Channel 4 memory address register */ const uint32 RESERVED4; /**< Reserved. */ - __io uint32 CCR5; /**< Channel 5 configuration register */ - __io uint32 CNDTR5; /**< Channel 5 number of data register */ - __io uint32 CPAR5; /**< Channel 5 peripheral address register */ - __io uint32 CMAR5; /**< Channel 5 memory address register */ + __IO uint32 CCR5; /**< Channel 5 configuration register */ + __IO uint32 CNDTR5; /**< Channel 5 number of data register */ + __IO uint32 CPAR5; /**< Channel 5 peripheral address register */ + __IO uint32 CMAR5; /**< Channel 5 memory address register */ const uint32 RESERVED5; /**< Reserved. */ - __io uint32 CCR6; /**< Channel 6 configuration register */ - __io uint32 CNDTR6; /**< Channel 6 number of data register */ - __io uint32 CPAR6; /**< Channel 6 peripheral address register */ - __io uint32 CMAR6; /**< Channel 6 memory address register */ + __IO uint32 CCR6; /**< Channel 6 configuration register */ + __IO uint32 CNDTR6; /**< Channel 6 number of data register */ + __IO uint32 CPAR6; /**< Channel 6 peripheral address register */ + __IO uint32 CMAR6; /**< Channel 6 memory address register */ const uint32 RESERVED6; /**< Reserved. */ - __io uint32 CCR7; /**< Channel 7 configuration register */ - __io uint32 CNDTR7; /**< Channel 7 number of data register */ - __io uint32 CPAR7; /**< Channel 7 peripheral address register */ - __io uint32 CMAR7; /**< Channel 7 memory address register */ + __IO uint32 CCR7; /**< Channel 7 configuration register */ + __IO uint32 CNDTR7; /**< Channel 7 number of data register */ + __IO uint32 CPAR7; /**< Channel 7 peripheral address register */ + __IO uint32 CMAR7; /**< Channel 7 memory address register */ const uint32 RESERVED7; /**< Reserved. */ } dma_reg_map; @@ -107,10 +107,10 @@ typedef struct dma_reg_map { * @see dma_tube_regs() */ typedef struct dma_tube_reg_map { - __io uint32 CCR; /**< Channel configuration register */ - __io uint32 CNDTR; /**< Channel number of data register */ - __io uint32 CPAR; /**< Channel peripheral address register */ - __io uint32 CMAR; /**< Channel memory address register */ + __IO uint32 CCR; /**< Channel configuration register */ + __IO uint32 CNDTR; /**< Channel number of data register */ + __IO uint32 CPAR; /**< Channel peripheral address register */ + __IO uint32 CMAR; /**< Channel memory address register */ } dma_tube_reg_map; /** DMA1 channel 1 register map base pointer */ @@ -516,7 +516,7 @@ typedef enum dma_request_src { #define DMA_CHANNEL_NREGS 5 /* accounts for reserved word */ static inline dma_tube_reg_map* dma_tube_regs(dma_dev *dev, dma_tube tube) { - __io uint32 *ccr1 = &dev->regs->CCR1; + __IO uint32 *ccr1 = &dev->regs->CCR1; return (dma_channel_reg_map*)(ccr1 + DMA_CHANNEL_NREGS * (tube - 1)); } @@ -538,6 +538,10 @@ static inline void dma_clear_isr_bits(dma_dev *dev, dma_tube tube) { dev->regs->IFCR = (1U << (4 * (tube - 1))); } +static inline uint16 dma_get_count(dma_dev *dev, dma_tube tube) { + return dma_channel_regs(dev, tube)->CNDTR; +} + /** * @brief Deprecated * STM32F1 mode flags for dma_setup_xfer(). Use dma_tube_cfg() instead. @@ -561,9 +565,9 @@ typedef enum dma_mode_flags { * this information, so this interface is too tied to the F1.) */ void dma_setup_transfer(dma_dev *dev, dma_channel channel, - __io void *peripheral_address, + __IO void *peripheral_address, dma_xfer_size peripheral_size, - __io void *memory_address, + __IO void *memory_address, dma_xfer_size memory_size, uint32 mode); diff --git a/STM32F1/system/libmaple/stm32f1/include/series/flash.h b/STM32F1/system/libmaple/stm32f1/include/series/flash.h index 24efb0bd7..0ed43c6a8 100644 --- a/STM32F1/system/libmaple/stm32f1/include/series/flash.h +++ b/STM32F1/system/libmaple/stm32f1/include/series/flash.h @@ -48,14 +48,14 @@ extern "C"{ /** @brief STM32F1 Flash register map type */ typedef struct flash_reg_map { - __io uint32 ACR; /**< Access control register */ - __io uint32 KEYR; /**< Key register */ - __io uint32 OPTKEYR; /**< OPTKEY register */ - __io uint32 SR; /**< Status register */ - __io uint32 CR; /**< Control register */ - __io uint32 AR; /**< Address register */ - __io uint32 OBR; /**< Option byte register */ - __io uint32 WRPR; /**< Write protection register */ + __IO uint32 ACR; /**< Access control register */ + __IO uint32 KEYR; /**< Key register */ + __IO uint32 OPTKEYR; /**< OPTKEY register */ + __IO uint32 SR; /**< Status register */ + __IO uint32 CR; /**< Control register */ + __IO uint32 AR; /**< Address register */ + __IO uint32 OBR; /**< Option byte register */ + __IO uint32 WRPR; /**< Write protection register */ } flash_reg_map; #define FLASH_BASE ((struct flash_reg_map*)0x40022000) @@ -132,7 +132,7 @@ typedef struct flash_reg_map { * Series-specific configuration values. */ -#define FLASH_SAFE_WAIT_STATES FLASH_WAIT_STATE_2 +#define FLASH_SAFE_WAIT_STATES (F_CPU > 48000000 ? FLASH_WAIT_STATE_2 : F_CPU > 24000000 ? FLASH_WAIT_STATE_1 : FLASH_WAIT_STATE_0) /* Flash memory features available via ACR */ enum { diff --git a/STM32F1/system/libmaple/stm32f1/include/series/gpio.h b/STM32F1/system/libmaple/stm32f1/include/series/gpio.h index aff639b4b..3819500c5 100644 --- a/STM32F1/system/libmaple/stm32f1/include/series/gpio.h +++ b/STM32F1/system/libmaple/stm32f1/include/series/gpio.h @@ -31,6 +31,7 @@ * General purpose I/O (GPIO) and Alternate Function I/O (AFIO). */ + #ifndef _LIBMAPLE_STM32F1_GPIO_H_ #define _LIBMAPLE_STM32F1_GPIO_H_ @@ -48,15 +49,16 @@ extern "C"{ /** GPIO register map type */ typedef struct gpio_reg_map { - __io uint32 CRL; /**< Port configuration register low */ - __io uint32 CRH; /**< Port configuration register high */ - __io uint32 IDR; /**< Port input data register */ - __io uint32 ODR; /**< Port output data register */ - __io uint32 BSRR; /**< Port bit set/reset register */ - __io uint32 BRR; /**< Port bit reset register */ - __io uint32 LCKR; /**< Port configuration lock register */ + __IO uint32 CRL; /**< Port configuration register low */ + __IO uint32 CRH; /**< Port configuration register high */ + __IO uint32 IDR; /**< Port input data register */ + __IO uint32 ODR; /**< Port output data register */ + __IO uint32 BSRR; /**< Port bit set/reset register */ + __IO uint32 BRR; /**< Port bit reset register */ + __IO uint32 LCKR; /**< Port configuration lock register */ } gpio_reg_map; + struct gpio_dev; extern struct gpio_dev gpioa; extern struct gpio_dev* const GPIOA; @@ -66,7 +68,7 @@ extern struct gpio_dev gpioc; extern struct gpio_dev* const GPIOC; extern struct gpio_dev gpiod; extern struct gpio_dev* const GPIOD; -#ifdef STM32_HIGH_DENSITY +#if STM32_NR_GPIO_PORTS > 4 extern struct gpio_dev gpioe; extern struct gpio_dev* const GPIOE; extern struct gpio_dev gpiof; @@ -145,13 +147,13 @@ typedef enum gpio_pin_mode { /** AFIO register map */ typedef struct afio_reg_map { - __io uint32 EVCR; /**< Event control register. */ - __io uint32 MAPR; /**< AF remap and debug I/O configuration register. */ - __io uint32 EXTICR1; /**< External interrupt configuration register 1. */ - __io uint32 EXTICR2; /**< External interrupt configuration register 2. */ - __io uint32 EXTICR3; /**< External interrupt configuration register 3. */ - __io uint32 EXTICR4; /**< External interrupt configuration register 4. */ - __io uint32 MAPR2; /**< + __IO uint32 EVCR; /**< Event control register. */ + __IO uint32 MAPR; /**< AF remap and debug I/O configuration register. */ + __IO uint32 EXTICR1; /**< External interrupt configuration register 1. */ + __IO uint32 EXTICR2; /**< External interrupt configuration register 2. */ + __IO uint32 EXTICR3; /**< External interrupt configuration register 3. */ + __IO uint32 EXTICR4; /**< External interrupt configuration register 4. */ + __IO uint32 MAPR2; /**< * AF remap and debug I/O configuration register 2. */ } afio_reg_map; @@ -378,6 +380,7 @@ typedef enum afio_remap_peripheral { } afio_remap_peripheral; void afio_remap(afio_remap_peripheral p); +int8_t afio_is_remapped(afio_remap_peripheral p); /** * @brief Debug port configuration @@ -404,7 +407,7 @@ typedef enum afio_debug_cfg { * @see afio_debug_cfg */ static inline void afio_cfg_debug_ports(afio_debug_cfg config) { - __io uint32 *mapr = &AFIO_BASE->MAPR; + __IO uint32 *mapr = &AFIO_BASE->MAPR; *mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config; } @@ -484,7 +487,7 @@ typedef exti_num afio_exti_num; /** * @brief Deprecated. Use exti_select(exti, port) instead. */ -static inline __always_inline void afio_exti_select(exti_num exti, exti_cfg port) { +inline void afio_exti_select(exti_num exti, exti_cfg port) { exti_select(exti, port); } diff --git a/STM32F1/system/libmaple/stm32f1/include/series/i2c.h b/STM32F1/system/libmaple/stm32f1/include/series/i2c.h index 35655036a..ece3b094c 100644 --- a/STM32F1/system/libmaple/stm32f1/include/series/i2c.h +++ b/STM32F1/system/libmaple/stm32f1/include/series/i2c.h @@ -64,8 +64,10 @@ static inline uint32 _i2c_bus_clk(i2c_dev *dev __attribute__((unused))) { return STM32_PCLK1 / (1000 * 1000); } +#ifndef _I2C_HAVE_IRQ_FIXUP // Allow disabling of the fixup via external define #define _I2C_HAVE_IRQ_FIXUP 1 void _i2c_irq_priority_fixup(i2c_dev *dev); +#endif /* * Deprecated functionality diff --git a/STM32F1/system/libmaple/stm32f1/include/series/rcc.h b/STM32F1/system/libmaple/stm32f1/include/series/rcc.h index f40dcbaba..3b26ddb85 100644 --- a/STM32F1/system/libmaple/stm32f1/include/series/rcc.h +++ b/STM32F1/system/libmaple/stm32f1/include/series/rcc.h @@ -46,16 +46,16 @@ extern "C"{ /** STM32F1 RCC register map type */ typedef struct rcc_reg_map { - __io uint32 CR; /**< Clock control register */ - __io uint32 CFGR; /**< Clock configuration register */ - __io uint32 CIR; /**< Clock interrupt register */ - __io uint32 APB2RSTR; /**< APB2 peripheral reset register */ - __io uint32 APB1RSTR; /**< APB1 peripheral reset register */ - __io uint32 AHBENR; /**< AHB peripheral clock enable register */ - __io uint32 APB2ENR; /**< APB2 peripheral clock enable register */ - __io uint32 APB1ENR; /**< APB1 peripheral clock enable register */ - __io uint32 BDCR; /**< Backup domain control register */ - __io uint32 CSR; /**< Control/status register */ + __IO uint32 CR; /**< Clock control register */ + __IO uint32 CFGR; /**< Clock configuration register */ + __IO uint32 CIR; /**< Clock interrupt register */ + __IO uint32 APB2RSTR; /**< APB2 peripheral reset register */ + __IO uint32 APB1RSTR; /**< APB1 peripheral reset register */ + __IO uint32 AHBENR; /**< AHB peripheral clock enable register */ + __IO uint32 APB2ENR; /**< APB2 peripheral clock enable register */ + __IO uint32 APB1ENR; /**< APB1 peripheral clock enable register */ + __IO uint32 BDCR; /**< Backup domain control register */ + __IO uint32 CSR; /**< Control/status register */ } rcc_reg_map; #define RCC_BASE ((struct rcc_reg_map*)0x40021000) @@ -353,7 +353,7 @@ typedef struct rcc_reg_map { #define RCC_BDCR_LSEON_BIT 0 #define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT) -#define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTC_BIT) +#define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTCEN_BIT) #define RCC_BDCR_RTCSEL (0x3 << 8) #define RCC_BDCR_RTCSEL_NONE (0x0 << 8) #define RCC_BDCR_RTCSEL_LSE (0x1 << 8) @@ -439,6 +439,7 @@ typedef enum rcc_clk_id { RCC_UART4, RCC_UART5, RCC_USB, + RCC_CAN, //! JMD after X893 } rcc_clk_id; /** diff --git a/STM32F1/system/libmaple/stm32f1/include/series/spi.h b/STM32F1/system/libmaple/stm32f1/include/series/spi.h index ec4821c80..82267bdbf 100644 --- a/STM32F1/system/libmaple/stm32f1/include/series/spi.h +++ b/STM32F1/system/libmaple/stm32f1/include/series/spi.h @@ -75,13 +75,13 @@ extern void spi_config_gpios(struct spi_dev*, uint8, * @brief Deprecated. Use spi_config_gpios() instead. * @see spi_config_gpios() */ -static inline __always_inline void spi_gpio_cfg(uint8 as_master, - struct gpio_dev *nss_dev, - uint8 nss_bit, - struct gpio_dev *comm_dev, - uint8 sck_bit, - uint8 miso_bit, - uint8 mosi_bit) { +inline void spi_gpio_cfg(uint8 as_master, + struct gpio_dev *nss_dev, + uint8 nss_bit, + struct gpio_dev *comm_dev, + uint8 sck_bit, + uint8 miso_bit, + uint8 mosi_bit) { /* We switched style globally to foo_config_gpios() and always * taking a foo_dev* argument (that last bit is the important * part) after this function was written. diff --git a/STM32F1/system/libmaple/stm32f1/include/series/stm32.h b/STM32F1/system/libmaple/stm32f1/include/series/stm32.h index 9386dc313..e656f3e42 100644 --- a/STM32F1/system/libmaple/stm32f1/include/series/stm32.h +++ b/STM32F1/system/libmaple/stm32f1/include/series/stm32.h @@ -89,6 +89,13 @@ extern "C" { # define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE # define STM32_MEDIUM_DENSITY +#elif defined(MCU_STM32F103C6) +# define STM32_NR_GPIO_PORTS 3 +# define STM32_SRAM_END ((void*)0x20002800) +# define NR_GPIO_PORTS STM32_NR_GPIO_PORTS +# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE +# define STM32_MEDIUM_DENSITY // this is actually a low density device, but it is very close to the C8 + #elif defined(MCU_STM32F103CB) # define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE /* This STM32_NR_GPIO_PORTS is not true, but only pins 0 and @@ -185,12 +192,20 @@ extern "C" { # elif defined(STM32_HIGH_DENSITY) # define STM32_NR_INTERRUPTS 60 # define STM32_TIMER_MASK 0x1FE /* TIMER1--TIMER8 */ -# define STM32_HAVE_FSMC 1 +# if STM32_NR_GPIO_PORTS > 4 +# define STM32_HAVE_FSMC 1 +# else +# define STM32_HAVE_FSMC 0 +# endif # define STM32_HAVE_DAC 1 # elif defined(STM32_XL_DENSITY) # define STM32_NR_INTERRUPTS 60 # define STM32_TIMER_MASK 0x7FFE /* TIMER1--TIMER14 */ -# define STM32_HAVE_FSMC 1 +# if STM32_NR_GPIO_PORTS > 4 +# define STM32_HAVE_FSMC 1 +# else +# define STM32_HAVE_FSMC 0 +# endif # define STM32_HAVE_DAC 1 # endif diff --git a/STM32F1/system/libmaple/stm32f1/include/series/timer.h b/STM32F1/system/libmaple/stm32f1/include/series/timer.h index 8c1f8f4d9..c07b7b470 100644 --- a/STM32F1/system/libmaple/stm32f1/include/series/timer.h +++ b/STM32F1/system/libmaple/stm32f1/include/series/timer.h @@ -41,26 +41,26 @@ /** STM32F1 general purpose timer register map type */ typedef struct timer_gen_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SMCR; /**< Slave mode control register */ - __io uint32 DIER; /**< DMA/Interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - __io uint32 CCMR1; /**< Capture/compare mode register 1 */ - __io uint32 CCMR2; /**< Capture/compare mode register 2 */ - __io uint32 CCER; /**< Capture/compare enable register */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ + __IO uint32 SMCR; /**< Slave mode control register */ + __IO uint32 DIER; /**< DMA/Interrupt enable register */ + __IO uint32 SR; /**< Status register */ + __IO uint32 EGR; /**< Event generation register */ + __IO uint32 CCMR1; /**< Capture/compare mode register 1 */ + __IO uint32 CCMR2; /**< Capture/compare mode register 2 */ + __IO uint32 CCER; /**< Capture/compare enable register */ + __IO uint32 CNT; /**< Counter */ + __IO uint32 PSC; /**< Prescaler */ + __IO uint32 ARR; /**< Auto-reload register */ const uint32 RESERVED1; /**< Reserved */ - __io uint32 CCR1; /**< Capture/compare register 1 */ - __io uint32 CCR2; /**< Capture/compare register 2 */ - __io uint32 CCR3; /**< Capture/compare register 3 */ - __io uint32 CCR4; /**< Capture/compare register 4 */ + __IO uint32 CCR1; /**< Capture/compare register 1 */ + __IO uint32 CCR2; /**< Capture/compare register 2 */ + __IO uint32 CCR3; /**< Capture/compare register 3 */ + __IO uint32 CCR4; /**< Capture/compare register 4 */ const uint32 RESERVED2; /**< Reserved */ - __io uint32 DCR; /**< DMA control register */ - __io uint32 DMAR; /**< DMA address for full transfer */ + __IO uint32 DCR; /**< DMA control register */ + __IO uint32 DMAR; /**< DMA address for full transfer */ } timer_gen_reg_map; struct timer_adv_reg_map; diff --git a/STM32F1/system/libmaple/stm32f2/include/series/adc.h b/STM32F1/system/libmaple/stm32f2/include/series/adc.h index 175fe112f..3bfa2cc5a 100644 --- a/STM32F1/system/libmaple/stm32f2/include/series/adc.h +++ b/STM32F1/system/libmaple/stm32f2/include/series/adc.h @@ -49,9 +49,9 @@ extern const struct adc_dev *ADC3; /** ADC common register map type */ typedef struct adc_common_reg_map { - __io uint32 CSR; /**< Common status register */ - __io uint32 CCR; /**< Common control register */ - __io uint32 CDR; /**< + __IO uint32 CSR; /**< Common status register */ + __IO uint32 CCR; /**< Common control register */ + __IO uint32 CDR; /**< * @brief Common regular data register * for dual and triple modes */ } adc_common_reg_map; diff --git a/STM32F1/system/libmaple/stm32f2/include/series/dac.h b/STM32F1/system/libmaple/stm32f2/include/series/dac.h index 0a578ca7f..0d74a168e 100644 --- a/STM32F1/system/libmaple/stm32f2/include/series/dac.h +++ b/STM32F1/system/libmaple/stm32f2/include/series/dac.h @@ -44,29 +44,29 @@ extern "C"{ /** STM32F2 DAC register map type. */ typedef struct dac_reg_map { - __io uint32 CR; /**< Control register */ - __io uint32 SWTRIGR; /**< Software trigger register */ - __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data + __IO uint32 CR; /**< Control register */ + __IO uint32 SWTRIGR; /**< Software trigger register */ + __IO uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data holding register */ - __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data + __IO uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data holding register */ - __io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data + __IO uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data holding register */ - __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data + __IO uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data holding register */ - __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data + __IO uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data holding register */ - __io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data + __IO uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data holding register */ - __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data + __IO uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data holding register */ - __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data + __IO uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data holding register */ - __io uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding + __IO uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding register */ - __io uint32 DOR1; /**< Channel 1 data output register */ - __io uint32 DOR2; /**< Channel 2 data output register */ - __io uint32 SR; /**< Status register */ + __IO uint32 DOR1; /**< Channel 1 data output register */ + __IO uint32 DOR2; /**< Channel 2 data output register */ + __IO uint32 SR; /**< Status register */ } dac_reg_map; /* diff --git a/STM32F1/system/libmaple/stm32f2/include/series/dma.h b/STM32F1/system/libmaple/stm32f2/include/series/dma.h index 56725e5e4..1c152fded 100644 --- a/STM32F1/system/libmaple/stm32f2/include/series/dma.h +++ b/STM32F1/system/libmaple/stm32f2/include/series/dma.h @@ -51,66 +51,66 @@ typedef struct dma_reg_map { /* Isn't it nice how on F1, it's CCR1, but on F2, it's S1CR? */ /* Global DMA registers */ - __io uint32 LISR; /**< Low interrupt status register */ - __io uint32 HISR; /**< High interrupt status register */ - __io uint32 LIFCR; /**< Low interrupt flag clear register */ - __io uint32 HIFCR; /**< High interrupt flag clear register */ + __IO uint32 LISR; /**< Low interrupt status register */ + __IO uint32 HISR; /**< High interrupt status register */ + __IO uint32 LIFCR; /**< Low interrupt flag clear register */ + __IO uint32 HIFCR; /**< High interrupt flag clear register */ /* Stream 0 registers */ - __io uint32 S0CR; /**< Stream 0 control register */ - __io uint32 S0NDTR; /**< Stream 0 number of data register */ - __io uint32 S0PAR; /**< Stream 0 peripheral address register */ - __io uint32 S0M0AR; /**< Stream 0 memory 0 address register */ - __io uint32 S0M1AR; /**< Stream 0 memory 1 address register */ - __io uint32 S0FCR; /**< Stream 0 FIFO control register */ + __IO uint32 S0CR; /**< Stream 0 control register */ + __IO uint32 S0NDTR; /**< Stream 0 number of data register */ + __IO uint32 S0PAR; /**< Stream 0 peripheral address register */ + __IO uint32 S0M0AR; /**< Stream 0 memory 0 address register */ + __IO uint32 S0M1AR; /**< Stream 0 memory 1 address register */ + __IO uint32 S0FCR; /**< Stream 0 FIFO control register */ /* Stream 1 registers */ - __io uint32 S1CR; /**< Stream 1 control register */ - __io uint32 S1NDTR; /**< Stream 1 number of data register */ - __io uint32 S1PAR; /**< Stream 1 peripheral address register */ - __io uint32 S1M0AR; /**< Stream 1 memory 0 address register */ - __io uint32 S1M1AR; /**< Stream 1 memory 1 address register */ - __io uint32 S1FCR; /**< Stream 1 FIFO control register */ + __IO uint32 S1CR; /**< Stream 1 control register */ + __IO uint32 S1NDTR; /**< Stream 1 number of data register */ + __IO uint32 S1PAR; /**< Stream 1 peripheral address register */ + __IO uint32 S1M0AR; /**< Stream 1 memory 0 address register */ + __IO uint32 S1M1AR; /**< Stream 1 memory 1 address register */ + __IO uint32 S1FCR; /**< Stream 1 FIFO control register */ /* Stream 2 registers */ - __io uint32 S2CR; /**< Stream 2 control register */ - __io uint32 S2NDTR; /**< Stream 2 number of data register */ - __io uint32 S2PAR; /**< Stream 2 peripheral address register */ - __io uint32 S2M0AR; /**< Stream 2 memory 0 address register */ - __io uint32 S2M1AR; /**< Stream 2 memory 1 address register */ - __io uint32 S2FCR; /**< Stream 2 FIFO control register */ + __IO uint32 S2CR; /**< Stream 2 control register */ + __IO uint32 S2NDTR; /**< Stream 2 number of data register */ + __IO uint32 S2PAR; /**< Stream 2 peripheral address register */ + __IO uint32 S2M0AR; /**< Stream 2 memory 0 address register */ + __IO uint32 S2M1AR; /**< Stream 2 memory 1 address register */ + __IO uint32 S2FCR; /**< Stream 2 FIFO control register */ /* Stream 3 registers */ - __io uint32 S3CR; /**< Stream 3 control register */ - __io uint32 S3NDTR; /**< Stream 3 number of data register */ - __io uint32 S3PAR; /**< Stream 3 peripheral address register */ - __io uint32 S3M0AR; /**< Stream 3 memory 0 address register */ - __io uint32 S3M1AR; /**< Stream 3 memory 1 address register */ - __io uint32 S3FCR; /**< Stream 3 FIFO control register */ + __IO uint32 S3CR; /**< Stream 3 control register */ + __IO uint32 S3NDTR; /**< Stream 3 number of data register */ + __IO uint32 S3PAR; /**< Stream 3 peripheral address register */ + __IO uint32 S3M0AR; /**< Stream 3 memory 0 address register */ + __IO uint32 S3M1AR; /**< Stream 3 memory 1 address register */ + __IO uint32 S3FCR; /**< Stream 3 FIFO control register */ /* Stream 4 registers */ - __io uint32 S4CR; /**< Stream 4 control register */ - __io uint32 S4NDTR; /**< Stream 4 number of data register */ - __io uint32 S4PAR; /**< Stream 4 peripheral address register */ - __io uint32 S4M0AR; /**< Stream 4 memory 0 address register */ - __io uint32 S4M1AR; /**< Stream 4 memory 1 address register */ - __io uint32 S4FCR; /**< Stream 4 FIFO control register */ + __IO uint32 S4CR; /**< Stream 4 control register */ + __IO uint32 S4NDTR; /**< Stream 4 number of data register */ + __IO uint32 S4PAR; /**< Stream 4 peripheral address register */ + __IO uint32 S4M0AR; /**< Stream 4 memory 0 address register */ + __IO uint32 S4M1AR; /**< Stream 4 memory 1 address register */ + __IO uint32 S4FCR; /**< Stream 4 FIFO control register */ /* Stream 5 registers */ - __io uint32 S5CR; /**< Stream 5 control register */ - __io uint32 S5NDTR; /**< Stream 5 number of data register */ - __io uint32 S5PAR; /**< Stream 5 peripheral address register */ - __io uint32 S5M0AR; /**< Stream 5 memory 0 address register */ - __io uint32 S5M1AR; /**< Stream 5 memory 1 address register */ - __io uint32 S5FCR; /**< Stream 5 FIFO control register */ + __IO uint32 S5CR; /**< Stream 5 control register */ + __IO uint32 S5NDTR; /**< Stream 5 number of data register */ + __IO uint32 S5PAR; /**< Stream 5 peripheral address register */ + __IO uint32 S5M0AR; /**< Stream 5 memory 0 address register */ + __IO uint32 S5M1AR; /**< Stream 5 memory 1 address register */ + __IO uint32 S5FCR; /**< Stream 5 FIFO control register */ /* Stream 6 registers */ - __io uint32 S6CR; /**< Stream 6 control register */ - __io uint32 S6NDTR; /**< Stream 6 number of data register */ - __io uint32 S6PAR; /**< Stream 6 peripheral address register */ - __io uint32 S6M0AR; /**< Stream 6 memory 0 address register */ - __io uint32 S6M1AR; /**< Stream 6 memory 1 address register */ - __io uint32 S6FCR; /**< Stream 6 FIFO control register */ + __IO uint32 S6CR; /**< Stream 6 control register */ + __IO uint32 S6NDTR; /**< Stream 6 number of data register */ + __IO uint32 S6PAR; /**< Stream 6 peripheral address register */ + __IO uint32 S6M0AR; /**< Stream 6 memory 0 address register */ + __IO uint32 S6M1AR; /**< Stream 6 memory 1 address register */ + __IO uint32 S6FCR; /**< Stream 6 FIFO control register */ /* Stream 7 registers */ - __io uint32 S7CR; /**< Stream 7 control register */ - __io uint32 S7NDTR; /**< Stream 7 number of data register */ - __io uint32 S7PAR; /**< Stream 7 peripheral address register */ - __io uint32 S7M0AR; /**< Stream 7 memory 0 address register */ - __io uint32 S7M1AR; /**< Stream 7 memory 1 address register */ - __io uint32 S7FCR; /**< Stream 7 FIFO control register */ + __IO uint32 S7CR; /**< Stream 7 control register */ + __IO uint32 S7NDTR; /**< Stream 7 number of data register */ + __IO uint32 S7PAR; /**< Stream 7 peripheral address register */ + __IO uint32 S7M0AR; /**< Stream 7 memory 0 address register */ + __IO uint32 S7M1AR; /**< Stream 7 memory 1 address register */ + __IO uint32 S7FCR; /**< Stream 7 FIFO control register */ } dma_reg_map; /** DMA controller 1 register map base pointer */ @@ -124,12 +124,12 @@ typedef struct dma_reg_map { * @see dma_tube_regs() */ typedef struct dma_tube_reg_map { - __io uint32 SCR; /**< Stream configuration register */ - __io uint32 SNDTR; /**< Stream number of data register */ - __io uint32 SPAR; /**< Stream peripheral address register */ - __io uint32 SM0AR; /**< Stream memory 0 address register */ - __io uint32 SM1AR; /**< Stream memory 1 address register */ - __io uint32 SFCR; /**< Stream FIFO control register */ + __IO uint32 SCR; /**< Stream configuration register */ + __IO uint32 SNDTR; /**< Stream number of data register */ + __IO uint32 SPAR; /**< Stream peripheral address register */ + __IO uint32 SM0AR; /**< Stream memory 0 address register */ + __IO uint32 SM1AR; /**< Stream memory 1 address register */ + __IO uint32 SFCR; /**< Stream FIFO control register */ } dma_tube_reg_map; /** DMA1 stream 0 register map base pointer */ @@ -697,7 +697,7 @@ static inline uint8 dma_is_enabled(dma_dev *dev, dma_tube tube) { /* F2-only; available because of double-buffering. */ void dma_set_mem_n_addr(dma_dev *dev, dma_tube tube, int n, - __io void *address); + __IO void *address); /** * @brief Set memory 0 address. @@ -707,8 +707,7 @@ void dma_set_mem_n_addr(dma_dev *dev, dma_tube tube, int n, * @param tube Tube whose memory 0 address to set * @param addr Address to use as memory 0 */ -static inline __always_inline void -dma_set_mem0_addr(dma_dev *dev, dma_tube tube, __io void *addr) { +inline void dma_set_mem0_addr(dma_dev *dev, dma_tube tube, __IO void *addr) { dma_set_mem_n_addr(dev, tube, 0, addr); } @@ -720,30 +719,29 @@ dma_set_mem0_addr(dma_dev *dev, dma_tube tube, __io void *addr) { * @param tube Tube whose memory 1 address to set * @param addr Address to use as memory 1 */ -static inline __always_inline void -dma_set_mem1_addr(dma_dev *dev, dma_tube tube, __io void *addr) { +inline void dma_set_mem1_addr(dma_dev *dev, dma_tube tube, __IO void *addr) { dma_set_mem_n_addr(dev, tube, 1, addr); } /* Assume the user means SM0AR in a non-double-buffered configuration. */ -static inline __always_inline void -dma_set_mem_addr(dma_dev *dev, dma_tube tube, __io void *addr) { +static __always_inline void +dma_set_mem_addr(dma_dev *dev, dma_tube tube, __IO void *addr) { dma_set_mem0_addr(dev, tube, addr); } /* SM0AR and SM1AR are treated as though they have the same size */ -static inline dma_xfer_size dma_get_mem_size(dma_dev *dev, dma_tube tube) { +inline dma_xfer_size dma_get_mem_size(dma_dev *dev, dma_tube tube) { return (dma_xfer_size)(dma_tube_regs(dev, tube)->SCR >> 13); } -static inline dma_xfer_size dma_get_per_size(dma_dev *dev, dma_tube tube) { +inline dma_xfer_size dma_get_per_size(dma_dev *dev, dma_tube tube) { return (dma_xfer_size)(dma_tube_regs(dev, tube)->SCR >> 11); } void dma_enable_fifo(dma_dev *dev, dma_tube tube); void dma_disable_fifo(dma_dev *dev, dma_tube tube); -static inline __always_inline int dma_is_fifo_enabled(dma_dev *dev, dma_tube tube) { +inline int dma_is_fifo_enabled(dma_dev *dev, dma_tube tube) { return dma_tube_regs(dev, tube)->SFCR & DMA_SFCR_DMDIS; } @@ -769,7 +767,7 @@ static inline __always_inline int dma_is_fifo_enabled(dma_dev *dev, dma_tube tub * I can't imagine why ST didn't just use a byte for each group. The * bits fit, and it would have made functions like these simpler and * faster. Oh well. */ -static inline __always_inline uint32 _dma_sr_fcr_shift(dma_tube tube) { +static __always_inline uint32 _dma_sr_fcr_shift(dma_tube tube) { switch (tube) { case DMA_S0: /* fall through */ case DMA_S4: @@ -791,13 +789,13 @@ static inline __always_inline uint32 _dma_sr_fcr_shift(dma_tube tube) { static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_tube tube) { dma_reg_map *regs = dev->regs; - __io uint32 *isr = tube > DMA_S3 ? ®s->HISR : ®s->LISR; + __IO uint32 *isr = tube > DMA_S3 ? ®s->HISR : ®s->LISR; return (*isr >> _dma_sr_fcr_shift(tube)) & 0x3D; } static inline void dma_clear_isr_bits(dma_dev *dev, dma_tube tube) { dma_reg_map *regs = dev->regs; - __io uint32 *ifcr = tube > DMA_S3 ? ®s->HIFCR : ®s->LIFCR; + __IO uint32 *ifcr = tube > DMA_S3 ? ®s->HIFCR : ®s->LIFCR; *ifcr = (0x3D << _dma_sr_fcr_shift(tube)); } diff --git a/STM32F1/system/libmaple/stm32f2/include/series/flash.h b/STM32F1/system/libmaple/stm32f2/include/series/flash.h index a3c393307..a02d4cac9 100644 --- a/STM32F1/system/libmaple/stm32f2/include/series/flash.h +++ b/STM32F1/system/libmaple/stm32f2/include/series/flash.h @@ -48,12 +48,12 @@ extern "C"{ /** @brief STM32F2 Flash register map type */ typedef struct flash_reg_map { - __io uint32 ACR; /**< Access control register */ - __io uint32 KEYR; /**< Key register */ - __io uint32 OPTKEYR; /**< Option key register */ - __io uint32 SR; /**< Status register */ - __io uint32 CR; /**< Control register */ - __io uint32 OPTCR; /**< Option control register */ + __IO uint32 ACR; /**< Access control register */ + __IO uint32 KEYR; /**< Key register */ + __IO uint32 OPTKEYR; /**< Option key register */ + __IO uint32 SR; /**< Status register */ + __IO uint32 CR; /**< Control register */ + __IO uint32 OPTCR; /**< Option control register */ } flash_reg_map; #define FLASH_BASE ((struct flash_reg_map*)0x40023C00) diff --git a/STM32F1/system/libmaple/stm32f2/include/series/gpio.h b/STM32F1/system/libmaple/stm32f2/include/series/gpio.h index 4d0d98cc8..13d83662d 100644 --- a/STM32F1/system/libmaple/stm32f2/include/series/gpio.h +++ b/STM32F1/system/libmaple/stm32f2/include/series/gpio.h @@ -44,16 +44,16 @@ extern "C"{ /** GPIO register map type */ typedef struct gpio_reg_map { - __io uint32 MODER; /**< Mode register */ - __io uint32 OTYPER; /**< Output type register */ - __io uint32 OSPEEDR; /**< Output speed register */ - __io uint32 PUPDR; /**< Pull-up/pull-down register */ - __io uint32 IDR; /**< Input data register */ - __io uint32 ODR; /**< Output data register */ - __io uint32 BSRR; /**< Bit set/reset register */ - __io uint32 LCKR; /**< Configuration lock register */ - __io uint32 AFRL; /**< Alternate function low register */ - __io uint32 AFRH; /**< Alternate function high register */ + __IO uint32 MODER; /**< Mode register */ + __IO uint32 OTYPER; /**< Output type register */ + __IO uint32 OSPEEDR; /**< Output speed register */ + __IO uint32 PUPDR; /**< Pull-up/pull-down register */ + __IO uint32 IDR; /**< Input data register */ + __IO uint32 ODR; /**< Output data register */ + __IO uint32 BSRR; /**< Bit set/reset register */ + __IO uint32 LCKR; /**< Configuration lock register */ + __IO uint32 AFRL; /**< Alternate function low register */ + __IO uint32 AFRH; /**< Alternate function high register */ } gpio_reg_map; /** GPIO port A register map base pointer */ diff --git a/STM32F1/system/libmaple/stm32f2/include/series/rcc.h b/STM32F1/system/libmaple/stm32f2/include/series/rcc.h index 441a5a80d..eae4d4223 100644 --- a/STM32F1/system/libmaple/stm32f2/include/series/rcc.h +++ b/STM32F1/system/libmaple/stm32f2/include/series/rcc.h @@ -44,46 +44,46 @@ extern "C"{ /** STM32F2 RCC register map type */ typedef struct rcc_reg_map { - __io uint32 CR; /**< Clock control register */ - __io uint32 PLLCFGR; /**< PLL configuration register */ - __io uint32 CFGR; /**< Clock configuration register */ - __io uint32 CIR; /**< Clock interrupt register */ - __io uint32 AHB1RSTR; /**< AHB1 peripheral reset register */ - __io uint32 AHB2RSTR; /**< AHB2 peripheral reset register */ - __io uint32 AHB3RSTR; /**< AHB3 peripheral reset register */ + __IO uint32 CR; /**< Clock control register */ + __IO uint32 PLLCFGR; /**< PLL configuration register */ + __IO uint32 CFGR; /**< Clock configuration register */ + __IO uint32 CIR; /**< Clock interrupt register */ + __IO uint32 AHB1RSTR; /**< AHB1 peripheral reset register */ + __IO uint32 AHB2RSTR; /**< AHB2 peripheral reset register */ + __IO uint32 AHB3RSTR; /**< AHB3 peripheral reset register */ const uint32 RESERVED1; /**< Reserved */ - __io uint32 APB1RSTR; /**< APB1 peripheral reset register */ - __io uint32 APB2RSTR; /**< APB2 peripheral reset register */ + __IO uint32 APB1RSTR; /**< APB1 peripheral reset register */ + __IO uint32 APB2RSTR; /**< APB2 peripheral reset register */ const uint32 RESERVED2; /**< Reserved */ const uint32 RESERVED3; /**< Reserved */ - __io uint32 AHB1ENR; /**< AHB1 peripheral clock enable register */ - __io uint32 AHB2ENR; /**< AHB2 peripheral clock enable register */ - __io uint32 AHB3ENR; /**< AHB3 peripheral clock enable register */ + __IO uint32 AHB1ENR; /**< AHB1 peripheral clock enable register */ + __IO uint32 AHB2ENR; /**< AHB2 peripheral clock enable register */ + __IO uint32 AHB3ENR; /**< AHB3 peripheral clock enable register */ const uint32 RESERVED4; /**< Reserved */ - __io uint32 APB1ENR; /**< APB1 peripheral clock enable register */ - __io uint32 APB2ENR; /**< APB2 peripheral clock enable register */ + __IO uint32 APB1ENR; /**< APB1 peripheral clock enable register */ + __IO uint32 APB2ENR; /**< APB2 peripheral clock enable register */ const uint32 RESERVED5; /**< Reserved */ const uint32 RESERVED6; /**< Reserved */ - __io uint32 AHB1LPENR; /**< AHB1 peripheral clock enable in + __IO uint32 AHB1LPENR; /**< AHB1 peripheral clock enable in low power mode register */ - __io uint32 AHB2LPENR; /**< AHB2 peripheral clock enable in + __IO uint32 AHB2LPENR; /**< AHB2 peripheral clock enable in low power mode register */ - __io uint32 AHB3LPENR; /**< AHB3 peripheral clock enable in + __IO uint32 AHB3LPENR; /**< AHB3 peripheral clock enable in low power mode register */ const uint32 RESERVED7; /**< Reserved */ - __io uint32 APB1LPENR; /**< APB1 peripheral clock enable in + __IO uint32 APB1LPENR; /**< APB1 peripheral clock enable in low power mode register */ - __io uint32 APB2LPENR; /**< APB2 peripheral clock enable in + __IO uint32 APB2LPENR; /**< APB2 peripheral clock enable in low power mode register */ const uint32 RESERVED8; /**< Reserved */ const uint32 RESERVED9; /**< Reserved */ - __io uint32 BDCR; /**< Backup domain control register */ - __io uint32 CSR; /**< Clock control and status register */ + __IO uint32 BDCR; /**< Backup domain control register */ + __IO uint32 CSR; /**< Clock control and status register */ const uint32 RESERVED10; /**< Reserved */ const uint32 RESERVED11; /**< Reserved */ - __io uint32 SSCGR; /**< Spread spectrum clock generation + __IO uint32 SSCGR; /**< Spread spectrum clock generation register */ - __io uint32 PLLI2SCFGR; /**< PLLI2S configuration register */ + __IO uint32 PLLI2SCFGR; /**< PLLI2S configuration register */ } rcc_reg_map; #define RCC_BASE ((struct rcc_reg_map*)0x40023800) diff --git a/STM32F1/system/libmaple/stm32f2/include/series/timer.h b/STM32F1/system/libmaple/stm32f2/include/series/timer.h index a7ac27640..94f654756 100644 --- a/STM32F1/system/libmaple/stm32f2/include/series/timer.h +++ b/STM32F1/system/libmaple/stm32f2/include/series/timer.h @@ -47,27 +47,27 @@ * registers. Consult your chip's reference manual for the details. */ typedef struct timer_gen_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SMCR; /**< Slave mode control register */ - __io uint32 DIER; /**< DMA/Interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - __io uint32 CCMR1; /**< Capture/compare mode register 1 */ - __io uint32 CCMR2; /**< Capture/compare mode register 2 */ - __io uint32 CCER; /**< Capture/compare enable register */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ + __IO uint32 SMCR; /**< Slave mode control register */ + __IO uint32 DIER; /**< DMA/Interrupt enable register */ + __IO uint32 SR; /**< Status register */ + __IO uint32 EGR; /**< Event generation register */ + __IO uint32 CCMR1; /**< Capture/compare mode register 1 */ + __IO uint32 CCMR2; /**< Capture/compare mode register 2 */ + __IO uint32 CCER; /**< Capture/compare enable register */ + __IO uint32 CNT; /**< Counter */ + __IO uint32 PSC; /**< Prescaler */ + __IO uint32 ARR; /**< Auto-reload register */ const uint32 RESERVED1; /**< Reserved */ - __io uint32 CCR1; /**< Capture/compare register 1 */ - __io uint32 CCR2; /**< Capture/compare register 2 */ - __io uint32 CCR3; /**< Capture/compare register 3 */ - __io uint32 CCR4; /**< Capture/compare register 4 */ + __IO uint32 CCR1; /**< Capture/compare register 1 */ + __IO uint32 CCR2; /**< Capture/compare register 2 */ + __IO uint32 CCR3; /**< Capture/compare register 3 */ + __IO uint32 CCR4; /**< Capture/compare register 4 */ const uint32 RESERVED2; /**< Reserved */ - __io uint32 DCR; /**< DMA control register */ - __io uint32 DMAR; /**< DMA address for full transfer */ - __io uint32 OR; /**< Option register. */ + __IO uint32 DCR; /**< DMA control register */ + __IO uint32 DMAR; /**< DMA address for full transfer */ + __IO uint32 OR; /**< Option register. */ } timer_gen_reg_map; struct timer_adv_reg_map; diff --git a/STM32F1/system/libmaple/timer_private.h b/STM32F1/system/libmaple/timer_private.h index 55e2cafb3..a2b482b30 100644 --- a/STM32F1/system/libmaple/timer_private.h +++ b/STM32F1/system/libmaple/timer_private.h @@ -121,15 +121,15 @@ * line may be shared with another timer. For example, the timer 1 * update interrupt shares an IRQ line with the timer 10 interrupt on * STM32F1 (XL-density), STM32F2, and STM32F4. */ -static inline __always_inline void dispatch_single_irq(timer_dev *dev, - timer_interrupt_id iid, - uint32 irq_mask) { +static inline void dispatch_single_irq(timer_dev *dev, + timer_interrupt_id iid, + uint32 irq_mask) { timer_bas_reg_map *regs = (dev->regs).bas; if (regs->DIER & regs->SR & irq_mask) { void (*handler)(void) = dev->handlers[iid]; if (handler) { handler(); - regs->SR &= ~irq_mask; + regs->SR = ~irq_mask; } } } @@ -145,15 +145,15 @@ static inline __always_inline void dispatch_single_irq(timer_dev *dev, } \ } while (0) -static inline __always_inline void dispatch_adv_brk(timer_dev *dev) { +static inline void dispatch_adv_brk(timer_dev *dev) { dispatch_single_irq(dev, TIMER_BREAK_INTERRUPT, TIMER_SR_BIF); } -static inline __always_inline void dispatch_adv_up(timer_dev *dev) { +static inline void dispatch_adv_up(timer_dev *dev) { dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); } -static inline __always_inline void dispatch_adv_trg_com(timer_dev *dev) { +static inline void dispatch_adv_trg_com(timer_dev *dev) { timer_adv_reg_map *regs = (dev->regs).adv; uint32 dsr = regs->DIER & regs->SR; void (**hs)(void) = dev->handlers; @@ -165,10 +165,10 @@ static inline __always_inline void dispatch_adv_trg_com(timer_dev *dev) { handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); handle_irq(dsr, TIMER_SR_COMIF, hs, TIMER_COM_INTERRUPT, handled); - regs->SR &= ~handled; + regs->SR = ~handled; } -static inline __always_inline void dispatch_adv_cc(timer_dev *dev) { +static inline void dispatch_adv_cc(timer_dev *dev) { timer_adv_reg_map *regs = (dev->regs).adv; uint32 dsr = regs->DIER & regs->SR; void (**hs)(void) = dev->handlers; @@ -179,10 +179,10 @@ static inline __always_inline void dispatch_adv_cc(timer_dev *dev) { handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); - regs->SR &= ~handled; + regs->SR = ~handled; } -static inline __always_inline void dispatch_general(timer_dev *dev) { +static inline void dispatch_general(timer_dev *dev) { timer_gen_reg_map *regs = (dev->regs).gen; uint32 dsr = regs->DIER & regs->SR; void (**hs)(void) = dev->handlers; @@ -195,12 +195,12 @@ static inline __always_inline void dispatch_general(timer_dev *dev) { handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); - regs->SR &= ~handled; + regs->SR = ~handled; } /* On F1 (XL-density), F2, and F4, TIM9 and TIM12 are restricted * general-purpose timers with update, CC1, CC2, and TRG interrupts. */ -static inline __always_inline void dispatch_tim_9_12(timer_dev *dev) { +inline void dispatch_tim_9_12(timer_dev *dev) { timer_gen_reg_map *regs = (dev->regs).gen; uint32 dsr = regs->DIER & regs->SR; void (**hs)(void) = dev->handlers; @@ -211,12 +211,12 @@ static inline __always_inline void dispatch_tim_9_12(timer_dev *dev) { handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); - regs->SR &= ~handled; + regs->SR = ~handled; } /* On F1 (XL-density), F2, and F4, timers 10, 11, 13, and 14 are * restricted general-purpose timers with update and CC1 interrupts. */ -static inline __always_inline void dispatch_tim_10_11_13_14(timer_dev *dev) { +inline void dispatch_tim_10_11_13_14(timer_dev *dev) { timer_gen_reg_map *regs = (dev->regs).gen; uint32 dsr = regs->DIER & regs->SR; void (**hs)(void) = dev->handlers; @@ -225,10 +225,10 @@ static inline __always_inline void dispatch_tim_10_11_13_14(timer_dev *dev) { handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); - regs->SR &= ~handled; + regs->SR = ~handled; } -static inline __always_inline void dispatch_basic(timer_dev *dev) { +static inline void dispatch_basic(timer_dev *dev) { dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); } diff --git a/STM32F1/system/libmaple/usart_private.h b/STM32F1/system/libmaple/usart_private.h index 34aaf4b3a..a340312da 100644 --- a/STM32F1/system/libmaple/usart_private.h +++ b/STM32F1/system/libmaple/usart_private.h @@ -37,21 +37,26 @@ #include #include -static inline __always_inline void usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs) { +static inline void usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs) { /* Handling RXNEIE and TXEIE interrupts. * RXNE signifies availability of a byte in DR. * * See table 198 (sec 27.4, p809) in STM document RM0008 rev 15. * We enable RXNEIE. */ if ((regs->CR1 & USART_CR1_RXNEIE) && (regs->SR & USART_SR_RXNE)) { + if( regs->SR & USART_SR_FE || regs->SR & USART_SR_PE ) { + // framing error or parity error + regs->DR; //read and throw away the data, this clears FE and PE as well + } else { #ifdef USART_SAFE_INSERT - /* If the buffer is full and the user defines USART_SAFE_INSERT, - * ignore new bytes. */ - rb_safe_insert(rb, (uint8)regs->DR); + /* If the buffer is full and the user defines USART_SAFE_INSERT, + * ignore new bytes. */ + rb_safe_insert(rb, (uint8)regs->DR); #else - /* By default, push bytes around in the ring buffer. */ - rb_push_insert(rb, (uint8)regs->DR); + /* By default, push bytes around in the ring buffer. */ + rb_push_insert(rb, (uint8)regs->DR); #endif + } } /* TXE signifies readiness to send a byte to DR. */ if ((regs->CR1 & USART_CR1_TXEIE) && (regs->SR & USART_SR_TXE)) { diff --git a/STM32F1/system/libmaple/usb/stm32f1/usb_reg_map.h b/STM32F1/system/libmaple/usb/stm32f1/usb_reg_map.h index d0423fc11..0f9da069d 100644 --- a/STM32F1/system/libmaple/usb/stm32f1/usb_reg_map.h +++ b/STM32F1/system/libmaple/usb/stm32f1/usb_reg_map.h @@ -42,13 +42,13 @@ /** USB register map type */ typedef struct usb_reg_map { - __io uint32 EP[USB_NR_EP_REGS]; /**< Endpoint registers */ + __IO uint32 EP[USB_NR_EP_REGS]; /**< Endpoint registers */ const uint32 RESERVED[8]; /**< Reserved */ - __io uint32 CNTR; /**< Control register */ - __io uint32 ISTR; /**< Interrupt status register */ - __io uint32 FNR; /**< Frame number register */ - __io uint32 DADDR; /**< Device address */ - __io uint32 BTABLE; /**< @brief Buffer table address + __IO uint32 CNTR; /**< Control register */ + __IO uint32 ISTR; /**< Interrupt status register */ + __IO uint32 FNR; /**< Frame number register */ + __IO uint32 DADDR; /**< Device address */ + __IO uint32 BTABLE; /**< @brief Buffer table address * * Address offset within the USB * packet memory area which points @@ -340,7 +340,7 @@ static inline void usb_clear_status_out(uint8 ep) { * * The USB PMA is SRAM shared between USB and CAN. The USB peripheral * accesses this memory directly via the packet buffer interface. */ -#define USB_PMA_BASE ((__io void*)0x40006000) +#define USB_PMA_BASE ((__IO void*)0x40006000) /* * PMA conveniences @@ -350,7 +350,7 @@ void usb_copy_to_pma(const uint8 *buf, uint16 len, uint16 pma_offset); void usb_copy_from_pma(uint8 *buf, uint16 len, uint16 pma_offset); */ static inline uint32 * usb_pma_ptr(uint32 offset) { - return (uint32*)(USB_PMA_BASE + 2 * offset); + return (uint32*)((uint8*)USB_PMA_BASE + 2 * offset); } /* @@ -367,42 +367,42 @@ union usb_btable_ent; /* Bidirectional endpoint BTABLE entry */ typedef struct usb_btable_bidi { - __io uint16 addr_tx; const uint16 PAD1; - __io uint16 count_tx; const uint16 PAD2; - __io uint16 addr_rx; const uint16 PAD3; - __io uint16 count_rx; const uint16 PAD4; + __IO uint16 addr_tx; const uint16 PAD1; + __IO uint16 count_tx; const uint16 PAD2; + __IO uint16 addr_rx; const uint16 PAD3; + __IO uint16 count_rx; const uint16 PAD4; } usb_btable_bidi; /* Unidirectional receive-only endpoint BTABLE entry */ typedef struct usb_btable_uni_rx { - __io uint16 empty1; const uint16 PAD1; - __io uint16 empty2; const uint16 PAD2; - __io uint16 addr_rx; const uint16 PAD3; - __io uint16 count_rx; const uint16 PAD4; + __IO uint16 empty1; const uint16 PAD1; + __IO uint16 empty2; const uint16 PAD2; + __IO uint16 addr_rx; const uint16 PAD3; + __IO uint16 count_rx; const uint16 PAD4; } usb_btable_uni_rx; /* Unidirectional transmit-only endpoint BTABLE entry */ typedef struct usb_btable_uni_tx { - __io uint16 addr_tx; const uint16 PAD1; - __io uint16 count_tx; const uint16 PAD2; - __io uint16 empty1; const uint16 PAD3; - __io uint16 empty2; const uint16 PAD4; + __IO uint16 addr_tx; const uint16 PAD1; + __IO uint16 count_tx; const uint16 PAD2; + __IO uint16 empty1; const uint16 PAD3; + __IO uint16 empty2; const uint16 PAD4; } usb_btable_uni_tx; /* Double-buffered transmission endpoint BTABLE entry */ typedef struct usb_btable_dbl_tx { - __io uint16 addr_tx0; const uint16 PAD1; - __io uint16 count_tx0; const uint16 PAD2; - __io uint16 addr_tx1; const uint16 PAD3; - __io uint16 count_tx1; const uint16 PAD4; + __IO uint16 addr_tx0; const uint16 PAD1; + __IO uint16 count_tx0; const uint16 PAD2; + __IO uint16 addr_tx1; const uint16 PAD3; + __IO uint16 count_tx1; const uint16 PAD4; } usb_btable_dbl_tx; /* Double-buffered reception endpoint BTABLE entry */ typedef struct usb_btable_dbl_rx { - __io uint16 addr_rx0; const uint16 PAD1; - __io uint16 count_rx0; const uint16 PAD2; - __io uint16 addr_rx1; const uint16 PAD3; - __io uint16 count_rx1; const uint16 PAD4; + __IO uint16 addr_rx0; const uint16 PAD1; + __IO uint16 count_rx0; const uint16 PAD2; + __IO uint16 addr_rx1; const uint16 PAD3; + __IO uint16 count_rx1; const uint16 PAD4; } usb_btable_dbl_rx; /* TODO isochronous endpoint entries */ diff --git a/STM32F1/system/libmaple/usb/usb_lib/usb_type.h b/STM32F1/system/libmaple/usb/usb_lib/usb_type.h index 34b3bf5b7..02bd5efb7 100644 --- a/STM32F1/system/libmaple/usb/usb_lib/usb_type.h +++ b/STM32F1/system/libmaple/usb/usb_lib/usb_type.h @@ -62,7 +62,7 @@ typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus; typedef enum { DISABLE = 0, ENABLE = !DISABLE} FunctionalState; -typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus; +//typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus; /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ diff --git a/STM32F1/variants/STM32VLD/board.cpp b/STM32F1/variants/STM32VLD/board.cpp index 1cecbd932..0e69c7ba7 100644 --- a/STM32F1/variants/STM32VLD/board.cpp +++ b/STM32F1/variants/STM32VLD/board.cpp @@ -143,19 +143,6 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { * Maps to which hardware serial port on the microprocessor */ -#ifdef SERIAL_USB - DEFINE_HWSERIAL(Serial1, 1); - - DEFINE_HWSERIAL(Serial2, 2); - - DEFINE_HWSERIAL(Serial3, 3); - -#else - DEFINE_HWSERIAL(Serial, 1); - - DEFINE_HWSERIAL(Serial1, 2); - - DEFINE_HWSERIAL(Serial2, 3); - - -#endif +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); +DEFINE_HWSERIAL(Serial3, 3); diff --git a/STM32F1/variants/STM32VLD/wirish/boards.cpp b/STM32F1/variants/STM32VLD/wirish/boards.cpp index 5274e7a93..7b7e9a685 100644 --- a/STM32F1/variants/STM32VLD/wirish/boards.cpp +++ b/STM32F1/variants/STM32VLD/wirish/boards.cpp @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/STM32VLD/wirish/syscalls.c b/STM32F1/variants/STM32VLD/wirish/syscalls.c index 91ed5a104..ad878cb24 100644 --- a/STM32F1/variants/STM32VLD/wirish/syscalls.c +++ b/STM32F1/variants/STM32VLD/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/generic_gd32f103c/board.cpp b/STM32F1/variants/generic_gd32f103c/board.cpp index 8b136f2a1..ed3b2c9c3 100644 --- a/STM32F1/variants/generic_gd32f103c/board.cpp +++ b/STM32F1/variants/generic_gd32f103c/board.cpp @@ -102,7 +102,7 @@ extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { }; extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { - PB0, PA7, PA6 , PA5 , PA4 , PA3 , PA2 , PA1 , PA0 + PA0,PA1,PA2,PA3,PA6,PA7,PA8,PA9,PA10,PA11,PB0,PB1,PB6,PB7,PB8,PB9 }; // Note. These defines are not really used by generic boards. They are for Maple Serial USB @@ -124,16 +124,6 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { * Maps to which hardware serial port on the microprocessor */ -#ifdef SERIAL_USB - DEFINE_HWSERIAL(Serial1, 1); - - DEFINE_HWSERIAL(Serial2, 2); - - DEFINE_HWSERIAL(Serial3, 3); -#else - DEFINE_HWSERIAL(Serial, 1); - - DEFINE_HWSERIAL(Serial1, 2); - - DEFINE_HWSERIAL(Serial2, 3); -#endif +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); +DEFINE_HWSERIAL(Serial3, 3); diff --git a/STM32F1/variants/generic_gd32f103c/wirish/boards.cpp b/STM32F1/variants/generic_gd32f103c/wirish/boards.cpp index fcb85b2ab..93ae23151 100644 --- a/STM32F1/variants/generic_gd32f103c/wirish/boards.cpp +++ b/STM32F1/variants/generic_gd32f103c/wirish/boards.cpp @@ -120,12 +120,12 @@ static void setup_clocks(void) { // Clear clock readiness interrupt flags and turn off clock // readiness interrupts. RCC_BASE->CIR = 0x00000000; - +#if !USE_HSI_CLOCK // Enable HSE, and wait until it's ready. rcc_turn_on_clk(RCC_CLK_HSE); while (!rcc_is_clk_ready(RCC_CLK_HSE)) ; - +#endif // Configure AHBx, APBx, etc. prescalers and the main PLL. wirish::priv::board_setup_clock_prescalers(); rcc_configure_pll(&wirish::priv::w_board_pll_cfg); @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/generic_gd32f103c/wirish/boards_setup.cpp b/STM32F1/variants/generic_gd32f103c/wirish/boards_setup.cpp index 3df1fe784..a297de1e6 100644 --- a/STM32F1/variants/generic_gd32f103c/wirish/boards_setup.cpp +++ b/STM32F1/variants/generic_gd32f103c/wirish/boards_setup.cpp @@ -46,6 +46,7 @@ // Additionally the GD32 has a 4 USB PLL divider settings, rather than the 2 settings in the STM32, which allow it to operate on frequencies of 48,72,96 and 120Mhz and still have USB functioning #ifndef BOARD_RCC_PLLMUL +#if !USE_HSI_CLOCK #if F_CPU==120000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_10 #elif F_CPU==96000000 @@ -53,14 +54,20 @@ #elif F_CPU==72000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 #endif - +#else + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 +#endif #endif namespace wirish { namespace priv { static stm32f1_rcc_pll_data pll_data = {BOARD_RCC_PLLMUL}; +#if !USE_HSI_CLOCK __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data}; +#else + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data}; +#endif __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6; __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5; diff --git a/STM32F1/variants/generic_gd32f103c/wirish/syscalls.c b/STM32F1/variants/generic_gd32f103c/wirish/syscalls.c index 6558dbd3b..74e21f048 100644 --- a/STM32F1/variants/generic_gd32f103c/wirish/syscalls.c +++ b/STM32F1/variants/generic_gd32f103c/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/generic_stm32f103c/board.cpp b/STM32F1/variants/generic_stm32f103c/board.cpp index 7102adb9c..d1cf3dab9 100644 --- a/STM32F1/variants/generic_stm32f103c/board.cpp +++ b/STM32F1/variants/generic_stm32f103c/board.cpp @@ -52,9 +52,8 @@ void boardInit(void) { // Note. See the enum of pin names in board.h -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - - +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = +{ {&gpioa, &timer2, &adc1, 0, 1, 0}, /* PA0 */ {&gpioa, &timer2, &adc1, 1, 2, 1}, /* PA1 */ {&gpioa, &timer2, &adc1, 2, 3, 2}, /* PA2 */ @@ -93,12 +92,10 @@ extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { {&gpioc, NULL, NULL, 14, 0, ADCx}, /* PC14 */ {&gpioc, NULL, NULL, 15, 0, ADCx}, /* PC15 */ - - }; extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { - PB0, PA7, PA6, PA3, PA2, PA1, PA0, PB7, PB6, PA10, PA9, PA8 + PA0, PA1, PA2, PA3, PA6, PA7, PA8, PA9, PA10, PA11, PB0, PB1, PB6, PB7, PB8, PB9 }; extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { @@ -124,16 +121,6 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { * Maps to which hardware serial port on the microprocessor */ -#ifdef SERIAL_USB - DEFINE_HWSERIAL(Serial1, 1); - - DEFINE_HWSERIAL(Serial2, 2); - - DEFINE_HWSERIAL(Serial3, 3); -#else - DEFINE_HWSERIAL(Serial, 1); - - DEFINE_HWSERIAL(Serial1, 2); - - DEFINE_HWSERIAL(Serial2, 3); -#endif +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); +DEFINE_HWSERIAL(Serial3, 3); diff --git a/STM32F1/variants/generic_stm32f103c/board/board.h b/STM32F1/variants/generic_stm32f103c/board/board.h index 4736dc9ff..f57e11d55 100644 --- a/STM32F1/variants/generic_stm32f103c/board/board.h +++ b/STM32F1/variants/generic_stm32f103c/board/board.h @@ -53,13 +53,18 @@ #define BOARD_SPI1_MISO_PIN PA6 #define BOARD_SPI1_SCK_PIN PA5 +#define BOARD_SPI1_ALT_NSS_PIN PA15 +#define BOARD_SPI1_ALT_MOSI_PIN PB5 +#define BOARD_SPI1_ALT_MISO_PIN PB4 +#define BOARD_SPI1_ALT_SCK_PIN PB3 + #define BOARD_SPI2_NSS_PIN PB12 #define BOARD_SPI2_MOSI_PIN PB15 #define BOARD_SPI2_MISO_PIN PB14 #define BOARD_SPI2_SCK_PIN PB13 #define BOARD_NR_GPIO_PINS 35 -#define BOARD_NR_PWM_PINS 12 +#define BOARD_NR_PWM_PINS 16 #define BOARD_NR_ADC_PINS 9 #define BOARD_NR_USED_PINS 4 diff --git a/STM32F1/variants/generic_stm32f103c/ld/bootloader_20_c6.ld b/STM32F1/variants/generic_stm32f103c/ld/bootloader_20_c6.ld new file mode 100755 index 000000000..499efcc9e --- /dev/null +++ b/STM32F1/variants/generic_stm32f103c/ld/bootloader_20_c6.ld @@ -0,0 +1,30 @@ +/* + * libmaple linker script for "Flash" builds. + * + * A Flash build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but offsets the sections by + * enough space to store the Maple bootloader, which lives in low + * Flash and uses low memory. + */ + +/* + * This pulls in the appropriate MEMORY declaration from the right + * subdirectory of stm32/mem/ (the environment must call ld with the + * right include directory flags to make this happen). Boards can also + * use this file to use any of libmaple's memory-related hooks (like + * where the heap should live). + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K + rom (rx) : ORIGIN = 0x08002000, LENGTH = 24K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/STM32F1/variants/generic_stm32f103c/ld/hid_bootloader.ld b/STM32F1/variants/generic_stm32f103c/ld/hid_bootloader.ld new file mode 100644 index 000000000..d5b1f06ea --- /dev/null +++ b/STM32F1/variants/generic_stm32f103c/ld/hid_bootloader.ld @@ -0,0 +1,30 @@ +/* + * libmaple linker script for "Flash" builds. + * + * A Flash build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but offsets the sections by + * enough space to store the Maple bootloader, which lives in low + * Flash and uses low memory. + */ + +/* + * This pulls in the appropriate MEMORY declaration from the right + * subdirectory of stm32/mem/ (the environment must call ld with the + * right include directory flags to make this happen). Boards can also + * use this file to use any of libmaple's memory-related hooks (like + * where the heap should live). + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08001000, LENGTH = 124K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/STM32F1/variants/generic_stm32f103c/ld/hid_bootloader_c6.ld b/STM32F1/variants/generic_stm32f103c/ld/hid_bootloader_c6.ld new file mode 100644 index 000000000..e758192c7 --- /dev/null +++ b/STM32F1/variants/generic_stm32f103c/ld/hid_bootloader_c6.ld @@ -0,0 +1,30 @@ +/* + * libmaple linker script for "Flash" builds. + * + * A Flash build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but offsets the sections by + * enough space to store the Maple bootloader, which lives in low + * Flash and uses low memory. + */ + +/* + * This pulls in the appropriate MEMORY declaration from the right + * subdirectory of stm32/mem/ (the environment must call ld with the + * right include directory flags to make this happen). Boards can also + * use this file to use any of libmaple's memory-related hooks (like + * where the heap should live). + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K + rom (rx) : ORIGIN = 0x08001000, LENGTH = 24K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/STM32F1/variants/generic_stm32f103c/ld/jtag_c6.ld b/STM32F1/variants/generic_stm32f103c/ld/jtag_c6.ld new file mode 100644 index 000000000..1684795c8 --- /dev/null +++ b/STM32F1/variants/generic_stm32f103c/ld/jtag_c6.ld @@ -0,0 +1,36 @@ +/* + * libmaple linker script for "JTAG" builds. + * + * A "JTAG" build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but links starting at the + * Flash and SRAM starting addresses (0x08000000 and 0x20000000 + * respectively). This will wipe out a Maple bootloader if there's one + * on the board, so only use this if you know what you're doing. + * + * Of course, a "JTAG" build is perfectly usable for upload over SWD, + * the system memory bootloader, etc. The name is just a historical + * artifact. + */ + +/* + * This pulls in the appropriate MEMORY declaration from the right + * subdirectory of stm32/mem/ (the environment must call ld with the + * right include directory flags to make this happen). Boards can also + * use this file to use any of libmaple's memory-related hooks (like + * where the heap should live). + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/STM32F1/variants/generic_stm32f103c/wirish/boards.cpp b/STM32F1/variants/generic_stm32f103c/wirish/boards.cpp index 36fcb3e84..53f346922 100644 --- a/STM32F1/variants/generic_stm32f103c/wirish/boards.cpp +++ b/STM32F1/variants/generic_stm32f103c/wirish/boards.cpp @@ -120,12 +120,12 @@ static void setup_clocks(void) { // Clear clock readiness interrupt flags and turn off clock // readiness interrupts. RCC_BASE->CIR = 0x00000000; - +#if !USE_HSI_CLOCK // Enable HSE, and wait until it's ready. rcc_turn_on_clk(RCC_CLK_HSE); while (!rcc_is_clk_ready(RCC_CLK_HSE)) ; - +#endif // Configure AHBx, APBx, etc. prescalers and the main PLL. wirish::priv::board_setup_clock_prescalers(); rcc_configure_pll(&wirish::priv::w_board_pll_cfg); @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/generic_stm32f103c/wirish/boards_setup.cpp b/STM32F1/variants/generic_stm32f103c/wirish/boards_setup.cpp index 9e8332eec..65f5d3b9b 100644 --- a/STM32F1/variants/generic_stm32f103c/wirish/boards_setup.cpp +++ b/STM32F1/variants/generic_stm32f103c/wirish/boards_setup.cpp @@ -48,20 +48,34 @@ // works for F103 performance line MCUs, which is all that LeafLabs // currently officially supports). #ifndef BOARD_RCC_PLLMUL + #if !USE_HSI_CLOCK #if F_CPU==128000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 #elif F_CPU==72000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif + #else + #if !HSI_USB_SPEED + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 + #else + #define BOARD_RCC_PLLMUL RCC_PLLMUL_12 + #endif + #endif #endif namespace wirish { namespace priv { static stm32f1_rcc_pll_data pll_data = {BOARD_RCC_PLLMUL}; +#if !USE_HSI_CLOCK __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data}; +#else + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data}; +#endif __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6; __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5; diff --git a/STM32F1/variants/generic_stm32f103c/wirish/start_c.c b/STM32F1/variants/generic_stm32f103c/wirish/start_c.c index 05df0602e..aa5001857 100644 --- a/STM32F1/variants/generic_stm32f103c/wirish/start_c.c +++ b/STM32F1/variants/generic_stm32f103c/wirish/start_c.c @@ -48,8 +48,6 @@ extern void __libc_init_array(void); extern int main(int, char**, char**); -extern void exit(int) __attribute__((noreturn, weak)); - /* The linker must ensure that these are at least 4-byte aligned. */ extern char __data_start__, __data_end__; extern char __bss_start__, __bss_end__; @@ -64,7 +62,6 @@ void __attribute__((noreturn)) start_c(void) { struct rom_img_cfg *img_cfg = (struct rom_img_cfg*)&_lm_rom_img_cfgp; int *src = img_cfg->img_start; int *dst = (int*)&__data_start__; - int exit_code; /* Initialize .data, if necessary. */ if (src != dst) { @@ -84,10 +81,7 @@ void __attribute__((noreturn)) start_c(void) { __libc_init_array(); /* Jump to main. */ - exit_code = main(0, 0, 0); - if (exit) { - exit(exit_code); - } + main(0, 0, 0); /* If exit is NULL, make sure we don't return. */ for (;;) diff --git a/STM32F1/variants/generic_stm32f103c/wirish/syscalls.c b/STM32F1/variants/generic_stm32f103c/wirish/syscalls.c index 91ed5a104..ad878cb24 100644 --- a/STM32F1/variants/generic_stm32f103c/wirish/syscalls.c +++ b/STM32F1/variants/generic_stm32f103c/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/generic_stm32f103r/board.cpp b/STM32F1/variants/generic_stm32f103r/board.cpp index 891e4e944..6fe63b0a8 100644 --- a/STM32F1/variants/generic_stm32f103r/board.cpp +++ b/STM32F1/variants/generic_stm32f103r/board.cpp @@ -153,18 +153,9 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN }; - -#ifdef SERIAL_USB - DEFINE_HWSERIAL(Serial1, 1); - DEFINE_HWSERIAL(Serial2, 2); - DEFINE_HWSERIAL(Serial3, 3); - DEFINE_HWSERIAL_UART(Serial4, 4); - DEFINE_HWSERIAL_UART(Serial5, 5); -#else - DEFINE_HWSERIAL(Serial, 1); - DEFINE_HWSERIAL(Serial1, 2); - DEFINE_HWSERIAL(Serial2, 3); - DEFINE_HWSERIAL_UART(Serial3, 4); - DEFINE_HWSERIAL_UART(Serial4, 5); -#endif +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); +DEFINE_HWSERIAL(Serial3, 3); +DEFINE_HWSERIAL_UART(Serial4, 4); +DEFINE_HWSERIAL_UART(Serial5, 5); diff --git a/STM32F1/variants/generic_stm32f103r/wirish/boards.cpp b/STM32F1/variants/generic_stm32f103r/wirish/boards.cpp index fcb85b2ab..93ae23151 100644 --- a/STM32F1/variants/generic_stm32f103r/wirish/boards.cpp +++ b/STM32F1/variants/generic_stm32f103r/wirish/boards.cpp @@ -120,12 +120,12 @@ static void setup_clocks(void) { // Clear clock readiness interrupt flags and turn off clock // readiness interrupts. RCC_BASE->CIR = 0x00000000; - +#if !USE_HSI_CLOCK // Enable HSE, and wait until it's ready. rcc_turn_on_clk(RCC_CLK_HSE); while (!rcc_is_clk_ready(RCC_CLK_HSE)) ; - +#endif // Configure AHBx, APBx, etc. prescalers and the main PLL. wirish::priv::board_setup_clock_prescalers(); rcc_configure_pll(&wirish::priv::w_board_pll_cfg); @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/generic_stm32f103r/wirish/boards_setup.cpp b/STM32F1/variants/generic_stm32f103r/wirish/boards_setup.cpp index 04130152c..c804d7f53 100644 --- a/STM32F1/variants/generic_stm32f103r/wirish/boards_setup.cpp +++ b/STM32F1/variants/generic_stm32f103r/wirish/boards_setup.cpp @@ -48,20 +48,30 @@ // works for F103 performance line MCUs, which is all that LeafLabs // currently officially supports). #ifndef BOARD_RCC_PLLMUL + #if !USE_HSI_CLOCK #if F_CPU==128000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 #elif F_CPU==72000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif + #else + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 + #endif #endif namespace wirish { namespace priv { static stm32f1_rcc_pll_data pll_data = {BOARD_RCC_PLLMUL}; +#if !USE_HSI_CLOCK __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data}; +#else + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data}; +#endif __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6; __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5; diff --git a/STM32F1/variants/generic_stm32f103r8/board.cpp b/STM32F1/variants/generic_stm32f103r8/board.cpp index 05f85a5cc..c9d6b98f3 100644 --- a/STM32F1/variants/generic_stm32f103r8/board.cpp +++ b/STM32F1/variants/generic_stm32f103r8/board.cpp @@ -138,20 +138,7 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { * Moved definitions for Hardware Serial devices from HardwareSerial.cpp so that each board can define which Arduino "Serial" instance * Maps to which hardware serial port on the microprocessor */ - -#ifdef SERIAL_USB - DEFINE_HWSERIAL(Serial1, 1); - DEFINE_HWSERIAL(Serial2, 2); - - DEFINE_HWSERIAL(Serial3, 3); - -#else - DEFINE_HWSERIAL(Serial, 1); - - DEFINE_HWSERIAL(Serial1, 2); - - DEFINE_HWSERIAL(Serial2, 3); - - -#endif +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); +DEFINE_HWSERIAL(Serial3, 3); diff --git a/STM32F1/variants/generic_stm32f103r8/wirish/boards.cpp b/STM32F1/variants/generic_stm32f103r8/wirish/boards.cpp index 5274e7a93..88063432e 100644 --- a/STM32F1/variants/generic_stm32f103r8/wirish/boards.cpp +++ b/STM32F1/variants/generic_stm32f103r8/wirish/boards.cpp @@ -120,12 +120,12 @@ static void setup_clocks(void) { // Clear clock readiness interrupt flags and turn off clock // readiness interrupts. RCC_BASE->CIR = 0x00000000; - +#if !USE_HSI_CLOCK // Enable HSE, and wait until it's ready. rcc_turn_on_clk(RCC_CLK_HSE); while (!rcc_is_clk_ready(RCC_CLK_HSE)) ; - +#endif // Configure AHBx, APBx, etc. prescalers and the main PLL. wirish::priv::board_setup_clock_prescalers(); rcc_configure_pll(&wirish::priv::w_board_pll_cfg); @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/generic_stm32f103r8/wirish/boards_setup.cpp b/STM32F1/variants/generic_stm32f103r8/wirish/boards_setup.cpp index 8da724ded..9e9c3c093 100644 --- a/STM32F1/variants/generic_stm32f103r8/wirish/boards_setup.cpp +++ b/STM32F1/variants/generic_stm32f103r8/wirish/boards_setup.cpp @@ -48,20 +48,30 @@ // works for F103 performance line MCUs, which is all that LeafLabs // currently officially supports). #ifndef BOARD_RCC_PLLMUL + #if !USE_HSI_CLOCK #if F_CPU==128000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 #elif F_CPU==72000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif + #else + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 + #endif #endif namespace wirish { namespace priv { static stm32f1_rcc_pll_data pll_data = {BOARD_RCC_PLLMUL}; +#if !USE_HSI_CLOCK __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data}; +#else + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data}; +#endif __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6; __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5; diff --git a/STM32F1/variants/generic_stm32f103r8/wirish/syscalls.c b/STM32F1/variants/generic_stm32f103r8/wirish/syscalls.c index 91ed5a104..ad878cb24 100644 --- a/STM32F1/variants/generic_stm32f103r8/wirish/syscalls.c +++ b/STM32F1/variants/generic_stm32f103r8/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/generic_stm32f103t/board.cpp b/STM32F1/variants/generic_stm32f103t/board.cpp index e7a1dc0e0..5c08b90f7 100644 --- a/STM32F1/variants/generic_stm32f103t/board.cpp +++ b/STM32F1/variants/generic_stm32f103t/board.cpp @@ -109,12 +109,5 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { * Maps to which hardware serial port on the microprocessor */ -#ifdef SERIAL_USB - DEFINE_HWSERIAL(Serial1, 1); - - DEFINE_HWSERIAL(Serial2, 2); -#else - DEFINE_HWSERIAL(Serial, 1); - - DEFINE_HWSERIAL(Serial1, 2); -#endif +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); diff --git a/STM32F1/variants/generic_stm32f103t/wirish/boards.cpp b/STM32F1/variants/generic_stm32f103t/wirish/boards.cpp index 5274e7a93..88063432e 100644 --- a/STM32F1/variants/generic_stm32f103t/wirish/boards.cpp +++ b/STM32F1/variants/generic_stm32f103t/wirish/boards.cpp @@ -120,12 +120,12 @@ static void setup_clocks(void) { // Clear clock readiness interrupt flags and turn off clock // readiness interrupts. RCC_BASE->CIR = 0x00000000; - +#if !USE_HSI_CLOCK // Enable HSE, and wait until it's ready. rcc_turn_on_clk(RCC_CLK_HSE); while (!rcc_is_clk_ready(RCC_CLK_HSE)) ; - +#endif // Configure AHBx, APBx, etc. prescalers and the main PLL. wirish::priv::board_setup_clock_prescalers(); rcc_configure_pll(&wirish::priv::w_board_pll_cfg); @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/generic_stm32f103t/wirish/boards_setup.cpp b/STM32F1/variants/generic_stm32f103t/wirish/boards_setup.cpp index 9e8332eec..59e8228cc 100644 --- a/STM32F1/variants/generic_stm32f103t/wirish/boards_setup.cpp +++ b/STM32F1/variants/generic_stm32f103t/wirish/boards_setup.cpp @@ -48,20 +48,30 @@ // works for F103 performance line MCUs, which is all that LeafLabs // currently officially supports). #ifndef BOARD_RCC_PLLMUL + #if !USE_HSI_CLOCK #if F_CPU==128000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 #elif F_CPU==72000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif + #else + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 + #endif #endif namespace wirish { namespace priv { static stm32f1_rcc_pll_data pll_data = {BOARD_RCC_PLLMUL}; +#if !USE_HSI_CLOCK __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data}; +#else + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data}; +#endif __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6; __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5; diff --git a/STM32F1/variants/generic_stm32f103t/wirish/syscalls.c b/STM32F1/variants/generic_stm32f103t/wirish/syscalls.c index 91ed5a104..ad878cb24 100644 --- a/STM32F1/variants/generic_stm32f103t/wirish/syscalls.c +++ b/STM32F1/variants/generic_stm32f103t/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/generic_stm32f103v/board.cpp b/STM32F1/variants/generic_stm32f103v/board.cpp index 9c137725a..ec2e68b15 100644 --- a/STM32F1/variants/generic_stm32f103v/board.cpp +++ b/STM32F1/variants/generic_stm32f103v/board.cpp @@ -98,7 +98,7 @@ extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { {&gpiob, &timer3, &adc1, 0, 3, 8}, /* PB0 */ {&gpiob, &timer3, &adc1, 1, 4, 9}, /* PB1 */ - /* NOTE PB2 is not included as its Boot 1 */ + {&gpiob, NULL, NULL, 2, 0, ADCx}, /* PB2 */ // Boot1 pin. It affects boot mode (flash, RAM, ROM) {&gpiob, NULL, NULL, 3, 0, ADCx}, /* PB3 */ //JTDO, SPI3_SCK / I2S3_CK/ {&gpiob, NULL, NULL, 4, 0, ADCx}, /* PB4 */ //NJTRST, SPI3_MISO {&gpiob, NULL, NULL, 5, 0, ADCx}, /* PB5 */ //I2C1_SMBA/ SPI3_MOSI @@ -183,17 +183,8 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN }; - -#ifdef SERIAL_USB - DEFINE_HWSERIAL(Serial1, 1); - DEFINE_HWSERIAL(Serial2, 2); - DEFINE_HWSERIAL(Serial3, 3); - DEFINE_HWSERIAL_UART(Serial4, 4); - DEFINE_HWSERIAL_UART(Serial5, 5); -#else - DEFINE_HWSERIAL(Serial, 1); - DEFINE_HWSERIAL(Serial1, 2); - DEFINE_HWSERIAL(Serial2, 3); - DEFINE_HWSERIAL_UART(Serial3, 4); - DEFINE_HWSERIAL_UART(Serial4, 5); -#endif \ No newline at end of file +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); +DEFINE_HWSERIAL(Serial3, 3); +DEFINE_HWSERIAL_UART(Serial4, 4); +DEFINE_HWSERIAL_UART(Serial5, 5); diff --git a/STM32F1/variants/generic_stm32f103v/board/board.h b/STM32F1/variants/generic_stm32f103v/board/board.h index 3bb680a78..e4bd0896c 100644 --- a/STM32F1/variants/generic_stm32f103v/board/board.h +++ b/STM32F1/variants/generic_stm32f103v/board/board.h @@ -90,8 +90,9 @@ #define BOARD_SPI3_MOSI_PIN PB5 -/* GPIO A to E = 5 * 16 - BOOT1 not used = 79*/ -#define BOARD_NR_GPIO_PINS 79 +/* GPIO A to E = 5 * 16 = 80*/ +/* value is now 80 as boo1 was added via PR to the pinmap but this value was not increased*/ +#define BOARD_NR_GPIO_PINS 80 /* Note: NOT 19. The missing one is D38 a.k.a. BOARD_BUTTON_PIN, which * isn't broken out to a header and is thus unusable for PWM. */ #define BOARD_NR_PWM_PINS 19 @@ -124,10 +125,10 @@ * write code using low-level GPIO functionality. */ enum { PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PA8,PA9,PA10,PA11,PA12,PA13,PA14,PA15, -PB0,PB1,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15, +PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15, PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PC8,PC9,PC10,PC11,PC12,PC13,PC14,PC15, PD0,PD1,PD2,PD3,PD4,PD5,PD6,PD7,PD8,PD9,PD10,PD11,PD12,PD13,PD14,PD15, PE0,PE1,PE2,PE3,PE4,PE5,PE6,PE7,PE8,PE9,PE10,PE11,PE12,PE13,PE14,PE15, -};/* Note PB2 is skipped as this is Boot1 and is not going to be much use as its likely to be pulled permanently low */ +}; #endif diff --git a/STM32F1/variants/generic_stm32f103v/ld/stm32f103vc.ld b/STM32F1/variants/generic_stm32f103v/ld/stm32f103vc.ld index 7efca5d77..6079807f5 100644 --- a/STM32F1/variants/generic_stm32f103v/ld/stm32f103vc.ld +++ b/STM32F1/variants/generic_stm32f103v/ld/stm32f103vc.ld @@ -16,7 +16,7 @@ */ MEMORY { - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K } diff --git a/STM32F1/variants/generic_stm32f103v/wirish/boards.cpp b/STM32F1/variants/generic_stm32f103v/wirish/boards.cpp index 254666f68..a2867b8e2 100644 --- a/STM32F1/variants/generic_stm32f103v/wirish/boards.cpp +++ b/STM32F1/variants/generic_stm32f103v/wirish/boards.cpp @@ -120,16 +120,22 @@ static void setup_clocks(void) { // Clear clock readiness interrupt flags and turn off clock // readiness interrupts. RCC_BASE->CIR = 0x00000000; - +#if !USE_HSI_CLOCK // Enable HSE, and wait until it's ready. rcc_turn_on_clk(RCC_CLK_HSE); while (!rcc_is_clk_ready(RCC_CLK_HSE)) ; - +#endif // Configure AHBx, APBx, etc. prescalers and the main PLL. wirish::priv::board_setup_clock_prescalers(); rcc_configure_pll(&wirish::priv::w_board_pll_cfg); +#ifdef XTAL16M + // 16MHz crystal (HSE) + // in this case we additionally set the Bit 17 (PLLXTPRE=1) => then HSE clock is divided by 2 before PLL entry + RCC_BASE->CFGR |= RCC_CFGR_PLLXTPRE; +#endif + // Enable the PLL, and wait until it's ready. rcc_turn_on_clk(RCC_CLK_PLL); while(!rcc_is_clk_ready(RCC_CLK_PLL)) @@ -147,11 +153,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/generic_stm32f103v/wirish/boards_setup.cpp b/STM32F1/variants/generic_stm32f103v/wirish/boards_setup.cpp index dba014b91..5ea718b4c 100644 --- a/STM32F1/variants/generic_stm32f103v/wirish/boards_setup.cpp +++ b/STM32F1/variants/generic_stm32f103v/wirish/boards_setup.cpp @@ -48,20 +48,30 @@ // works for F103 performance line MCUs, which is all that LeafLabs // currently officially supports). #ifndef BOARD_RCC_PLLMUL + #if !USE_HSI_CLOCK #if F_CPU==128000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 #elif F_CPU==72000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif + #else + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 + #endif #endif namespace wirish { namespace priv { static stm32f1_rcc_pll_data pll_data = {BOARD_RCC_PLLMUL}; +#if !USE_HSI_CLOCK __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data}; +#else + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data}; +#endif __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6; __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5; diff --git a/STM32F1/variants/generic_stm32f103v/wirish/syscalls.c b/STM32F1/variants/generic_stm32f103v/wirish/syscalls.c index ec1c34dba..156d2a3d1 100644 --- a/STM32F1/variants/generic_stm32f103v/wirish/syscalls.c +++ b/STM32F1/variants/generic_stm32f103v/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/generic_stm32f103vb/board.cpp b/STM32F1/variants/generic_stm32f103vb/board.cpp new file mode 100644 index 000000000..6f9ce6a7e --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/board.cpp @@ -0,0 +1,177 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ +#warning "vb" +/** + * @file wirish/boards/maple_mini/board.cpp + * @author Marti Bolivar + * @brief Maple Mini board file. + */ + +#include + +#include +#include + +/* Roger Clark. Added next to includes for changes to Serial */ +#include +#include + +#include +#include + +/* Since we want the Serial Wire/JTAG pins as GPIOs, disable both SW + * and JTAG debug support, unless configured otherwise. */ +void boardInit(void) { +#ifndef CONFIG_MAPLE_MINI_NO_DISABLE_DEBUG + disableDebugPorts(); +#endif +} + +// Note. See the enum of pin names in board.h + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + + + {&gpioa, &timer2, &adc1, 0, 1, 0}, /* PA0 */ + {&gpioa, &timer2, &adc1, 1, 2, 1}, /* PA1 */ + {&gpioa, &timer2, &adc1, 2, 3, 2}, /* PA2 */ + {&gpioa, &timer2, &adc1, 3, 4, 3}, /* PA3 */ + {&gpioa, NULL, &adc1, 4, 0, 4}, /* PA4 */ + {&gpioa, NULL, &adc1, 5, 0, 5}, /* PA5 */ + {&gpioa, &timer3, &adc1, 6, 1, 6}, /* PA6 */ + {&gpioa, &timer3, &adc1, 7, 2, 7}, /* PA7 */ + {&gpioa, &timer1, NULL, 8, 1, ADCx}, /* PA8 */ + {&gpioa, &timer1, NULL, 9, 2, ADCx}, /* PA9 */ + {&gpioa, &timer1, NULL, 10, 3, ADCx}, /* PA10 */ + {&gpioa, &timer1, NULL, 11, 4, ADCx}, /* PA11 */ + {&gpioa, NULL, NULL, 12, 0, ADCx}, /* PA12 */ + {&gpioa, NULL, NULL, 13, 0, ADCx}, /* PA13 */ + {&gpioa, NULL, NULL, 14, 0, ADCx}, /* PA14 */ + {&gpioa, NULL, NULL, 15, 0, ADCx}, /* PA15 */ + + {&gpiob, &timer3, &adc1, 0, 3, 8}, /* PB0 */ + {&gpiob, &timer3, &adc1, 1, 4, 9}, /* PB1 */ + {&gpiob, NULL, NULL, 2, 0, ADCx}, /* PB2 */ + {&gpiob, NULL, NULL, 3, 0, ADCx}, /* PB3 */ + {&gpiob, NULL, NULL, 4, 0, ADCx}, /* PB4 */ + {&gpiob, NULL, NULL, 5, 0, ADCx}, /* PB5 */ + {&gpiob, &timer4, NULL, 6, 1, ADCx}, /* PB6 */ + {&gpiob, &timer4, NULL, 7, 2, ADCx}, /* PB7 */ + {&gpiob, &timer4, NULL, 8, 3, ADCx}, /* PB8 */ + {&gpiob, &timer4, NULL, 9, 4, ADCx}, /* PB9 */ + {&gpiob, NULL, NULL, 10, 0, ADCx}, /* PB10 */ + {&gpiob, NULL, NULL, 11, 0, ADCx}, /* PB11 */ + {&gpiob, NULL, NULL, 12, 0, ADCx}, /* PB12 */ + {&gpiob, NULL, NULL, 13, 0, ADCx}, /* PB13 */ + {&gpiob, NULL, NULL, 14, 0, ADCx}, /* PB14 */ + {&gpiob, NULL, NULL, 15, 0, ADCx}, /* PB15 */ + + {&gpioc, NULL, &adc1, 0, 0, 10}, /* PC0 */ + {&gpioc, NULL, &adc1, 1, 0, 11}, /* PC1 */ + {&gpioc, NULL, &adc1, 2, 0, 12}, /* PC2 */ + {&gpioc, NULL, &adc1, 3, 0, 13}, /* PC3 */ + {&gpioc, NULL, &adc1, 4, 0, 14}, /* PC4 */ + {&gpioc, NULL, &adc1, 5, 0, 15}, /* PC5 */ + + {&gpioc, NULL, NULL, 6, 0, ADCx}, /* PC6 */ + {&gpioc, NULL, NULL, 7, 0, ADCx}, /* PC7 */ + {&gpioc, NULL, NULL, 8, 0, ADCx}, /* PC8 */ + {&gpioc, NULL, NULL, 9, 0, ADCx}, /* PC9 */ + + {&gpioc, NULL, NULL, 10, 0, ADCx}, /* PC10 */ + {&gpioc, NULL, NULL, 11, 0, ADCx}, /* PC11 */ + {&gpioc, NULL, NULL, 12, 0, ADCx}, /* PC12 */ + {&gpioc, NULL, NULL, 13, 0, ADCx}, /* PC13 */ + {&gpioc, NULL, NULL, 14, 0, ADCx}, /* PC14 */ + {&gpioc, NULL, NULL, 15, 0, ADCx}, /* PC15 */ + +/* the VB is similar to the RB but exposes more GPIO as follows */ + {&gpiod, NULL, NULL, 0, 0, ADCx} , /* PD0 N */ + {&gpiod, NULL, NULL, 1, 0, ADCx} , /* PD1 */ + {&gpiod, NULL, NULL, 2, 0, ADCx} , /* PD2 TIM3_ETR */ + {&gpiod, NULL, NULL, 3, 0, ADCx} , /* PD3 */ + {&gpiod, NULL, NULL, 4, 0, ADCx} , /* PD4 */ + {&gpiod, NULL, NULL, 5, 0, ADCx} , /* PD5 */ + {&gpiod, NULL, NULL, 6, 0, ADCx} , /* PD6 */ + {&gpiod, NULL, NULL, 7, 0, ADCx} , /* PD7 */ + {&gpiod, NULL, NULL, 8, 0, ADCx} , /* PD8 */ + {&gpiod, NULL, NULL, 9, 0, ADCx} , /* PD9 */ + {&gpiod, NULL, NULL, 10, 0, ADCx} , /* PD10 */ + {&gpiod, NULL, NULL, 11, 0, ADCx} , /* PD11 */ + {&gpiod, NULL, NULL, 12, 0, ADCx} , /* PD12 */ + {&gpiod, NULL, NULL, 13, 0, ADCx} , /* PD13 */ + {&gpiod, NULL, NULL, 14, 0, ADCx} , /* PD14 */ + {&gpiod, NULL, NULL, 15, 0, ADCx} , /* PD15 */ + + {&gpioe, NULL, NULL, 0, 0, ADCx} , /* PE0 TIM4_ETR / FSMC_NBL0 */ + {&gpioe, NULL, NULL, 1, 0, ADCx} , /* PE1 FSMC_NBL1 */ + {&gpioe, NULL, NULL, 2, 0, ADCx} , /* PE2 TRACECK */ + {&gpioe, NULL, NULL, 3, 0, ADCx} , /* PE3 TRACED0 */ + {&gpioe, NULL, NULL, 4, 0, ADCx} , /* PE4 TRACED1 */ + {&gpioe, NULL, NULL, 5, 0, ADCx} , /* PE5 TRACED2 */ + {&gpioe, NULL, NULL, 6, 0, ADCx} , /* PE6 TRACED3 */ + {&gpioe, NULL, NULL, 7, 0, ADCx} , /* PE7 */ + {&gpioe, NULL, NULL, 8, 0, ADCx} , /* PE8 */ + {&gpioe, NULL, NULL, 9, 0, ADCx} , /* PE9 */ + {&gpioe, NULL, NULL, 10, 0, ADCx} , /* PE10 */ + {&gpioe, NULL, NULL, 11, 0, ADCx} , /* PE11 */ + {&gpioe, NULL, NULL, 12, 0, ADCx} , /* PE12 */ + {&gpioe, NULL, NULL, 13, 0, ADCx} , /* PE13 */ + {&gpioe, NULL, NULL, 14, 0, ADCx} , /* PE14 */ + {&gpioe, NULL, NULL, 15, 0, ADCx} , /* PE15 */ + +}; + +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + PB0, PA7, PA6, PA3, PA2, PA1, PA0, PB7, PB6, PA10, PA9, PA8, PC6, PC7, PC8, PC9 +}; + +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + PB0, PA7, PA6 , PA5 , PA4 , PA3 , PA2 , PA1 , PA0 , PC0, PC1, PC2, PC3, PC4, PC5 +}; + +// Note. These defines are not really used by generic boards. They are for Maple Serial USB +#define USB_DP PA12 +#define USB_DM PA11 + +// NOte. These definitions are not really used for generic boards, they only relate to boards modified to behave like Maple boards +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + USB_DP, USB_DM +}; + + +/* + * Roger Clark + * + * 2015/05/28 + * + * Moved definitions for Hardware Serial devices from HardwareSerial.cpp so that each board can define which Arduino "Serial" instance + * Maps to which hardware serial port on the microprocessor + */ + +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); +DEFINE_HWSERIAL(Serial3, 3); diff --git a/STM32F1/variants/generic_stm32f103vb/board/board.h b/STM32F1/variants/generic_stm32f103vb/board/board.h new file mode 100644 index 000000000..1271bb0a7 --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/board/board.h @@ -0,0 +1,84 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file wirish/boards/maple_mini/include/board/board.h + * @author Marti Bolivar + * @brief Maple Mini board header. + * + * See wirish/boards/maple/include/board/board.h for more information + * on these definitions. + */ +#ifndef _BOARD_GENERIC_STM32F103VB_H_ +#define _BOARD_GENERIC_STM32F103VB_H_ + +#define CYCLES_PER_MICROSECOND (F_CPU / 1000000U) +#define SYSTICK_RELOAD_VAL (F_CPU/1000) - 1 /* takes a cycle to reload */ + +#define BOARD_NR_USARTS 3 +#define BOARD_USART1_TX_PIN PA9 +#define BOARD_USART1_RX_PIN PA10 +#define BOARD_USART2_TX_PIN PA2 +#define BOARD_USART2_RX_PIN PA3 +#define BOARD_USART3_TX_PIN PB10 +#define BOARD_USART3_RX_PIN PB11 + +#define BOARD_NR_SPI 2 +#define BOARD_SPI1_NSS_PIN PA4 +#define BOARD_SPI1_MOSI_PIN PA7 +#define BOARD_SPI1_MISO_PIN PA6 +#define BOARD_SPI1_SCK_PIN PA5 + +#define BOARD_SPI2_NSS_PIN PB12 +#define BOARD_SPI2_MOSI_PIN PB15 +#define BOARD_SPI2_MISO_PIN PB14 +#define BOARD_SPI2_SCK_PIN PB13 + +#define BOARD_NR_GPIO_PINS 80 +#define BOARD_NR_PWM_PINS 16 +#define BOARD_NR_ADC_PINS 15 +#define BOARD_NR_USED_PINS 4 + + +#define BOARD_JTMS_SWDIO_PIN 22 +#define BOARD_JTCK_SWCLK_PIN 21 +#define BOARD_JTDI_PIN 20 +#define BOARD_JTDO_PIN 19 +#define BOARD_NJTRST_PIN 18 + +#define BOARD_USB_DISC_DEV NULL +#define BOARD_USB_DISC_BIT NULL + +// Note this needs to match with the PIN_MAP array in board.cpp +enum { + PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, + PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15, + PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10, PC11, PC12, PC13, PC14, PC15, + PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15, + PE0, PE1, PE2, PE3, PE4, PE5, PE6, PE7, PE8, PE9, PE10, PE11, PE12, PE13, PE14, PE15 +}; + +#endif diff --git a/STM32F1/variants/generic_stm32f103vb/ld/bootloader.ld b/STM32F1/variants/generic_stm32f103vb/ld/bootloader.ld new file mode 100644 index 000000000..348b19c1d --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/ld/bootloader.ld @@ -0,0 +1,18 @@ +/* + * Linker script for Generic STM32F103RE boards, using the generic bootloader (which takes the lower 8k of memory) + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08002000, LENGTH = 120K +} + + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/STM32F1/variants/generic_stm32f103vb/ld/bootloader_20.ld b/STM32F1/variants/generic_stm32f103vb/ld/bootloader_20.ld new file mode 100644 index 000000000..4de3a0839 --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/ld/bootloader_20.ld @@ -0,0 +1,30 @@ +/* + * libmaple linker script for "Flash" builds. + * + * A Flash build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but offsets the sections by + * enough space to store the Maple bootloader, which lives in low + * Flash and uses low memory. + */ + +/* + * This pulls in the appropriate MEMORY declaration from the right + * subdirectory of stm32/mem/ (the environment must call ld with the + * right include directory flags to make this happen). Boards can also + * use this file to use any of libmaple's memory-related hooks (like + * where the heap should live). + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08002000, LENGTH = 120K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/STM32F3/variants/discovery_f3/ld/common.inc b/STM32F1/variants/generic_stm32f103vb/ld/common.inc similarity index 98% rename from STM32F3/variants/discovery_f3/ld/common.inc rename to STM32F1/variants/generic_stm32f103vb/ld/common.inc index 49aaf6fc4..e086a58bc 100644 --- a/STM32F3/variants/discovery_f3/ld/common.inc +++ b/STM32F1/variants/generic_stm32f103vb/ld/common.inc @@ -133,8 +133,9 @@ SECTIONS */ .data : { - . = ALIGN(8); __data_start__ = .; + LONG(0) + . = ALIGN(8); *(.got.plt) *(.got) *(.data .data.* .gnu.linkonce.d.*) @@ -182,16 +183,6 @@ SECTIONS _end = __bss_end__; } > REGION_BSS - /* - * .ccm - */ - .ccm (NOLOAD) : - { - . = ALIGN(4); - *(.CCM) - . = ALIGN(4); - } > REGION_CCM - /* * Debugging sections */ diff --git a/STM32F3/variants/discovery_f3/ld/extra_libs.inc b/STM32F1/variants/generic_stm32f103vb/ld/extra_libs.inc similarity index 100% rename from STM32F3/variants/discovery_f3/ld/extra_libs.inc rename to STM32F1/variants/generic_stm32f103vb/ld/extra_libs.inc diff --git a/STM32F3/variants/discovery_f3/ld/flash.ld b/STM32F1/variants/generic_stm32f103vb/ld/flash.ld similarity index 96% rename from STM32F3/variants/discovery_f3/ld/flash.ld rename to STM32F1/variants/generic_stm32f103vb/ld/flash.ld index 2fa903538..9e250cd74 100644 --- a/STM32F3/variants/discovery_f3/ld/flash.ld +++ b/STM32F1/variants/generic_stm32f103vb/ld/flash.ld @@ -14,7 +14,6 @@ * use this file to use any of libmaple's memory-related hooks (like * where the heap should live). */ - INCLUDE mem-flash.inc /* Provide memory region aliases for common.inc */ @@ -22,7 +21,6 @@ REGION_ALIAS("REGION_TEXT", rom); REGION_ALIAS("REGION_DATA", ram); REGION_ALIAS("REGION_BSS", ram); REGION_ALIAS("REGION_RODATA", rom); -REGION_ALIAS("REGION_CCM", ccm); /* Let common.inc handle the real work. */ INCLUDE common.inc diff --git a/STM32F3/variants/discovery_f3/ld/jtag.ld b/STM32F1/variants/generic_stm32f103vb/ld/jtag.ld similarity index 97% rename from STM32F3/variants/discovery_f3/ld/jtag.ld rename to STM32F1/variants/generic_stm32f103vb/ld/jtag.ld index cf08b20c0..0612f9586 100644 --- a/STM32F3/variants/discovery_f3/ld/jtag.ld +++ b/STM32F1/variants/generic_stm32f103vb/ld/jtag.ld @@ -19,7 +19,6 @@ * use this file to use any of libmaple's memory-related hooks (like * where the heap should live). */ - INCLUDE mem-jtag.inc /* Provide memory region aliases for common.inc */ @@ -27,7 +26,6 @@ REGION_ALIAS("REGION_TEXT", rom); REGION_ALIAS("REGION_DATA", ram); REGION_ALIAS("REGION_BSS", ram); REGION_ALIAS("REGION_RODATA", rom); -REGION_ALIAS("REGION_CCM", ccm); /* Let common.inc handle the real work. */ INCLUDE common.inc diff --git a/STM32F1/variants/generic_stm32f103vb/ld/mem-flash.inc b/STM32F1/variants/generic_stm32f103vb/ld/mem-flash.inc new file mode 100644 index 000000000..a9091ca85 --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/ld/mem-flash.inc @@ -0,0 +1,5 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K +} diff --git a/STM32F1/variants/generic_stm32f103vb/ld/mem-jtag.inc b/STM32F1/variants/generic_stm32f103vb/ld/mem-jtag.inc new file mode 100644 index 000000000..20fbec056 --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/ld/mem-jtag.inc @@ -0,0 +1,5 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K +} diff --git a/STM32F1/variants/generic_stm32f103vb/ld/mem-ram.inc b/STM32F1/variants/generic_stm32f103vb/ld/mem-ram.inc new file mode 100644 index 000000000..f02453b9a --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/ld/mem-ram.inc @@ -0,0 +1,5 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K +} diff --git a/STM32F3/variants/discovery_f3/ld/ram.ld b/STM32F1/variants/generic_stm32f103vb/ld/ram.ld similarity index 96% rename from STM32F3/variants/discovery_f3/ld/ram.ld rename to STM32F1/variants/generic_stm32f103vb/ld/ram.ld index 0484423b0..34b468e0a 100644 --- a/STM32F3/variants/discovery_f3/ld/ram.ld +++ b/STM32F1/variants/generic_stm32f103vb/ld/ram.ld @@ -13,7 +13,6 @@ * use this file to use any of libmaple's memory-related hooks (like * where the heap should live). */ - INCLUDE mem-ram.inc /* Provide memory region aliases for common.inc */ @@ -21,7 +20,6 @@ REGION_ALIAS("REGION_TEXT", ram); REGION_ALIAS("REGION_DATA", ram); REGION_ALIAS("REGION_BSS", ram); REGION_ALIAS("REGION_RODATA", ram); -REGION_ALIAS("REGION_CCM", ccm); /* Let common.inc handle the real work. */ INCLUDE common.inc diff --git a/STM32F1/variants/generic_stm32f103vb/ld/stm32f103vb.ld b/STM32F1/variants/generic_stm32f103vb/ld/stm32f103vb.ld new file mode 100644 index 000000000..814d50870 --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/ld/stm32f103vb.ld @@ -0,0 +1,30 @@ +/* + * libmaple linker script for "Flash" builds. + * + * A Flash build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but offsets the sections by + * enough space to store the Maple bootloader, which lives in low + * Flash and uses low memory. + */ + +/* + * This pulls in the appropriate MEMORY declaration from the right + * subdirectory of stm32/mem/ (the environment must call ld with the + * right include directory flags to make this happen). Boards can also + * use this file to use any of libmaple's memory-related hooks (like + * where the heap should live). + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/STM32F1/variants/generic_stm32f103vb/ld/stm32f103veDFU.ld b/STM32F1/variants/generic_stm32f103vb/ld/stm32f103veDFU.ld new file mode 100644 index 000000000..5782fb9fa --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/ld/stm32f103veDFU.ld @@ -0,0 +1,30 @@ +/* + * libmaple linker script for "Flash" builds. + * + * A Flash build puts .text (and .rodata) in Flash, and + * .data/.bss/heap (of course) in SRAM, but offsets the sections by + * enough space to store the Maple bootloader, which lives in low + * Flash and uses low memory. + */ + +/* + * This pulls in the appropriate MEMORY declaration from the right + * subdirectory of stm32/mem/ (the environment must call ld with the + * right include directory flags to make this happen). Boards can also + * use this file to use any of libmaple's memory-related hooks (like + * where the heap should live). + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08002000, LENGTH = 504K +} + +/* Provide memory region aliases for common.inc */ +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Let common.inc handle the real work. */ +INCLUDE common.inc diff --git a/STM32F4/variants/discovery_f407/ld/names.inc b/STM32F1/variants/generic_stm32f103vb/ld/vector_symbols.inc similarity index 97% rename from STM32F4/variants/discovery_f407/ld/names.inc rename to STM32F1/variants/generic_stm32f103vb/ld/vector_symbols.inc index 6d7ff6e94..f8519bba4 100644 --- a/STM32F4/variants/discovery_f407/ld/names.inc +++ b/STM32F1/variants/generic_stm32f103vb/ld/vector_symbols.inc @@ -1,5 +1,5 @@ -EXTERN(__cs3_stack) -EXTERN(__cs3_reset) +EXTERN(__msp_init) +EXTERN(__exc_reset) EXTERN(__exc_nmi) EXTERN(__exc_hardfault) EXTERN(__exc_memmanage) diff --git a/STM32F1/variants/generic_stm32f103vb/pins_arduino.h b/STM32F1/variants/generic_stm32f103vb/pins_arduino.h new file mode 100644 index 000000000..3052f2eb2 --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/pins_arduino.h @@ -0,0 +1,6 @@ + + + + +// API compatibility +#include "variant.h" \ No newline at end of file diff --git a/STM32F1/variants/generic_stm32f103vb/variant.h b/STM32F1/variants/generic_stm32f103vb/variant.h new file mode 100644 index 000000000..8a88623e7 --- /dev/null +++ b/STM32F1/variants/generic_stm32f103vb/variant.h @@ -0,0 +1,20 @@ +#ifndef _VARIANT_ARDUINO_STM32_ +#define _VARIANT_ARDUINO_STM32_ + +#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device ) +#define digitalPinToBitMask(P) ( BIT(PIN_MAP[P].gpio_bit) ) +#define portOutputRegister(port) ( &(port->regs->ODR) ) +#define portInputRegister(port) ( &(port->regs->IDR) ) + +#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) ) +#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) ) + +#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) ) + +static const uint8_t SS = BOARD_SPI1_NSS_PIN; +static const uint8_t SS1 = BOARD_SPI2_NSS_PIN; +static const uint8_t MOSI = BOARD_SPI1_MOSI_PIN; +static const uint8_t MISO = BOARD_SPI1_MISO_PIN; +static const uint8_t SCK = BOARD_SPI1_SCK_PIN; + +#endif /* _VARIANT_ARDUINO_STM32_ */ \ No newline at end of file diff --git a/STM32F3/cores/maple/wirish/boards.cpp b/STM32F1/variants/generic_stm32f103vb/wirish/boards.cpp similarity index 94% rename from STM32F3/cores/maple/wirish/boards.cpp rename to STM32F1/variants/generic_stm32f103vb/wirish/boards.cpp index a693fa60a..a2867b8e2 100644 --- a/STM32F3/cores/maple/wirish/boards.cpp +++ b/STM32F1/variants/generic_stm32f103vb/wirish/boards.cpp @@ -45,7 +45,7 @@ * notice. */ -#include +#include #include #include #include @@ -120,16 +120,22 @@ static void setup_clocks(void) { // Clear clock readiness interrupt flags and turn off clock // readiness interrupts. RCC_BASE->CIR = 0x00000000; - +#if !USE_HSI_CLOCK // Enable HSE, and wait until it's ready. rcc_turn_on_clk(RCC_CLK_HSE); while (!rcc_is_clk_ready(RCC_CLK_HSE)) ; - +#endif // Configure AHBx, APBx, etc. prescalers and the main PLL. wirish::priv::board_setup_clock_prescalers(); rcc_configure_pll(&wirish::priv::w_board_pll_cfg); +#ifdef XTAL16M + // 16MHz crystal (HSE) + // in this case we additionally set the Bit 17 (PLLXTPRE=1) => then HSE clock is divided by 2 before PLL entry + RCC_BASE->CFGR |= RCC_CFGR_PLLXTPRE; +#endif + // Enable the PLL, and wait until it's ready. rcc_turn_on_clk(RCC_CLK_PLL); while(!rcc_is_clk_ready(RCC_CLK_PLL)) @@ -144,7 +150,11 @@ static void setup_clocks(void) { * present. If no bootloader is present, the user NVIC usually starts * at the Flash base address, 0x08000000. */ -#define USER_ADDR_ROM 0x08005000 +#if defined(BOOTLOADER_maple) + #define USER_ADDR_ROM 0x08005000 +#else + #define USER_ADDR_ROM 0x08000000 +#endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; @@ -165,7 +175,7 @@ static void setup_nvic(void) { #endif } -static void adc_default_config(const adc_dev *dev) { +static void adc_default_config(adc_dev *dev) { adc_enable_single_swstart(dev); adc_set_sample_rate(dev, wirish::priv::w_adc_smp); } diff --git a/STM32F3/cores/maple/wirish/stm32f3/boards_setup.cpp b/STM32F1/variants/generic_stm32f103vb/wirish/boards_setup.cpp similarity index 54% rename from STM32F3/cores/maple/wirish/stm32f3/boards_setup.cpp rename to STM32F1/variants/generic_stm32f103vb/wirish/boards_setup.cpp index 698441974..5ea718b4c 100644 --- a/STM32F3/cores/maple/wirish/stm32f3/boards_setup.cpp +++ b/STM32F1/variants/generic_stm32f103vb/wirish/boards_setup.cpp @@ -2,7 +2,6 @@ * The MIT License * * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -26,12 +25,11 @@ *****************************************************************************/ /** - * @file wirish/stm32f3/boards_setup.cpp - * @author Marti Bolivar , - * Hanspeter Portner - * @brief STM32F3 chip setup. + * @file wirish/stm32f1/boards_setup.cpp + * @author Marti Bolivar + * @brief STM32F1 chip setup. * - * This file controls how init() behaves on the STM32F3. Be very + * This file controls how init() behaves on the STM32F1. Be very * careful when changing anything here. Many of these values depend * upon each other. */ @@ -41,27 +39,41 @@ #include #include -#include -#include -#include -#include +#include +#include // Allow boards to provide a PLL multiplier. This is useful for -// e.g. STM32F300 value line MCUs, which use slower multipliers. +// e.g. STM32F100 value line MCUs, which use slower multipliers. // (We're leaving the default to RCC_PLLMUL_9 for now, since that -// works for F303 performance line MCUs, which is all that LeafLabs +// works for F103 performance line MCUs, which is all that LeafLabs // currently officially supports). #ifndef BOARD_RCC_PLLMUL -#define BOARD_RCC_PLLMUL RCC_PLLMUL_9 + #if !USE_HSI_CLOCK + #if F_CPU==128000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 + #elif F_CPU==72000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 + #elif F_CPU==48000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 + #endif + #else + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 + #endif #endif namespace wirish { namespace priv { - static stm32f3_rcc_pll_data pll_data = {.pll_mul=BOARD_RCC_PLLMUL, .pclk_prediv=RCC_PREDIV_PCLK_DIV_1}; + static stm32f1_rcc_pll_data pll_data = {BOARD_RCC_PLLMUL}; +#if !USE_HSI_CLOCK __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data}; - __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK_DIV_1; - __weak adc_smp_rate w_adc_smp = ADC_SMPR_181_5; +#else + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data}; +#endif + __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6; + __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5; __weak void board_reset_pll(void) { // TODO @@ -71,6 +83,12 @@ namespace wirish { rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); + rcc_clk_disable(RCC_USB); + #if F_CPU == 72000000 + rcc_set_prescaler(RCC_PRESCALER_USB, RCC_USB_SYSCLK_DIV_1_5); + #elif F_CPU == 48000000 + rcc_set_prescaler(RCC_PRESCALER_USB, RCC_USB_SYSCLK_DIV_1); + #endif } __weak void board_setup_gpio(void) { @@ -78,15 +96,26 @@ namespace wirish { } __weak void board_setup_usb(void) { - SerialUSB.begin(); +#ifdef SERIAL_USB + + +#ifdef GENERIC_BOOTLOADER + //Reset the USB interface on generic boards - developed by Victor PV + gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_OUTPUT_PP); + gpio_write_bit(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit,0); + + for(volatile unsigned int i=0;i<512;i++);// Only small delay seems to be needed, and USB pins will get configured in Serial.begin + gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING); +#endif + Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility +#endif } __weak void series_init(void) { - /* We need SYSCFG for external interrupts */ - syscfg_init(); - - /* enable floating point unit */ - fpu_enable(); + // Initialize AFIO here, too, so peripheral remaps and external + // interrupts work out of the box. + afio_init(); } + } } diff --git a/STM32F3/variants/discovery_f3/wirish/start.S b/STM32F1/variants/generic_stm32f103vb/wirish/start.S similarity index 100% rename from STM32F3/variants/discovery_f3/wirish/start.S rename to STM32F1/variants/generic_stm32f103vb/wirish/start.S diff --git a/STM32F3/variants/discovery_f3/wirish/start_c.c b/STM32F1/variants/generic_stm32f103vb/wirish/start_c.c similarity index 100% rename from STM32F3/variants/discovery_f3/wirish/start_c.c rename to STM32F1/variants/generic_stm32f103vb/wirish/start_c.c diff --git a/STM32F3/cores/maple/wirish/syscalls.c b/STM32F1/variants/generic_stm32f103vb/wirish/syscalls.c similarity index 75% rename from STM32F3/cores/maple/wirish/syscalls.c rename to STM32F1/variants/generic_stm32f103vb/wirish/syscalls.c index a3b6d2c85..ec1c34dba 100644 --- a/STM32F3/cores/maple/wirish/syscalls.c +++ b/STM32F1/variants/generic_stm32f103vb/wirish/syscalls.c @@ -37,17 +37,18 @@ #include #include +#include /* If CONFIG_HEAP_START (or CONFIG_HEAP_END) isn't defined, then * assume _lm_heap_start (resp. _lm_heap_end) is appropriately set by * the linker */ #ifndef CONFIG_HEAP_START extern char _lm_heap_start; -#define CONFIG_HEAP_START ((caddr_t)&_lm_heap_start) +#define CONFIG_HEAP_START ((void *)&_lm_heap_start) #endif #ifndef CONFIG_HEAP_END extern char _lm_heap_end; -#define CONFIG_HEAP_END ((caddr_t)&_lm_heap_end) +#define CONFIG_HEAP_END ((void *)&_lm_heap_end) #endif /* @@ -56,9 +57,9 @@ extern char _lm_heap_end; * Get incr bytes more RAM (for use by the heap). malloc() and * friends call this function behind the scenes. */ -caddr_t _sbrk(int incr) { - static caddr_t pbreak = NULL; /* current program break */ - caddr_t ret; +void *_sbrk(int incr) { + static void * pbreak = NULL; /* current program break */ + void * ret; if (pbreak == NULL) { pbreak = CONFIG_HEAP_START; @@ -67,7 +68,7 @@ caddr_t _sbrk(int incr) { if ((CONFIG_HEAP_END - pbreak < incr) || (pbreak - CONFIG_HEAP_START < -incr)) { errno = ENOMEM; - return (caddr_t)-1; + return (void *)-1; } ret = pbreak; @@ -75,28 +76,28 @@ caddr_t _sbrk(int incr) { return ret; } -__weak int _open(const char *path, int flags, ...) { +__weak int _open(const char *path __attribute__((unused)), int flags __attribute__((unused)), ...) { return 1; } -__weak int _close(int fd) { +__weak int _close(int fd __attribute__((unused))) { return 0; } -__weak int _fstat(int fd, struct stat *st) { +__weak int _fstat(int fd __attribute__((unused)), struct stat *st) { st->st_mode = S_IFCHR; return 0; } -__weak int _isatty(int fd) { +__weak int _isatty(int fd __attribute__((unused))) { return 1; } -__weak int isatty(int fd) { +__weak int isatty(int fd __attribute__((unused))) { return 1; } -__weak int _lseek(int fd, off_t pos, int whence) { +__weak int _lseek(int fd __attribute__((unused)), off_t pos __attribute__((unused)), int whence __attribute__((unused))) { return -1; } @@ -105,13 +106,13 @@ __weak unsigned char getch(void) { } -__weak int _read(int fd, char *buf, size_t cnt) { +__weak int _read(int fd __attribute__((unused)), char *buf, size_t cnt __attribute__((unused))) { *buf = getch(); return 1; } -__weak void putch(unsigned char c) { +__weak void putch(unsigned char c __attribute__((unused))) { } __weak void cgets(char *s, int bufsize) { @@ -154,7 +155,7 @@ __weak void cgets(char *s, int bufsize) { return; } -__weak int _write(int fd, const char *buf, size_t cnt) { +__weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { int i; for (i = 0; i < cnt; i++) @@ -164,12 +165,12 @@ __weak int _write(int fd, const char *buf, size_t cnt) { } /* Override fgets() in newlib with a version that does line editing */ -__weak char *fgets(char *s, int bufsize, void *f) { +__weak char *fgets(char *s, int bufsize, void *f __attribute__((unused))) { cgets(s, bufsize); return s; } -__weak void _exit(int exitcode) { +__weak void _exit(int exitcode __attribute__((unused))) { while (1) ; } diff --git a/STM32F1/variants/generic_stm32f103z/board.cpp b/STM32F1/variants/generic_stm32f103z/board.cpp index 500f9b86d..a6cceebd9 100644 --- a/STM32F1/variants/generic_stm32f103z/board.cpp +++ b/STM32F1/variants/generic_stm32f103z/board.cpp @@ -217,17 +217,8 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN }; - -#ifdef SERIAL_USB - DEFINE_HWSERIAL(Serial1, 1); - DEFINE_HWSERIAL(Serial2, 2); - DEFINE_HWSERIAL(Serial3, 3); - DEFINE_HWSERIAL_UART(Serial4, 4); - DEFINE_HWSERIAL_UART(Serial5, 5); -#else - DEFINE_HWSERIAL(Serial, 1); - DEFINE_HWSERIAL(Serial1, 2); - DEFINE_HWSERIAL(Serial2, 3); - DEFINE_HWSERIAL_UART(Serial3, 4); - DEFINE_HWSERIAL_UART(Serial4, 5); -#endif +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); +DEFINE_HWSERIAL(Serial3, 3); +DEFINE_HWSERIAL_UART(Serial4, 4); +DEFINE_HWSERIAL_UART(Serial5, 5); diff --git a/STM32F1/variants/generic_stm32f103z/wirish/boards.cpp b/STM32F1/variants/generic_stm32f103z/wirish/boards.cpp index fcb85b2ab..93ae23151 100644 --- a/STM32F1/variants/generic_stm32f103z/wirish/boards.cpp +++ b/STM32F1/variants/generic_stm32f103z/wirish/boards.cpp @@ -120,12 +120,12 @@ static void setup_clocks(void) { // Clear clock readiness interrupt flags and turn off clock // readiness interrupts. RCC_BASE->CIR = 0x00000000; - +#if !USE_HSI_CLOCK // Enable HSE, and wait until it's ready. rcc_turn_on_clk(RCC_CLK_HSE); while (!rcc_is_clk_ready(RCC_CLK_HSE)) ; - +#endif // Configure AHBx, APBx, etc. prescalers and the main PLL. wirish::priv::board_setup_clock_prescalers(); rcc_configure_pll(&wirish::priv::w_board_pll_cfg); @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/generic_stm32f103z/wirish/boards_setup.cpp b/STM32F1/variants/generic_stm32f103z/wirish/boards_setup.cpp index 3d4e4e8cf..6cc457eee 100644 --- a/STM32F1/variants/generic_stm32f103z/wirish/boards_setup.cpp +++ b/STM32F1/variants/generic_stm32f103z/wirish/boards_setup.cpp @@ -48,20 +48,30 @@ // works for F103 performance line MCUs, which is all that LeafLabs // currently officially supports). #ifndef BOARD_RCC_PLLMUL + #if !USE_HSI_CLOCK #if F_CPU==128000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 #elif F_CPU==72000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif + #else + #define BOARD_RCC_PLLMUL RCC_PLLMUL_16 + #endif #endif namespace wirish { namespace priv { static stm32f1_rcc_pll_data pll_data = {BOARD_RCC_PLLMUL}; +#if !USE_HSI_CLOCK __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data}; +#else + __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data}; +#endif __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6; __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5; diff --git a/STM32F1/variants/generic_stm32f103z/wirish/syscalls.c b/STM32F1/variants/generic_stm32f103z/wirish/syscalls.c index 91ed5a104..ad878cb24 100644 --- a/STM32F1/variants/generic_stm32f103z/wirish/syscalls.c +++ b/STM32F1/variants/generic_stm32f103z/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/hytiny_stm32f103t/board.cpp b/STM32F1/variants/hytiny_stm32f103t/board.cpp index f1fb44f07..337967fe4 100644 --- a/STM32F1/variants/hytiny_stm32f103t/board.cpp +++ b/STM32F1/variants/hytiny_stm32f103t/board.cpp @@ -109,14 +109,6 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { * Moved definitions for Hardware Serial devices from HardwareSerial.cpp so that each board can define which Arduino "Serial" instance * Maps to which hardware serial port on the microprocessor */ - -#ifdef SERIAL_USB - DEFINE_HWSERIAL(Serial1, 1); - DEFINE_HWSERIAL(Serial2, 2); - -#else - DEFINE_HWSERIAL(Serial, 1); - - DEFINE_HWSERIAL(Serial1, 2); -#endif +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); diff --git a/STM32F1/variants/hytiny_stm32f103t/wirish/boards.cpp b/STM32F1/variants/hytiny_stm32f103t/wirish/boards.cpp index 0a358ee19..d7b6edca3 100644 --- a/STM32F1/variants/hytiny_stm32f103t/wirish/boards.cpp +++ b/STM32F1/variants/hytiny_stm32f103t/wirish/boards.cpp @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/hytiny_stm32f103t/wirish/boards_setup.cpp b/STM32F1/variants/hytiny_stm32f103t/wirish/boards_setup.cpp index f10fcf864..905198972 100644 --- a/STM32F1/variants/hytiny_stm32f103t/wirish/boards_setup.cpp +++ b/STM32F1/variants/hytiny_stm32f103t/wirish/boards_setup.cpp @@ -54,6 +54,8 @@ #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif #endif diff --git a/STM32F1/variants/hytiny_stm32f103t/wirish/syscalls.c b/STM32F1/variants/hytiny_stm32f103t/wirish/syscalls.c index ec1c34dba..156d2a3d1 100644 --- a/STM32F1/variants/hytiny_stm32f103t/wirish/syscalls.c +++ b/STM32F1/variants/hytiny_stm32f103t/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/maple/wirish/boards.cpp b/STM32F1/variants/maple/wirish/boards.cpp index fcb85b2ab..ef1f2ad28 100644 --- a/STM32F1/variants/maple/wirish/boards.cpp +++ b/STM32F1/variants/maple/wirish/boards.cpp @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/maple/wirish/boards_setup.cpp b/STM32F1/variants/maple/wirish/boards_setup.cpp index c4b55c099..d1170cdbe 100644 --- a/STM32F1/variants/maple/wirish/boards_setup.cpp +++ b/STM32F1/variants/maple/wirish/boards_setup.cpp @@ -54,6 +54,8 @@ #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif #endif diff --git a/STM32F1/variants/maple/wirish/syscalls.c b/STM32F1/variants/maple/wirish/syscalls.c index ec1c34dba..156d2a3d1 100644 --- a/STM32F1/variants/maple/wirish/syscalls.c +++ b/STM32F1/variants/maple/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/maple_mini/wirish/boards.cpp b/STM32F1/variants/maple_mini/wirish/boards.cpp index 5274e7a93..7b7e9a685 100644 --- a/STM32F1/variants/maple_mini/wirish/boards.cpp +++ b/STM32F1/variants/maple_mini/wirish/boards.cpp @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/maple_mini/wirish/boards_setup.cpp b/STM32F1/variants/maple_mini/wirish/boards_setup.cpp index f10fcf864..905198972 100644 --- a/STM32F1/variants/maple_mini/wirish/boards_setup.cpp +++ b/STM32F1/variants/maple_mini/wirish/boards_setup.cpp @@ -54,6 +54,8 @@ #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif #endif diff --git a/STM32F1/variants/maple_mini/wirish/syscalls.c b/STM32F1/variants/maple_mini/wirish/syscalls.c index ec1c34dba..156d2a3d1 100644 --- a/STM32F1/variants/maple_mini/wirish/syscalls.c +++ b/STM32F1/variants/maple_mini/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/maple_ret6/board/board.h b/STM32F1/variants/maple_ret6/board/board.h index 86d94f07c..4f6fae753 100644 --- a/STM32F1/variants/maple_ret6/board/board.h +++ b/STM32F1/variants/maple_ret6/board/board.h @@ -102,6 +102,16 @@ #define BOARD_USB_DISC_DEV GPIOC #define BOARD_USB_DISC_BIT 12 +/* + * SDIO Pins + */ +#define BOARD_SDIO_D0 PC8 +#define BOARD_SDIO_D1 PC9 +#define BOARD_SDIO_D2 PC10 +#define BOARD_SDIO_D3 PC11 +#define BOARD_SDIO_CLK PC12 +#define BOARD_SDIO_CMD PD2 + /* Pin aliases: these give the GPIO port/bit for each pin as an * enum. These are optional, but recommended. They make it easier to * write code using low-level GPIO functionality. */ @@ -117,4 +127,4 @@ enum { //15 16 17 18 19 20 21 22 23 24 25 26 27 28 -//29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 \ No newline at end of file +//29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 diff --git a/STM32F1/variants/maple_ret6/wirish/boards.cpp b/STM32F1/variants/maple_ret6/wirish/boards.cpp index fcb85b2ab..ef1f2ad28 100644 --- a/STM32F1/variants/maple_ret6/wirish/boards.cpp +++ b/STM32F1/variants/maple_ret6/wirish/boards.cpp @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/maple_ret6/wirish/boards_setup.cpp b/STM32F1/variants/maple_ret6/wirish/boards_setup.cpp index c4b55c099..d1170cdbe 100644 --- a/STM32F1/variants/maple_ret6/wirish/boards_setup.cpp +++ b/STM32F1/variants/maple_ret6/wirish/boards_setup.cpp @@ -54,6 +54,8 @@ #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif #endif diff --git a/STM32F1/variants/maple_ret6/wirish/syscalls.c b/STM32F1/variants/maple_ret6/wirish/syscalls.c index ec1c34dba..156d2a3d1 100644 --- a/STM32F1/variants/maple_ret6/wirish/syscalls.c +++ b/STM32F1/variants/maple_ret6/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/microduino/wirish/boards.cpp b/STM32F1/variants/microduino/wirish/boards.cpp index fcb85b2ab..ef1f2ad28 100644 --- a/STM32F1/variants/microduino/wirish/boards.cpp +++ b/STM32F1/variants/microduino/wirish/boards.cpp @@ -147,11 +147,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/microduino/wirish/boards_setup.cpp b/STM32F1/variants/microduino/wirish/boards_setup.cpp index 785753a20..1f1ec5ec8 100644 --- a/STM32F1/variants/microduino/wirish/boards_setup.cpp +++ b/STM32F1/variants/microduino/wirish/boards_setup.cpp @@ -54,6 +54,8 @@ #define BOARD_RCC_PLLMUL RCC_PLLMUL_9 #elif F_CPU==48000000 #define BOARD_RCC_PLLMUL RCC_PLLMUL_6 + #elif F_CPU==16000000 + #define BOARD_RCC_PLLMUL RCC_PLLMUL_2 #endif #endif diff --git a/STM32F1/variants/microduino/wirish/syscalls.c b/STM32F1/variants/microduino/wirish/syscalls.c index ec1c34dba..156d2a3d1 100644 --- a/STM32F1/variants/microduino/wirish/syscalls.c +++ b/STM32F1/variants/microduino/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F1/variants/nucleo_f103rb/board.cpp b/STM32F1/variants/nucleo_f103rb/board.cpp index 9f3e08ae7..b7d82f7ca 100644 --- a/STM32F1/variants/nucleo_f103rb/board.cpp +++ b/STM32F1/variants/nucleo_f103rb/board.cpp @@ -248,12 +248,6 @@ MOSI alternate functions on the GPIO ports. * Maps to which hardware serial port on the microprocessor */ -#ifdef SERIAL_USB - DEFINE_HWSERIAL(Serial1, 1); - DEFINE_HWSERIAL(Serial2, 2); - DEFINE_HWSERIAL(Serial3, 3); -#else - DEFINE_HWSERIAL(Serial, 3);// Use HW Serial 2 as "Serial" - DEFINE_HWSERIAL(Serial1, 2); - DEFINE_HWSERIAL(Serial2, 1); -#endif \ No newline at end of file +DEFINE_HWSERIAL(Serial1, 1); +DEFINE_HWSERIAL(Serial2, 2); +DEFINE_HWSERIAL(Serial3, 3); diff --git a/STM32F1/variants/nucleo_f103rb/wirish/boards.cpp b/STM32F1/variants/nucleo_f103rb/wirish/boards.cpp index f38cbf6a8..61368ce0a 100644 --- a/STM32F1/variants/nucleo_f103rb/wirish/boards.cpp +++ b/STM32F1/variants/nucleo_f103rb/wirish/boards.cpp @@ -149,11 +149,7 @@ static void setup_clocks(void) { #if defined(BOOTLOADER_maple) #define USER_ADDR_ROM 0x08005000 #else - #if defined(BOOTLOADER_robotis) - #define USER_ADDR_ROM 0x08003000 - #else - #define USER_ADDR_ROM 0x08000000 - #endif + #define USER_ADDR_ROM 0x08000000 #endif #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; diff --git a/STM32F1/variants/nucleo_f103rb/wirish/syscalls.c b/STM32F1/variants/nucleo_f103rb/wirish/syscalls.c index ec1c34dba..156d2a3d1 100644 --- a/STM32F1/variants/nucleo_f103rb/wirish/syscalls.c +++ b/STM32F1/variants/nucleo_f103rb/wirish/syscalls.c @@ -156,7 +156,7 @@ __weak void cgets(char *s, int bufsize) { } __weak int _write(int fd __attribute__((unused)), const char *buf, size_t cnt) { - int i; + size_t i; for (i = 0; i < cnt; i++) putch(buf[i]); diff --git a/STM32F3/README.md b/STM32F3/README.md deleted file mode 100644 index 75cd5a402..000000000 --- a/STM32F3/README.md +++ /dev/null @@ -1,45 +0,0 @@ -STM32F3 files have been supplied by Frank-Michael Krause. - -The API is not as up to date as in the STM F103 files. -It looks like this port is as the F103 files orginally were when I started work on the project. -The API is for pre- Arduino 1.0 and doesn't include a lot of functions in the 1.0 API, and the class inheritance will -be different in a number of places, most importantly in the Serial class. -Specifically Stream.cpp / .h are not present in this port. - - - --------------------- Details from Frank-Michael ---------------------------- - -This port of libmaple for Arduino-IDE is based on the inofficial F3 branch -of libmaple found on -https://github.com/ventosus/libmaple/tree/F3 -and supports at the moment the STM32F3Discovery board with programming via ST-link. -Linker is configured for linking to flash, not to RAM - -Changes by Frank-Michael Krause (mich dot krause at web dot de): - -- renaming some stm32f3 related files because the Arduino build system copy all objects to same directory so the source file names must be different -- selected the correct startup modules and linker scripts for board variant stm32f3discovery - -Notes: - -- the pin names as noted on stm32f3discovery board (PA0, PA1, ..., PF10) can be used as pin id -- usb is untested because I haven't used it really -- There are some libraries and examples related to the STM32F3discovery board. - They are commented mostly in german only because I wrote them for use at robotic club of a secondary school - and the kids like to have the documentation in german. - - gyro: Interface library for the gyro-chip of the stm32f3discovery, setup the gyro in FIFO mode and so - requiring update calls only every < 120ms - lsm303: Interface library for Acceleration sensor of the stm32f3discovery, magnetometer not yet supported (writing this driver is currently under work by a student at school) - ringbuffer: Class impelentig a ringbuffer with functions for adding time stampes per added element, averaging functions, accessing the stored data like an array - roboter: several functionalities needed to program a robot: - - dc motor control as known from Lego NXC language - - support for HC-SR04 ultrasonic sensors driven by interrupt or blocking direct measurement - - function timers based on timer interrupt - - modul for interfacing a 24Cxx I2C eeprom chip - - - - - diff --git a/STM32F3/boards.txt b/STM32F3/boards.txt deleted file mode 100644 index 98a184df4..000000000 --- a/STM32F3/boards.txt +++ /dev/null @@ -1,62 +0,0 @@ -# - -menu.opt=Optimize - -############################################################## -discovery_f3.name=STM32F3Discovery - -discovery_f3.upload.tool=stlink -discovery_f3.upload.protocol=stlink - -#discovery_f407.upload.use_1200bps_touch=false -discovery_f3.upload.file_type=bin -discovery_f3.upload.maximum_size=262144 -discovery_f3.upload.maximum_data_size=49152 - -#discovery_f3.upload.usbID=1EAF:0003 -#discovery_f3.upload.altID=1 -#discovery_f3.upload.auto_reset=true - -discovery_f3.build.mcu=cortex-m3 -discovery_f3.build.f_cpu=72000000L -discovery_f3.build.core=maple -discovery_f3.build.extra_flags=-DMCU_STM32F303VC -mthumb -DSTM32_XL_DENSITY -march=armv7-m -DSTM32F3 -DF303VC -DBOARD_discovery_f3 -discovery_f3.build.ldscript=ld/jtag.ld -discovery_f3.build.variant=discovery_f3 -discovery_f3.build.variant_system_lib=lib_f3.a -discovery_f3.build.vect=VECT_TAB_BASE -discovery_f3.build.density=STM32_XL_DENSITY -discovery_f3.build.error_led_port=GPIOE -discovery_f3.build.error_led_pin=8 -discovery_f3.build.board=STM32F3Discovery - -#-- Optimizations -discovery_f3.menu.opt.osstd=Smallest (default) -discovery_f3.menu.opt.osstd.build.flags.optimize=-Os -discovery_f3.menu.opt.osstd.build.flags.ldspecs= -discovery_f3.menu.opt.oslto=Smallest Code with LTO -discovery_f3.menu.opt.oslto.build.flags.optimize=-Os -flto -discovery_f3.menu.opt.oslto.build.flags.ldspecs=-flto -discovery_f3.menu.opt.o1std=Fast (-O1) -discovery_f3.menu.opt.o1std.build.flags.optimize=-O1 -discovery_f3.menu.opt.o1std.build.flags.ldspecs= -discovery_f3.menu.opt.o1lto=Fast (-O1) with LTO -discovery_f3.menu.opt.o1lto.build.flags.optimize=-O1 -flto -discovery_f3.menu.opt.o1lto.build.flags.ldspecs=-flto -discovery_f3.menu.opt.o2std=Faster (-O2) -discovery_f3.menu.opt.o2std.build.flags.optimize=-O2 -discovery_f3.menu.opt.o2std.build.flags.ldspecs= -discovery_f3.menu.opt.o2lto=Faster (-O2) with LTO -discovery_f3.menu.opt.o2lto.build.flags.optimize=-O2 -flto -discovery_f3.menu.opt.o2lto.build.flags.ldspecs=-flto -discovery_f3.menu.opt.o3std=Fastest (-O3) -discovery_f3.menu.opt.o3std.build.flags.optimize=-O3 -discovery_f3.menu.opt.o3std.build.flags.ldspecs= -discovery_f3.menu.opt.o3lto=Fastest (-O3) with LTO -discovery_f3.menu.opt.o3lto.build.flags.optimize=-O3 -flto -discovery_f3.menu.opt.o3lto.build.flags.ldspecs=-flto -discovery_f3.menu.opt.ogstd=Debug (-g) -discovery_f3.menu.opt.ogstd.build.flags.optimize=-Og -discovery_f3.menu.opt.ogstd.build.flags.ldspecs= -############################################################## - diff --git a/STM32F3/cores/maple/Arduino.h b/STM32F3/cores/maple/Arduino.h deleted file mode 100644 index 7278f8990..000000000 --- a/STM32F3/cores/maple/Arduino.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef Arduino_h -#define Arduino_h -#include "WProgram.h" -#endif diff --git a/STM32F3/cores/maple/WProgram.h b/STM32F3/cores/maple/WProgram.h deleted file mode 100644 index b24ec2a30..000000000 --- a/STM32F3/cores/maple/WProgram.h +++ /dev/null @@ -1,35 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#ifndef _WIRISH_WPROGRAM_H_ -#define _WIRISH_WPROGRAM_H_ - -#include - -void setup(); -void loop(); - -#endif diff --git a/STM32F3/cores/maple/libmaple/adc.c b/STM32F3/cores/maple/libmaple/adc.c deleted file mode 100644 index 630a8a88f..000000000 --- a/STM32F3/cores/maple/libmaple/adc.c +++ /dev/null @@ -1,52 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/adc.c - * @author Marti Bolivar , - * Perry Hung , - * F3-port by Hanspeter Portner - * @brief Analog to digital converter routines - */ - -#include -#include -#include - -/** - * @brief Initialize an ADC peripheral. - * - * Initializes the RCC clock line for the given peripheral. Resets - * ADC device registers. - * - * @param dev ADC peripheral to initialize - */ -void adc_init(const adc_dev *dev) { - rcc_clk_enable(dev->clk_id); - rcc_reset_dev(dev->clk_id); -} diff --git a/STM32F3/cores/maple/libmaple/bkp.c b/STM32F3/cores/maple/libmaple/bkp.c deleted file mode 100644 index c8373079b..000000000 --- a/STM32F3/cores/maple/libmaple/bkp.c +++ /dev/null @@ -1,69 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/bkp.c - * @author F3-port by Hanspeter Portner - * @brief Backup register support (STM32F1 & STM32F3 only). - */ - -#include -#include -#include - -bkp_dev bkp = { - .regs = BKP_BASE, -}; -/** Backup device. */ -const bkp_dev *BKP = &bkp; - -void bkp_enable_writes(void) { - *bb_perip(&PWR_BASE->CR, PWR_CR_DBP_BIT) = 1; -} - -void bkp_disable_writes(void) { - *bb_perip(&PWR_BASE->CR, PWR_CR_DBP_BIT) = 0; -} - -uint16 bkp_read(uint8 reg) { - __io uint32* dr = bkp_data_register(reg); - if (!dr) { - ASSERT(0); /* nonexistent register */ - return 0; - } - return (uint16)*dr; -} - -void bkp_write(uint8 reg, uint16 val) { - __io uint32* dr = bkp_data_register(reg); - if (!dr) { - ASSERT(0); /* nonexistent register */ - return; - } - *dr = (uint32)val; -} - diff --git a/STM32F3/cores/maple/libmaple/dac.c b/STM32F3/cores/maple/libmaple/dac.c deleted file mode 100644 index d802d2b0c..000000000 --- a/STM32F3/cores/maple/libmaple/dac.c +++ /dev/null @@ -1,120 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/dac.c - * @brief Digital to analog converter support. - */ - -#include -#include -#include - -#if STM32_HAVE_DAC -dac_dev dac = { - .regs = DAC_BASE, -}; -const dac_dev *DAC = &dac; -#endif - -/** - * @brief Initialize the digital to analog converter - * @param dev DAC device - * @param flags Flags: - * DAC_CH1: Enable channel 1 - * DAC_CH2: Enable channel 2 - * @sideeffect May set PA4 or PA5 to INPUT_ANALOG - */ -void dac_init(const dac_dev *dev, uint32 flags) { - /* First turn on the clock */ - rcc_clk_enable(RCC_DAC); - rcc_reset_dev(RCC_DAC); - - if (flags & DAC_CH1) { - dac_enable_channel(dev, 1); - } - - if (flags & DAC_CH2) { - dac_enable_channel(dev, 2); - } -} - -/** - * @brief Write a 12-bit value to the DAC to output - * @param dev DAC device - * @param channel channel to select (1 or 2) - * @param val value to write - */ -void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val) { - switch(channel) { - case 1: - dev->regs->DHR12R1 = DAC_DHR12R1_DACC1DHR & val; - break; - case 2: - dev->regs->DHR12R2 = DAC_DHR12R2_DACC2DHR & val; - break; - } -} - -/** - * @brief Enable a DAC channel - * @param dev DAC device - * @param channel channel to enable, either 1 or 2 - * @sideeffect May change pin mode of PA4 or PA5 - */ -void dac_enable_channel(const dac_dev *dev, uint8 channel) { - /* - * Setup ANALOG mode on PA4 and PA5. This mapping is consistent - * across all supported STM32s with a DAC. - */ - switch (channel) { - case 1: - gpio_set_mode(GPIOA, 4, GPIO_MODE_ANALOG); - dev->regs->CR |= DAC_CR_EN1; - break; - case 2: - gpio_set_mode(GPIOA, 5, GPIO_MODE_ANALOG); - dev->regs->CR |= DAC_CR_EN2; - break; - } -} - -/** - * @brief Disable a DAC channel - * @param dev DAC device - * @param channel channel to disable, either 1 or 2 - */ -void dac_disable_channel(const dac_dev *dev, uint8 channel) { - switch (channel) { - case 1: - dev->regs->CR &= ~DAC_CR_EN1; - break; - case 2: - dev->regs->CR &= ~DAC_CR_EN2; - break; - } -} diff --git a/STM32F3/cores/maple/libmaple/dma.c b/STM32F3/cores/maple/libmaple/dma.c deleted file mode 100644 index d13de1081..000000000 --- a/STM32F3/cores/maple/libmaple/dma.c +++ /dev/null @@ -1,82 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/dma.c - * @author Marti Bolivar ; - * Original implementation by Michael Hope - * @brief Portable DMA routines. - */ - -#include -#include "dma_private.h" -#include "stm32_private.h" - -/* - * Convenience routines - */ - -/** - * @brief Initialize a DMA device. - * @param dev Device to initialize. - */ -void dma_init(dma_dev *dev) { - rcc_clk_enable(dev->clk_id); -} - -/* - * Private API - */ - -enum dma_atype _dma_addr_type(__io void *addr) { - switch (stm32_block_purpose((void*)addr)) { - /* Notice we're treating the code block as memory here. That's - * correct for addresses in Flash and in [0x0, 0x7FFFFFF] - * (provided that those addresses are aliased to Flash, SRAM, or - * FSMC, depending on BOOT[01] and possibly SYSCFG_MEMRMP). It's - * not correct for other addresses in the code block, but those - * will (hopefully) just fail-fast with transfer or bus errors. If - * lots of people get confused, it might be worth being more - * careful here. */ - case STM32_BLOCK_CODE: /* Fall through */ - case STM32_BLOCK_SRAM: /* ... */ - case STM32_BLOCK_FSMC_1_2: /* ... */ - case STM32_BLOCK_FSMC_3_4: - return DMA_ATYPE_MEM; - case STM32_BLOCK_PERIPH: - return DMA_ATYPE_PER; - case STM32_BLOCK_FSMC_REG: /* Fall through */ - /* Is this right? I can't think of a reason to DMA into or out - * of the FSMC registers. [mbolivar] */ - case STM32_BLOCK_UNUSED: /* ... */ - case STM32_BLOCK_CORTEX_INTERNAL: /* ... */ - return DMA_ATYPE_OTHER; - default: - ASSERT(0); /* Can't happen */ - return DMA_ATYPE_OTHER; - } -} diff --git a/STM32F3/cores/maple/libmaple/exc.S b/STM32F3/cores/maple/libmaple/exc.S deleted file mode 100644 index 7631e4885..000000000 --- a/STM32F3/cores/maple/libmaple/exc.S +++ /dev/null @@ -1,101 +0,0 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -# On an exception, push a fake stack thread mode stack frame and redirect -# thread execution to a thread mode error handler - -# From RM008: -# The SP is decremented by eight words by the completion of the stack push. -# Figure 5-1 shows the contents of the stack after an exception pre-empts the -# current program flow. -# -# Old SP--> -# xPSR -# PC -# LR -# r12 -# r3 -# r2 -# r1 -# SP--> r0 - -.text -.globl __exc_hardfault -.globl __exc_nmi -.globl __exc_hardfault -.globl __exc_memmanage -.globl __exc_busfault -.globl __exc_usagefault - -.code 16 -.thumb_func -__exc_nmi: - mov r0, #1 - b __default_exc - -.thumb_func -__exc_hardfault: - mov r0, #2 - b __default_exc - -.thumb_func -__exc_memmanage: - mov r0, #3 - b __default_exc - -.thumb_func -__exc_busfault: - mov r0, #4 - b __default_exc - -.thumb_func -__exc_usagefault: - mov r0, #5 - b __default_exc - -.thumb_func -__default_exc: - ldr r2, NVIC_CCR @ Enable returning to thread mode even if there are - mov r1 ,#1 @ pending exceptions. See flag NONEBASETHRDENA. - str r1, [r2] - cpsid i @ Disable global interrupts - ldr r2, SYSTICK_CSR @ Disable systick handler - mov r1, #0 - str r1, [r2] - ldr r1, CPSR_MASK @ Set default CPSR - push {r1} - ldr r1, TARGET_PC @ Set target pc - push {r1} - sub sp, sp, #24 @ Don't care - ldr r1, EXC_RETURN @ Return to thread mode - mov lr, r1 - bx lr @ Exception exit - -.align 4 -CPSR_MASK: .word 0x61000000 -EXC_RETURN: .word 0xFFFFFFF9 -TARGET_PC: .word __error -NVIC_CCR: .word 0xE000ED14 @ NVIC configuration control register -SYSTICK_CSR: .word 0xE000E010 @ Systick control register - diff --git a/STM32F3/cores/maple/libmaple/exti.c b/STM32F3/cores/maple/libmaple/exti.c deleted file mode 100644 index c35072ca3..000000000 --- a/STM32F3/cores/maple/libmaple/exti.c +++ /dev/null @@ -1,293 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/exti.c - * @brief External interrupt control routines - */ - -#include -#include -#include -#include - -static inline void dispatch_single_exti(uint32 exti_num); -static inline void dispatch_extis(uint32 start, uint32 stop); - -/* - * Internal state - */ - -typedef struct exti_channel { - void (*handler)(void *); - void *arg; -} exti_channel; - -static exti_channel exti_channels[] = { - { .handler = NULL, .arg = NULL }, // EXTI0 - { .handler = NULL, .arg = NULL }, // EXTI1 - { .handler = NULL, .arg = NULL }, // EXTI2 - { .handler = NULL, .arg = NULL }, // EXTI3 - { .handler = NULL, .arg = NULL }, // EXTI4 - { .handler = NULL, .arg = NULL }, // EXTI5 - { .handler = NULL, .arg = NULL }, // EXTI6 - { .handler = NULL, .arg = NULL }, // EXTI7 - { .handler = NULL, .arg = NULL }, // EXTI8 - { .handler = NULL, .arg = NULL }, // EXTI9 - { .handler = NULL, .arg = NULL }, // EXTI10 - { .handler = NULL, .arg = NULL }, // EXTI11 - { .handler = NULL, .arg = NULL }, // EXTI12 - { .handler = NULL, .arg = NULL }, // EXTI13 - { .handler = NULL, .arg = NULL }, // EXTI14 - { .handler = NULL, .arg = NULL }, // EXTI15 -}; - -/* - * Portable routines - */ - -/** - * @brief Register a handler to run upon external interrupt. - * - * This function assumes that the interrupt request corresponding to - * the given external interrupt is masked. - * - * @param num External interrupt line number. - * @param port Port to use as source input for external interrupt. - * @param handler Function handler to execute when interrupt is triggered. - * @param mode Type of transition to trigger on, one of: - * EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING. - * @see exti_num - * @see exti_cfg - * @see voidFuncPtr - * @see exti_trigger_mode - */ -void exti_attach_interrupt(exti_num num, - exti_cfg port, - voidFuncPtr handler, - exti_trigger_mode mode) { - // Call callback version with arg being null - exti_attach_callback(num, port, (voidArgumentFuncPtr)handler, NULL, mode); -} - -/** - * @brief Register a handler with an argument to run upon external interrupt. - * - * This function assumes that the interrupt request corresponding to - * the given external interrupt is masked. - * - * @param num External interrupt line number. - * @param port Port to use as source input for external interrupt. - * @param handler Function handler to execute when interrupt is triggered. - * @param arg Argument to pass to the interrupt handler. - * @param mode Type of transition to trigger on, one of: - * EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING. - * @see exti_num - * @see exti_cfg - * @see voidFuncPtr - * @see exti_trigger_mode - */ -void exti_attach_callback(exti_num num, - exti_cfg port, - voidArgumentFuncPtr handler, - void *arg, - exti_trigger_mode mode) { - ASSERT(handler); - - /* Register the handler */ - exti_channels[num].handler = handler; - exti_channels[num].arg = arg; - - /* Set trigger mode */ - switch (mode) { - case EXTI_RISING: - bb_peri_set_bit(&EXTI_BASE->RTSR, num, 1); - break; - case EXTI_FALLING: - bb_peri_set_bit(&EXTI_BASE->FTSR, num, 1); - break; - case EXTI_RISING_FALLING: - bb_peri_set_bit(&EXTI_BASE->RTSR, num, 1); - bb_peri_set_bit(&EXTI_BASE->FTSR, num, 1); - break; - } - - /* Use the chip-specific exti_select() to map num to port */ - exti_select(num, port); - - /* Unmask external interrupt request */ - bb_peri_set_bit(&EXTI_BASE->IMR, num, 1); - - /* Enable the interrupt line */ - switch(num) - { - case EXTI0: - nvic_irq_enable(NVIC_EXTI0); - break; - case EXTI1: - nvic_irq_enable(NVIC_EXTI1); - break; - case EXTI2: - nvic_irq_enable(NVIC_EXTI2); - break; - case EXTI3: - nvic_irq_enable(NVIC_EXTI3); - break; - case EXTI4: - nvic_irq_enable(NVIC_EXTI4); - break; - case EXTI5: - case EXTI6: - case EXTI7: - case EXTI8: - case EXTI9: - nvic_irq_enable(NVIC_EXTI_9_5); - break; - case EXTI10: - case EXTI11: - case EXTI12: - case EXTI13: - case EXTI14: - case EXTI15: - nvic_irq_enable(NVIC_EXTI_15_10); - break; - } -} - -/** - * @brief Unregister an external interrupt handler - * @param num External interrupt line to disable. - * @see exti_num - */ -void exti_detach_interrupt(exti_num num) { - /* First, mask the interrupt request */ - bb_peri_set_bit(&EXTI_BASE->IMR, num, 0); - - /* Then, clear the trigger selection registers */ - bb_peri_set_bit(&EXTI_BASE->FTSR, num, 0); - bb_peri_set_bit(&EXTI_BASE->RTSR, num, 0); - - /* Finally, unregister the user's handler */ - exti_channels[num].handler = NULL; - exti_channels[num].arg = NULL; -} - -/* - * Private routines - */ - -void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port) { - uint32 shift = 4 * (num % 4); - uint32 cr = *exti_cr; - cr &= ~(0xF << shift); - cr |= port << shift; - *exti_cr = cr; -} - -/* - * Interrupt handlers - */ - -void __irq_exti0(void) { - dispatch_single_exti(EXTI0); -} - -void __irq_exti1(void) { - dispatch_single_exti(EXTI1); -} - -void __irq_exti2(void) { - dispatch_single_exti(EXTI2); - // FIXME handle capatitive touch IRQ on F302/303 -} - -void __irq_exti3(void) { - dispatch_single_exti(EXTI3); -} - -void __irq_exti4(void) { - dispatch_single_exti(EXTI4); -} - -void __irq_exti9_5(void) { - dispatch_extis(5, 9); -} - -void __irq_exti15_10(void) { - dispatch_extis(10, 15); -} - -/* - * Auxiliary functions - */ - -/* Clear the pending bits for EXTIs whose bits are set in exti_msk. - * - * If a pending bit is cleared as the last instruction in an ISR, it - * won't actually be cleared in time and the ISR will fire again. To - * compensate, this function NOPs for 2 cycles after clearing the - * pending bits to ensure it takes effect. */ -static __always_inline void clear_pending_msk(uint32 exti_msk) { - EXTI_BASE->PR = exti_msk; - asm volatile("nop"); - asm volatile("nop"); -} - -/* This dispatch routine is for non-multiplexed EXTI lines only; i.e., - * it doesn't check EXTI_PR. */ -static __always_inline void dispatch_single_exti(uint32 exti) { - voidArgumentFuncPtr handler = exti_channels[exti].handler; - - if (!handler) { - return; - } - - handler(exti_channels[exti].arg); - clear_pending_msk(1U << exti); -} - -/* Dispatch routine for EXTIs which share an IRQ. */ -static __always_inline void dispatch_extis(uint32 start, uint32 stop) { - uint32 pr = EXTI_BASE->PR; - uint32 handled_msk = 0; - uint32 exti; - - /* Dispatch user handlers for pending EXTIs. */ - for (exti = start; exti <= stop; exti++) { - uint32 eb = (1U << exti); - if (pr & eb) { - voidArgumentFuncPtr handler = exti_channels[exti].handler; - if (handler) { - handler(exti_channels[exti].arg); - handled_msk |= eb; - } - } - } - - /* Clear the pending bits for handled EXTIs. */ - clear_pending_msk(handled_msk); -} diff --git a/STM32F3/cores/maple/libmaple/exti_private.h b/STM32F3/cores/maple/libmaple/exti_private.h deleted file mode 100644 index 4f0a4cf9c..000000000 --- a/STM32F3/cores/maple/libmaple/exti_private.h +++ /dev/null @@ -1,34 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -#ifndef _LIBMAPLE_EXTI_PRIVATE_H_ -#define _LIBMAPLE_EXTI_PRIVATE_H_ - -#include - -void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port); - -#endif diff --git a/STM32F3/cores/maple/libmaple/gpio.c b/STM32F3/cores/maple/libmaple/gpio.c deleted file mode 100644 index 6e63d2f08..000000000 --- a/STM32F3/cores/maple/libmaple/gpio.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/gpio.c - * @brief Generic STM32 GPIO support. - */ - -#include -#include - -/* - * GPIO routines - */ - -/** - * Initialize a GPIO device. - * - * Enables the clock for and resets the given device. - * - * @param dev GPIO device to initialize. - */ -void gpio_init(gpio_dev *dev) { - rcc_clk_enable(dev->clk_id); - rcc_reset_dev(dev->clk_id); -} diff --git a/STM32F3/cores/maple/libmaple/i2c.c b/STM32F3/cores/maple/libmaple/i2c.c deleted file mode 100644 index 87b96d1f9..000000000 --- a/STM32F3/cores/maple/libmaple/i2c.c +++ /dev/null @@ -1,52 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/i2c.c - * @author Perry Hung , - * F3-port by Hanspeter Portner - * @brief Inter-Integrated Circuit (I2C) support. - * - * Currently, only master mode is supported. - */ - -#include "i2c_private.h" - -#include -#include -#include -#include -#include -#include - -#include - -void i2c_init(i2c_dev *dev) { - rcc_reset_dev(dev->clk_id); - rcc_clk_enable(dev->clk_id); -} diff --git a/STM32F3/cores/maple/libmaple/i2c_private.h b/STM32F3/cores/maple/libmaple/i2c_private.h deleted file mode 100644 index 4857955b7..000000000 --- a/STM32F3/cores/maple/libmaple/i2c_private.h +++ /dev/null @@ -1,75 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#ifndef _LIBMAPLE_I2C_PRIVATE_H_ -#define _LIBMAPLE_I2C_PRIVATE_H_ - -#include - -/* For old-style definitions (SDA/SCL on same GPIO device) */ -#define I2C_DEV_OLD(num, port, sda, scl) \ - { \ - .regs = I2C##num##_BASE, \ - .gpio_port = port, \ - .scl_port = NULL, \ - .sda_port = NULL, \ - .sda_pin = sda, \ - .scl_pin = scl, \ - .clk_id = RCC_I2C##num, \ - .ev_nvic_line = NVIC_I2C##num##_EV, \ - .er_nvic_line = NVIC_I2C##num##_ER, \ - .state = I2C_STATE_DISABLED, \ - } - -/* For new-style definitions (SDA/SCL may be on different GPIO devices) */ -#define I2C_DEV_NEW(num, sdaport, sdabit, sclport, sclbit) \ - { \ - .regs = I2C##num##_BASE, \ - .gpio_port = NULL, \ - .scl_port = sclport, \ - .scl_pin = sclbit, \ - .sda_port = sdaport, \ - .sda_pin = sdabit, \ - .clk_id = RCC_I2C##num, \ - .ev_nvic_line = NVIC_I2C##num##_EV, \ - .er_nvic_line = NVIC_I2C##num##_ER, \ - .state = I2C_STATE_DISABLED, \ - } - -void _i2c_irq_handler(i2c_dev *dev); -void _i2c_irq_error_handler(i2c_dev *dev); - -struct gpio_dev; - -static inline struct gpio_dev* scl_port(const i2c_dev *dev) { - return (dev->gpio_port == NULL) ? dev->scl_port : dev->gpio_port; -} - -static inline struct gpio_dev* sda_port(const i2c_dev *dev) { - return (dev->gpio_port == NULL) ? dev->sda_port : dev->gpio_port; -} - -#endif /* _LIBMAPLE_I2C_PRIVATE_H_ */ diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/adc.h b/STM32F3/cores/maple/libmaple/include/libmaple/adc.h deleted file mode 100644 index e2d711d3a..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/adc.h +++ /dev/null @@ -1,319 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/adc.h - * @author Marti Bolivar , - * Perry Hung , - * F3-port by Hanspeter Portner - * @brief Analog-to-Digital Conversion (ADC) header. - */ - -#ifndef _LIBMAPLE_ADC_H_ -#define _LIBMAPLE_ADC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include -#include - -/** - * TODO document - */ -typedef struct adc_callback_data { - uint32 irq_flags; - void *arg; -} adc_callback_data; - -/** - * TODO document - */ -typedef struct adc_private_data { - void (*handler)(adc_callback_data*); - uint32 handler_flags; - adc_callback_data cb_data; -} adc_private_data; - -/* Pull in the series header - * - * IMPORTANT: The series header must define the following: - * - * - enum adc_extsel_event (and typedef to adc_extsel_event): One per - * external event used to trigger start of conversion of a regular - * group. If two different series support the same event as a - * trigger, they must use the same token for the enumerator for that - * event. (The value of the enumerator is of course allowed to be - * different). - * - * - enum adc_smp_rate (and typedef to adc_smp_rate): One per - * available sampling time. These must be in the form ADC_SMPR_X_Y - * for X.Y cycles (e.g. ADC_SMPR_1_5 means 1.5 cycles), or - * ADC_SMPR_X for X cycles (e.g. ADC_SMPR_3 means 3 cycles). - * - * - enum adc_prescaler (and typedef): One per available prescaler, - * suitable for adc_set_prescaler. Series which have the same - * prescaler dividers (e.g. STM32F1 and STM32F2 both divide PCLK2 by - * 2, 4, 6, or 8) must provide the same tokens as enumerators, for - * portability. - */ - -#include - -/* - * Routines - */ - -extern void adc_init(const adc_dev *dev); - -/** - * @brief Set external event select for regular group - * @param dev ADC device - * @param event Event used to trigger the start of conversion. - * @see adc_extsel_event - */ -extern void adc_set_extsel(const adc_dev *dev, adc_extsel_event event); - -/** - * @brief Set the sample rate for all channels on an ADC device. - * - * Don't call this during conversion. - * - * @param dev adc device - * @param smp_rate sample rate to set - * @see adc_smp_rate - */ -extern void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate); - -/** - * @brief Enable scan mode for an ADC. - * - * In scan mode, the ADC converts all channels in a regular or - * injected sequence. After each conversion is done, the ADC - * automatically starts converting the next channel in the sequence. - * - * Scan mode is disabled by default. - * - * @see adc_disable_scan() - */ -extern void adc_enable_scan(const adc_dev *dev); - -/** - * @brief Disable scan mode for an ADC. - * - * This is the default setting. - * - * @see adc_enable_scan() - */ -extern void adc_disable_scan(const adc_dev *dev); - -/** - * @brief Enable continuous mode for an ADC. - * - * In this mode, the ADC will automatically perform conversions - * continuously until taken out of this mode or disabled. - * - * Continuous mode is disabled by default. - * - * @see adc_disable_continuous() - */ -extern void adc_enable_continuous(const adc_dev *dev); - -/** - * @brief Disable continuous mode for an ADC. - * - * This is the default setting. - * - * @see adc_enable_continuous() - */ -extern void adc_disable_continuous(const adc_dev *dev); - -/** - * @brief Set the sequence of channels to convert. - * - * This sets the (regular) sequence of up to 16 channels to convert. - * - * @param dev ADC device - * @param channels ADC channels to convert; these can repeat and may - * be in any order. - * @param len Length of `channels', from 1 to 16. - * @see adc_start_conv() - */ -extern void adc_set_conv_seq(const adc_dev *dev, const uint8 *channels, uint8 len); - -/** - * @brief Attach an interrupt handler and enable its interrupts. - * - * This function sets `handler' as the function to be called when any - * ADC interrupts for `dev' occur. At most one ADC interrupt handler - * may be attached at any time. Subsequent calls to this function will - * overwrite any previously attached handler. - * - * When `handler' is called, its argument will point to a struct - * adc_callback_data. The .irq_flags field in this struct will be a - * logical OR of adc_interrupt_id values encoding the reason(s) for - * the call. Its .arg field will be the `arg' argument to this - * function. - * - * The interrupt bits set in the adc_callback_data's .irq_flags will - * always be a subset of those set in the `interrupt_flags' argument - * to this function. That is, interrupts not given here in the - * `interrupt_flags' argument will never cause `handler' to be - * called. This has the effect that any enabled ADC interrupts not - * specified in `interrupt_flags' will be ignored. - * - * This function additionally enables the ADC interrupts specified by - * `interrupt_flags'. - * - * @param dev ADC device whose interrupts to attach to. - * @param interrupt_flags Logical or of adc_interrupt_id values - * specifying interrupts to enable. - * @param handler Interrupt handler to call when any interrupt in - * interrupt_flags occurs. - * @param arg Value to store in .arg field of handler's callback data. - * @see enum adc_interrupt_id - * @see struct adc_callback_data - */ -extern void adc_attach_interrupt(const adc_dev *dev, uint32 interrupt_flags, - void (*handler)(adc_callback_data*), void *arg); - -/** - * @brief Disable ADC interrupts and detach interrupt handlers. - * - * This function disables all interrupts for `dev', and unsets any - * handler attached with adc_attach_interrupt(). - * - * @param dev ADC device whose handler to detach. - */ -extern void adc_detach_interrupt(const adc_dev *dev); - -/** - * @brief Enable ADC interrupts - * @param dev ADC device - * @param interrupt_flags Logical or of adc_interrupt_id values to enable. - * @see adc_disable_interrupt() - * @see adc_attach_interrupt() - */ -extern void adc_enable_interrupts(const adc_dev *dev, uint32 interrupt_flags); - -/** - * @brief Disable ADC interrupts. - * @param dev ADC device - * @param interrupt_flags Logical or of adc_interrupt_id values to disable. - * @brief adc_enable_interrupt() - */ -extern void adc_disable_interrupts(const adc_dev *dev, uint32 interrupt_flags); - -/** - * @brief Perform a single synchronous software triggered conversion on a - * channel. - * @param dev ADC device to use for reading. - * @param channel channel to convert - * @return conversion result - */ -extern uint16 adc_read(const adc_dev *dev, uint8 channel); - -/** - * @brief Set the ADC prescaler. - * - * This determines the ADC clock for all devices. - */ -extern void adc_set_prescaler(adc_prescaler pre); - -/** - * @brief Call a function on all ADC devices. - * @param fn Function to call on each ADC device. - */ -extern void adc_foreach(void (*fn)(const adc_dev*)); - -struct gpio_dev; -/** - * @brief Configure a GPIO pin for ADC conversion. - * @param dev ADC device to use for conversion (currently ignored on - * all targets). - * @param gdev GPIO device to configure. - * @param bit Bit on gdev to configure for ADC conversion. - */ -extern void adc_config_gpio(const struct adc_dev *dev, - struct gpio_dev *gdev, - uint8 bit); - -/** - * @brief Enable an ADC and configure it for single conversion mode. - * - * This function performs any initialization necessary to allow the - * ADC device to perform a single synchronous regular software - * triggered conversion, using adc_read(). - * - * @param dev Device to enable. - * @see adc_read() - */ -extern void adc_enable_single_swstart(const adc_dev* dev); - -/** - * @brief Set the regular channel sequence length. - * - * Defines the total number of conversions in the regular channel - * conversion sequence. - * - * @param dev ADC device. - * @param length Regular channel sequence length, from 1 to 16. - */ -extern void adc_set_reg_seqlen(const adc_dev *dev, uint8 length); - -/** - * @brief Enable an adc peripheral - * @param dev ADC device to enable - */ -extern void adc_enable(const adc_dev *dev); - -/** - * @brief Disable an ADC peripheral - * @param dev ADC device to disable - */ -extern void adc_disable(const adc_dev *dev); - -/** - * @brief Disable all ADC peripherals. - */ -static inline void adc_disable_all(void) { - adc_foreach(adc_disable); -} - -/* - * private - */ -extern void _adc_enable_dev_irq(const adc_dev *dev); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/bitband.h b/STM32F3/cores/maple/libmaple/include/libmaple/bitband.h deleted file mode 100644 index 6e77991bd..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/bitband.h +++ /dev/null @@ -1,128 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/bitband.h - * - * @brief Bit-banding utility functions - */ - -#ifndef _LIBMAPLE_BITBAND_H_ -#define _LIBMAPLE_BITBAND_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define BB_SRAM_REF 0x20000000 -#define BB_SRAM_BASE 0x22000000 -#define BB_PERI_REF 0x40000000 -#define BB_PERI_BASE 0x42000000 - -static inline volatile uint32* __bb_addr(volatile void*, - uint32, - uint32, - uint32); - -/** - * @brief Obtain a pointer to the bit-band address corresponding to a - * bit in a volatile SRAM address. - * @param address Address in the bit-banded SRAM region - * @param bit Bit in address to bit-band - */ -static inline volatile uint32* bb_sramp(volatile void *address, uint32 bit) { - return __bb_addr(address, bit, BB_SRAM_BASE, BB_SRAM_REF); -} - -/** - * @brief Get a bit from an address in the SRAM bit-band region. - * @param address Address in the SRAM bit-band region to read from - * @param bit Bit in address to read - * @return bit's value in address. - */ -static inline uint8 bb_sram_get_bit(volatile void *address, uint32 bit) { - return *bb_sramp(address, bit); -} - -/** - * @brief Set a bit in an address in the SRAM bit-band region. - * @param address Address in the SRAM bit-band region to write to - * @param bit Bit in address to write to - * @param val Value to write for bit, either 0 or 1. - */ -static inline void bb_sram_set_bit(volatile void *address, - uint32 bit, - uint8 val) { - *bb_sramp(address, bit) = val; -} - -/** - * @brief Obtain a pointer to the bit-band address corresponding to a - * bit in a peripheral address. - * @param address Address in the bit-banded peripheral region - * @param bit Bit in address to bit-band - */ -static inline volatile uint32* bb_perip(volatile void *address, uint32 bit) { - return __bb_addr(address, bit, BB_PERI_BASE, BB_PERI_REF); -} - -/** - * @brief Get a bit from an address in the peripheral bit-band region. - * @param address Address in the peripheral bit-band region to read from - * @param bit Bit in address to read - * @return bit's value in address. - */ -static inline uint8 bb_peri_get_bit(volatile void *address, uint32 bit) { - return *bb_perip(address, bit); -} - -/** - * @brief Set a bit in an address in the peripheral bit-band region. - * @param address Address in the peripheral bit-band region to write to - * @param bit Bit in address to write to - * @param val Value to write for bit, either 0 or 1. - */ -static inline void bb_peri_set_bit(volatile void *address, - uint32 bit, - uint8 val) { - *bb_perip(address, bit) = val; -} - -static inline volatile uint32* __bb_addr(volatile void *address, - uint32 bit, - uint32 bb_base, - uint32 bb_ref) { - return (volatile uint32*)(bb_base + ((uint32)address - bb_ref) * 32 + - bit * 4); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/bkp.h b/STM32F3/cores/maple/libmaple/include/libmaple/bkp.h deleted file mode 100644 index 7e795ddf2..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/bkp.h +++ /dev/null @@ -1,100 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/bkp.h - * @author F3-port by Hanspeter Portner - * @brief Backup register support (STM32F1 & STM32F3 only). - */ - -#ifndef _LIBMAPLE_BKP_H_ -#define _LIBMAPLE_BKP_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - -/** Backup peripheral device type. */ -typedef struct bkp_dev { - bkp_reg_map *regs; /**< Register map */ -} bkp_dev; - -extern const struct bkp_dev *BKP; - -/* - * this function needs to be implemented for each series separately - */ -extern inline __io uint32* bkp_data_register(uint8 reg); - -/** - * @brief Initialize backup interface. - * - * Enables the power and backup interface clocks, and resets the - * backup device. - */ -void bkp_init(void); - -/** - * Enable write access to the backup registers. Backup interface must - * be initialized for subsequent register writes to work. - * @see bkp_init() - */ -void bkp_enable_writes(void); - -/** - * Disable write access to the backup registers. - */ -void bkp_disable_writes(void); - -/** - * Read a value from given backup data register. - * @param reg Data register to read, from 1 to BKP_NR_DATA_REGS (10 on - * medium-density devices, 42 on high-density devices). - */ -uint16 bkp_read(uint8 reg); - -/** - * @brief Write a value to given data register. - * - * Write access to backup registers must be enabled. - * - * @param reg Data register to write, from 1 to BKP_NR_DATA_REGS (10 - * on medium-density devices, 42 on high-density devices). - * @param val Value to write into the register. - * @see bkp_enable_writes() - */ -void bkp_write(uint8 reg, uint16 val); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/comp.h b/STM32F3/cores/maple/libmaple/include/libmaple/comp.h deleted file mode 100644 index 508ba639c..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/comp.h +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file libmaple/include/libmaple/fpu.h - * @author F3-port by Hanspeter Portner - * @brief Floating Point Unit (COMP) interace. - */ - -#ifndef _LIBMAPLE_COMP_H_ -#define _LIBMAPLE_COMP_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/dac.h b/STM32F3/cores/maple/libmaple/include/libmaple/dac.h deleted file mode 100644 index 56bfdc480..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/dac.h +++ /dev/null @@ -1,158 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/dac.h - * @brief Digital to analog converter support. - */ - -/* See notes/dac.txt for more info */ - -#ifndef _LIBMAPLE_DAC_H_ -#define _LIBMAPLE_DAC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include -#include -#include - -/* - * Register map base and device pointers. - * - * The DACs are the same on all supported targets, so it's not worth - * repeating these in the series headers. - */ - -#define DAC_BASE ((struct dac_reg_map*)0x40007400) - -/** DAC device type. */ -typedef struct dac_dev { - dac_reg_map *regs; /**< Register map */ -} dac_dev; - -#if STM32_HAVE_DAC -extern const dac_dev *DAC; -#endif - -/* - * Register bit definitions - */ - -/* Control register */ - -/* Channel 1 control */ -#define DAC_CR_EN1 (1U << 0) /* Enable */ -#define DAC_CR_BOFF1 (1U << 1) /* Output buffer disable */ -#define DAC_CR_TEN1 (1U << 2) /* Trigger enable */ -#define DAC_CR_TSEL1 (0x7 << 3) /* Trigger selection */ -#define DAC_CR_WAVE1 (0x3 << 6) /* Noise/triangle wave */ -#define DAC_CR_MAMP1 (0xF << 8) /* Mask/amplitude selector */ -#define DAC_CR_DMAEN1 (1U << 12) /* DMA enable */ -/* Channel 2 control */ -#define DAC_CR_EN2 (1U << 16) /* Enable */ -#define DAC_CR_BOFF2 (1U << 17) /* Output buffer disable */ -#define DAC_CR_TEN2 (1U << 18) /* Trigger enable */ -#define DAC_CR_TSEL2 (0x7 << 19) /* Trigger selection */ -#define DAC_CR_WAVE2 (0x3 << 22) /* Noise/triangle wave */ -#define DAC_CR_MAMP2 (0xF << 24) /* Mask/amplitude selector */ -#define DAC_CR_DMAEN2 (1U << 28) /* DMA enable */ - -/* Software trigger register */ - -#define DAC_SWTRIGR_SWTRIG1 (1U << 0) /* Channel 1 software trigger */ -#define DAC_SWTRIGR_SWTRIG2 (1U << 1) /* Channel 2 software trigger */ - -/* Channel 1 12-bit right-aligned data holding register */ - -#define DAC_DHR12R1_DACC1DHR 0x00000FFF - -/* Channel 1 12-bit left-aligned data holding register */ - -#define DAC_DHR12L1_DACC1DHR 0x0000FFF0 - -/* Channel 1 8-bit left-aligned data holding register */ - -#define DAC_DHR8R1_DACC1DHR 0x000000FF - -/* Channel 2 12-bit right-aligned data holding register */ - -#define DAC_DHR12R2_DACC2DHR 0x00000FFF - -/* Channel 2 12-bit left-aligned data holding register */ - -#define DAC_DHR12L2_DACC2DHR 0x0000FFF0 - -/* Channel 2 8-bit left-aligned data holding register */ - -#define DAC_DHR8R2_DACC2DHR 0x000000FF - -/* Dual DAC 12-bit right-aligned data holding register */ - -#define DAC_DHR12RD_DACC1DHR 0x00000FFF -#define DAC_DHR12RD_DACC2DHR 0x0FFF0000 - -/* Dual DAC 12-bit left-aligned data holding register */ - -#define DAC_DHR12LD_DACC1DHR 0x0000FFF0 -#define DAC_DHR12LD_DACC2DHR 0xFFF00000 - -/* Dual DAC 8-bit left-aligned data holding register */ - -#define DAC_DHR8RD_DACC1DHR 0x000000FF -#define DAC_DHR8RD_DACC2DHR 0x0000FF00 - -/* Channel 1 data output register */ - -#define DAC_DOR1_DACC1DOR 0x00000FFF - -/* Channel 1 data output register */ - -#define DAC_DOR2_DACC2DOR 0x00000FFF - -/* - * Routines - */ - -/* We take the dev argument in these for future-proofing */ - -#define DAC_CH1 0x1 -#define DAC_CH2 0x2 -void dac_init(const dac_dev *dev, uint32 flags); - -void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val); -void dac_enable_channel(const dac_dev *dev, uint8 channel); -void dac_disable_channel(const dac_dev *dev, uint8 channel); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/dma.h b/STM32F3/cores/maple/libmaple/include/libmaple/dma.h deleted file mode 100644 index e22cdaf5a..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/dma.h +++ /dev/null @@ -1,444 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/dma.h - * - * @author Marti Bolivar ; - * Original implementation by Michael Hope - * - * @brief Direct Memory Access peripheral support - */ - -#ifndef _LIBMAPLE_DMA_H_ -#define _LIBMAPLE_DMA_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -/* provides: - * - * - An opaque dma_tube type, and predefined rvalues for each tube - * supported by the series. - * - * A "DMA tube" is a series-specific (hopefully integer) datatype - * that abstracts the conduit through which DMA-ed data flow. - * - * Examples: On STM32F1, dma_tube is just an alias for dma_channel, - * and the tube values are just DMA_CH1 (=1), DMA_CH2 (=2), etc. - * - * Note that a dma_tube doesn't have to be an enum, and its values - * don't have to be integral. They _do_ need to be cheap to pass as - * arguments, though. - * - * - struct dma_tube_reg_map (and typedef to dma_tube_reg_map). DMA - * register maps tend to be split into global registers and per-tube - * registers. It's convenient to pass around pointers to a tube's - * registers, since that makes it possible to configure or otherwise - * mess with a tube without knowing which one you're dealing with. - * - * - Base pointers to the various dma_tube_reg_maps. - * - * Examples: On STM32F1, these are DMAxCHy_BASE. You can access - * registers like DMAxCHy_BASE->CPAR, etc. - * - * - enum dma_request_src (and typedef to dma_request_src). This - * specifies the peripheral DMA request sources (e.g. USART TX DMA - * requests, etc.). - * - * - enum dma_mode_flags (and typedef to dma_mode_flags). Used in - * dma_tube_config. If two series both support the same mode flags, - * they must use the same enumerator names for those flags (the - * values of those enumerators are of course allowed to differ). - * - * - Normal stuff: dma_reg_map and base pointers, register bit - * definitions, dma_dev pointer declarations, and any other - * convenience functions useful for the series. */ -#include -/* buys us dma_dev and other necessities. */ -#include -#include - -/* - * Declarations/documentation for some of the series-provided types. - */ - -/** - * @brief (Series-dependent) DMA request sources. - * - * These specify the various pieces of peripheral functionality which - * may make DMA requests. Use them to set up a DMA transfer (see - * struct dma_tube_config, dma_tube_cfg()). - */ -enum dma_request_src; - -/** - * @brief (Series-dependent) DMA tube configuration flags. - * These specify miscellaneous bits of configuration for a DMA tube. - * @see struct dma_mode_config - */ -enum dma_cfg_flags; - -/** - * @brief (Series-dependent) DMA tube register map type. - * This allows you to access a tube's registers as a group. - * @see dma_tube_regs() - */ -struct dma_tube_reg_map; - -/* - * Convenience functions - */ - -/* Initialization */ - -void dma_init(dma_dev *dev); - -/* dma_tube configuration - * - * Use these types and functions to set up DMA transfers, handle - * interrupts, etc. The main function of interest is dma_tube_cfg(), - * which the various series implement separately. */ - -/** - * @brief Specifies a DMA tube configuration. - * - * Use one of these to set up a DMA transfer by passing it to - * dma_tube_cfg(). - * - * @see dma_tube_cfg() - * @see dma_xfer_size - */ -typedef struct dma_tube_config { - /** Source of data */ - __io void *tube_src; - /** Source transfer size */ - dma_xfer_size tube_src_size; - - /** Destination of data */ - __io void *tube_dst; - /** Destination transfer size */ - dma_xfer_size tube_dst_size; - - /** - * Number of data to transfer (0 to 65,535). - * - * Note that this is NOT measured in bytes; it's measured in - * number of data, which occur in multiples of tube_src_size. For - * example, if tube_src_size is DMA_SIZE_32BITS and tube_nr_xfers - * is 2, then 8 total bytes will be transferred. - */ - unsigned tube_nr_xfers; - - /** - * Target-specific configuration flags. - * - * These are an OR of series-specific enum dma_mode_flags values. - * Consult the documentation for your target for what flags you - * can use here. - * - * Typical flag examples: DMA_CFG_SRC_INC, DMA_CFG_DST_INC, - * DMA_CFG_CIRC, DMA_CFG_CMPLT_IE, etc. - */ - unsigned tube_flags; - - /** - * Currently unused. You must set this to 0 or something valid for - * your target. */ - void *target_data; - - /** - * Hardware DMA request source. - * - * This is ignored for memory-to-memory transfers. - */ - enum dma_request_src tube_req_src; -} dma_tube_config; - -#define DMA_TUBE_CFG_SUCCESS 0 -#define DMA_TUBE_CFG_EREQ 1 -#define DMA_TUBE_CFG_ENDATA 2 -#define DMA_TUBE_CFG_EDEV 3 -#define DMA_TUBE_CFG_ESRC 4 -#define DMA_TUBE_CFG_EDST 5 -#define DMA_TUBE_CFG_EDIR 6 -#define DMA_TUBE_CFG_ESIZE 7 -#define DMA_TUBE_CFG_ECFG 0xFF -/** - * @brief Configure a DMA tube. - * - * Use this function to set up a DMA transfer. The tube will be - * disabled before being reconfigured. The transfer will have low - * priority by default. You can choose another priority before the - * transfer begins using dma_set_priority(). You can manage your - * interrupt handlers for the tube using dma_attach_interrupt() and - * dma_detach_interrupt(). - * - * After calling dma_tube_cfg() and performing any other desired - * configuration, start the transfer using dma_enable(). - * - * @param dev DMA device. - * @param tube DMA tube to configure. - * @param cfg Configuration to apply to tube. - * - * @return DMA_TUBE_CFG_SUCCESS (0) on success, <0 on failure. On - * failure, returned value will be the opposite (-) of one of: - * - * - DMA_TUBE_CFG_EREQ: tube doesn't work with cfg->tube_req_src - * - DMA_TUBE_CFG_ENDATA: cfg->tube_[src,dst]_size are - * incompatible with cfg->tube_nr_xfers, or cfg->tube_nr_xfers - * is out of bounds. - * - DMA_TUBE_CFG_EDEV: dev does not support cfg - * - DMA_TUBE_CFG_ESRC: bad cfg->tube_src - * - DMA_TUBE_CFG_EDST: bad cfg->tube_dst - * - DMA_TUBE_CFG_EDIR: dev can't transfer from cfg->tube_src to - * cfg->tube_dst - * - DMA_TUBE_CFG_ESIZE: something ended up wrong due to MSIZE/PSIZE - * - DMA_TUBE_CFG_ECFG: generic "something's wrong" - * - * @sideeffect Disables tube. May alter tube's registers even when an - * error occurs. - * @see struct dma_tube_config - * @see dma_attach_interrupt() - * @see dma_detach_interrupt() - * @see dma_enable() - */ -extern int dma_tube_cfg(dma_dev *dev, dma_tube tube, dma_tube_config *cfg); - -/* Other tube configuration functions. You can use these if - * dma_tube_cfg() isn't enough, or to adjust parts of an existing tube - * configuration. */ - -/** DMA transfer priority. */ -typedef enum dma_priority { - DMA_PRIORITY_LOW = 0, /**< Low priority */ - DMA_PRIORITY_MEDIUM = 1, /**< Medium priority */ - DMA_PRIORITY_HIGH = 2, /**< High priority */ - DMA_PRIORITY_VERY_HIGH = 3, /**< Very high priority */ -} dma_priority; - -/** - * @brief Set the priority of a DMA transfer. - * - * You may not call this function while the tube is enabled. - * - * @param dev DMA device - * @param tube DMA tube - * @param priority priority to set. - */ -extern void dma_set_priority(dma_dev *dev, dma_tube tube, - dma_priority priority); - -/** - * @brief Set the number of data transfers on a DMA tube. - * - * You may not call this function while the tube is enabled. - * - * @param dev DMA device - * @param tube Tube through which the transfer will occur. - * @param num_transfers Number of DMA transactions to set. - */ -extern void dma_set_num_transfers(dma_dev *dev, dma_tube tube, - uint16 num_transfers); - -/** - * @brief Set the base memory address where data will be read from or - * written to. - * - * You must not call this function while the tube is enabled. - * - * If the DMA memory size is 16 bits, the address is automatically - * aligned to a half-word. If the DMA memory size is 32 bits, the - * address is aligned to a word. - * - * @param dev DMA Device - * @param tube Tube whose base memory address to set. - * @param address Memory base address to use. - */ -extern void dma_set_mem_addr(dma_dev *dev, dma_tube tube, __io void *address); - -/** - * @brief Set the base peripheral address where data will be read from - * or written to. - * - * You must not call this function while the channel is enabled. - * - * If the DMA peripheral size is 16 bits, the address is automatically - * aligned to a half-word. If the DMA peripheral size is 32 bits, the - * address is aligned to a word. - * - * @param dev DMA Device - * @param tube Tube whose peripheral data register base address to set. - * @param address Peripheral memory base address to use. - */ -extern void dma_set_per_addr(dma_dev *dev, dma_tube tube, __io void *address); - -/* Interrupt handling */ - -/** - * @brief Attach an interrupt to a DMA transfer. - * - * Interrupts are enabled using series-specific mode flags in - * dma_tube_cfg(). - * - * @param dev DMA device - * @param tube Tube to attach handler to - * @param handler Interrupt handler to call when tube interrupt fires. - * @see dma_tube_cfg() - * @see dma_get_irq_cause() - * @see dma_detach_interrupt() - */ -extern void dma_attach_interrupt(dma_dev *dev, dma_tube tube, - void (*handler)(void)); - - -/** - * @brief Detach a DMA transfer interrupt handler. - * - * After calling this function, the given tube's interrupts will be - * disabled. - * - * @param dev DMA device - * @param tube Tube whose handler to detach - * @sideeffect Clears the tube's interrupt enable bits. - * @see dma_attach_interrupt() - */ -extern void dma_detach_interrupt(dma_dev *dev, dma_tube tube); - -/* Tube enable/disable */ - -/** - * @brief Enable a DMA tube. - * - * If the tube has been properly configured, calling this function - * allows it to start serving DMA requests. - * - * @param dev DMA device - * @param tube Tube to enable - * @see dma_tube_cfg() - */ -extern void dma_enable(dma_dev *dev, dma_tube tube); - -/** - * @brief Disable a DMA channel. - * - * Calling this function makes the tube stop serving DMA requests. - * - * @param dev DMA device - * @param tube Tube to disable - */ -extern void dma_disable(dma_dev *dev, dma_tube tube); - -/** - * @brief Check if a DMA tube is enabled. - * @param dev DMA device. - * @param tube Tube to check. - * @return 0 if the tube is disabled, >0 if it is enabled. - */ -static inline uint8 dma_is_enabled(dma_dev *dev, dma_tube tube); - -/* Other conveniences */ - -/** - * @brief Obtain a pointer to an individual DMA tube's registers. - * - * Examples: - * - * - On STM32F1, dma_channel_regs(DMA1, DMA_CH1)->CCR is DMA1_BASE->CCR1. - * - * @param dev DMA device. - * @param tube DMA tube whose register map to obtain. - * @return (Series-specific) tube register map. - */ -static inline dma_tube_reg_map* dma_tube_regs(dma_dev *dev, dma_tube tube); - -/** - * Encodes the reason why a DMA interrupt was called. - * @see dma_get_irq_cause() - */ -typedef enum dma_irq_cause { - DMA_TRANSFER_COMPLETE, /**< Transfer is complete. */ - DMA_TRANSFER_HALF_COMPLETE, /**< Transfer is half complete. */ - DMA_TRANSFER_ERROR, /**< Error occurred during transfer. */ - DMA_TRANSFER_DME_ERROR, /**< - * @brief Direct mode error occurred during - * transfer. */ - DMA_TRANSFER_FIFO_ERROR, /**< FIFO error occurred during transfer. */ -} dma_irq_cause; - -/** - * @brief Discover the reason why a DMA interrupt was called. - * - * You may only call this function within an attached interrupt - * handler for the given channel. - * - * This function resets the internal DMA register state which encodes - * the cause of the interrupt; consequently, it can only be called - * once per interrupt handler invocation. - * - * @param dev DMA device - * @param tube Tube whose interrupt is being handled. - * @return Reason why the interrupt fired. - * @sideeffect Clears flags in dev's interrupt status registers. - * @see dma_attach_interrupt() - * @see dma_irq_cause - */ -extern dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_tube tube); - -/** - * @brief Get the ISR status bits for a DMA channel. - * - * The bits are returned right-aligned, in the order they appear in - * the corresponding ISR register. - * - * If you're trying to figure out why a DMA interrupt fired, you may - * find dma_get_irq_cause() more convenient. - * - * @param dev DMA device - * @param tube Tube whose ISR bits to return. - * @see dma_get_irq_cause(). - */ -static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_tube tube); - -/** - * @brief Clear the ISR status bits for a given DMA tube. - * - * If you're trying to clean up after yourself in a DMA interrupt, you - * may find dma_get_irq_cause() more convenient. - * - * @param dev DMA device - * @param tube Tube whose ISR bits to clear. - * @see dma_get_irq_cause() - */ -static inline void dma_clear_isr_bits(dma_dev *dev, dma_tube tube); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/dma_common.h b/STM32F3/cores/maple/libmaple/include/libmaple/dma_common.h deleted file mode 100644 index 3765cd577..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/dma_common.h +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/dma_common.h - * @author Marti Bolivar - * @brief Common DMA sub-header for and . - * - * CONTENTS UNSTABLE. The existence of this file is an implementation - * detail. Never include it directly. If you need something from - * here, include instead. - */ - -/* - * There's a fair amount of common DMA functionality needed by each - * and . This header exists in order - * to provide it to both, avoiding some hacks and circular - * dependencies. - */ - -#ifndef _LIBMAPLE_DMA_COMMON_H_ -#define _LIBMAPLE_DMA_COMMON_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include -#include - -/* - * Devices - */ - -struct dma_reg_map; - -/* Encapsulates state related to user interrupt handlers. You - * shouldn't touch these directly; use dma_attach_interrupt() and - * dma_detach_interupt() instead. */ -typedef struct dma_handler_config { - void (*handler)(void); /* User handler */ - nvic_irq_num irq_line; /* IRQ line for interrupt */ -} dma_handler_config; - -/** DMA device type */ -typedef struct dma_dev { - struct dma_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< Clock ID */ - struct dma_handler_config handlers[]; /**< For internal use */ -} dma_dev; - -/** - * @brief DMA channels - * - * Notes: - * - This is also the dma_tube type for STM32F1. - * - Channel 0 is not available on all STM32 series. - * - * @see dma_tube - */ -typedef enum dma_channel { - DMA_CH0 = 0, /**< Channel 0 */ - DMA_CH1 = 1, /**< Channel 1 */ - DMA_CH2 = 2, /**< Channel 2 */ - DMA_CH3 = 3, /**< Channel 3 */ - DMA_CH4 = 4, /**< Channel 4 */ - DMA_CH5 = 5, /**< Channel 5 */ - DMA_CH6 = 6, /**< Channel 6 */ - DMA_CH7 = 7, /**< Channel 7 */ -} dma_channel; - -/** - * @brief Source and destination transfer sizes. - * Use these when initializing a struct dma_tube_config. - * @see struct dma_tube_config - * @see dma_tube_cfg - */ -typedef enum dma_xfer_size { - DMA_SIZE_8BITS = 0, /**< 8-bit transfers */ - DMA_SIZE_16BITS = 1, /**< 16-bit transfers */ - DMA_SIZE_32BITS = 2, /**< 32-bit transfers */ -} dma_xfer_size; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/dsp.h b/STM32F3/cores/maple/libmaple/include/libmaple/dsp.h deleted file mode 100644 index 435c801ce..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/dsp.h +++ /dev/null @@ -1,131 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file libmaple/include/libmaple/dsp.h - * @author F3-port by Hanspeter Portner - * @brief Convenience macros for the digital signal processing (DSP) - * instruction set of the ARM Cortex M4 microcontroller. - */ - -#ifndef _LIBMAPLE_DSP_H_ -#define _LIBMAPLE_DSP_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#define DSP3(ID, A, B, C) \ -({ \ - uint32_t X; \ - asm volatile (ID" %[res], %[val1], %[val2], %[val3]" \ - : [res]"=r" (X) \ - : [val1]"r" (A), [val2]"r" (B), [val3]"r" (C) \ - ); \ - (uint32_t)X; \ -}) - -#define DSP2(ID, A, B) \ -({ \ - uint32_t X; \ - asm volatile (ID" %[res], %[val1], %[val2]" \ - : [res]"=r" (X) \ - : [val1]"r" (A), [val2]"r" (B) \ - );\ - (uint32_t)X; \ -}) - -#define DSP1(ID, A) \ -({ \ - uint32_t X; \ - asm volatile (ID" %[res], %[val1]" \ - : [res]"=r" (X) \ - : [val1]"r" (A) \ - ); \ - (uint32_t)X; \ -}) - -/* General data processing instructions */ -#define __rev16(A) DSP1("REV16", A) -//TODO - -/* Multiply and divide instructions */ -//TODO - -/* Saturating instructions */ -//TODO - -/* Packing and unpacking instructions */ -//TODO - -/* Bitfield instructions */ -//TODO - -/* Floating-point instructions */ -//TODO - -/* Miscellaneous instructions */ -//TODO - -/* SIMD instructions (single instruction multiple data) */ -#define __sadd16(A, B) DSP2("SADD16", A, B) -#define __shadd16(A, B) DSP2("SHADD16", A, B) -#define __ssub16(A, B) DSP2("SSUB16", A, B) -#define __shsub16(A, B) DSP2("SHSUB16", A, B) -#define __uadd16(A, B) DSP2("UADD16", A, B) -#define __uhadd16(A, B) DSP2("UHADD16", A, B) -#define __usub16(A, B) DSP2("USUB16", A, B) -#define __uhsub16(A, B) DSP2("UHSUB16", A, B) - -#define __sadd8(A, B) DSP2("SADD8", A, B) -#define __shadd8(A, B) DSP2("SHADD8", A, B) -#define __ssub8(A, B) DSP2("SSUB8", A, B) -#define __shsub8(A, B) DSP2("SHSUB8", A, B) -#define __uadd8(A, B) DSP2("UADD8", A, B) -#define __uhadd8(A, B) DSP2("UHADD8", A, B) -#define __usub8(A, B) DSP2("USUB8", A, B) -#define __uhsub8(A, B) DSP2("UHSUB8", A, B) - -#define __sasx(A, B) DSP2("SASX", A, B) -#define __ssax(A, B) DSP2("SSAX", A, B) -#define __shasx(A, B) DSP2("SHASX", A, B) -#define __shsax(A, B) DSP2("SHSAX", A, B) -#define __uasx(A, B) DSP2("UASX", A, B) -#define __usax(A, B) DSP2("USAX", A, B) -#define __uhasx(A, B) DSP2("UHASX", A, B) -#define __uhsax(A, B) DSP2("UHSAX", A, B) - -#define __usad8(A, B) DSP2("USAD8", A, B) -#define __usada8(A, B, C) DSP3("USADA8", A, B, C) - -/* MAC instructions (multiply and accumulate) */ -/* TODO */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/exti.h b/STM32F3/cores/maple/libmaple/include/libmaple/exti.h deleted file mode 100644 index 1d201ac34..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/exti.h +++ /dev/null @@ -1,143 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/exti.h - * @brief External interrupt control - */ - -/* See notes/exti.txt for more info */ - -#ifndef _LIBMAPLE_EXTI_H_ -#define _LIBMAPLE_EXTI_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include /* provides EXTI_BASE */ -#include - -/* - * Register map and base pointer. - */ - -/** EXTI register map type */ -typedef struct exti_reg_map { - __io uint32 IMR; /**< Interrupt mask register */ - __io uint32 EMR; /**< Event mask register */ - __io uint32 RTSR; /**< Rising trigger selection register */ - __io uint32 FTSR; /**< Falling trigger selection register */ - __io uint32 SWIER; /**< Software interrupt event register */ - __io uint32 PR; /**< Pending register */ -} exti_reg_map; - -/* - * Types: exti_num, exti_cfg, exti_trigger_mode. - * - * A combination of these three specifies an external interrupt - * configuration (see exti_attach_interrupt()). - */ - -/** EXTI line. */ -typedef enum exti_num { - EXTI0, /**< EXTI line 0 */ - EXTI1, /**< EXTI line 1 */ - EXTI2, /**< EXTI line 2 */ - EXTI3, /**< EXTI line 3 */ - EXTI4, /**< EXTI line 4 */ - EXTI5, /**< EXTI line 5 */ - EXTI6, /**< EXTI line 6 */ - EXTI7, /**< EXTI line 7 */ - EXTI8, /**< EXTI line 8 */ - EXTI9, /**< EXTI line 9 */ - EXTI10, /**< EXTI line 10 */ - EXTI11, /**< EXTI line 11 */ - EXTI12, /**< EXTI line 12 */ - EXTI13, /**< EXTI line 13 */ - EXTI14, /**< EXTI line 14 */ - EXTI15, /**< EXTI line 15 */ -} exti_num; - -/** - * @brief EXTI port configuration - * - * These specify which GPIO port an external interrupt line should be - * connected to. - */ -typedef enum exti_cfg { - EXTI_PA, /**< Use PAx pin */ - EXTI_PB, /**< Use PBx pin */ - EXTI_PC, /**< Use PCx pin */ - EXTI_PD, /**< Use PDx pin */ - EXTI_PE, /**< Use PEx pin */ - EXTI_PF, /**< Use PFx pin */ - EXTI_PG, /**< Use PGx pin */ - EXTI_PH, /**< Use PHx pin */ - EXTI_PI, /**< Use PIx pin */ -} exti_cfg; - -/** External interrupt trigger mode */ -typedef enum exti_trigger_mode { - EXTI_RISING, /**< Trigger on the rising edge */ - EXTI_FALLING, /**< Trigger on the falling edge */ - EXTI_RISING_FALLING /**< Trigger on both the rising and falling edges */ -} exti_trigger_mode; - -/* - * Routines - */ - -void exti_attach_interrupt(exti_num num, - exti_cfg port, - voidFuncPtr handler, - exti_trigger_mode mode); -void exti_attach_callback(exti_num num, - exti_cfg port, - voidArgumentFuncPtr handler, - void *arg, - exti_trigger_mode mode); -void exti_detach_interrupt(exti_num num); - -/** - * @brief Set the GPIO port for an EXTI line. - * - * This is a low-level routine that most users will not - * need. exti_attach_interrupt() handles calling this function - * appropriately. - * - * @param num EXTI line - * @param port EXTI configuration for GPIO port to connect to num. - * @see exti_num - * @see exti_cfg - */ -extern void exti_select(exti_num num, exti_cfg port); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/flash.h b/STM32F3/cores/maple/libmaple/include/libmaple/flash.h deleted file mode 100644 index 943e46641..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/flash.h +++ /dev/null @@ -1,106 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/flash.h - * @brief Flash support. - */ - -#ifndef _LIBMAPLE_FLASH_H_ -#define _LIBMAPLE_FLASH_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -#define FLASH_WAIT_STATE_0 0x0 -#define FLASH_WAIT_STATE_1 0x1 -#define FLASH_WAIT_STATE_2 0x2 -#define FLASH_WAIT_STATE_3 0x3 -#define FLASH_WAIT_STATE_4 0x4 -#define FLASH_WAIT_STATE_5 0x5 -#define FLASH_WAIT_STATE_6 0x6 -#define FLASH_WAIT_STATE_7 0x7 - -/* The series header must define: - * - * - FLASH_SAFE_WAIT_STATES, the smallest number of wait states that - * it is safe to use when SYSCLK is at its fastest documented rate - * and the MCU is powered at 3.3V (i.e. this doesn't consider - * overclocking or low voltage operation). - * - * - The following bit flags, for flash_enable_features(): - * - * -- FLASH_PREFETCH: prefetcher - * -- FLASH_ICACHE: instruction cache - * -- FLASH_DCACHE: data cache - * - * See that function's Doxygen for more restrictions. - */ -#include - -#ifdef __DOXYGEN__ -/** Flash register map base pointer. */ -#define FLASH_BASE -#endif - -/* - * Flash routines - */ - -void flash_set_latency(uint32 wait_states); - -/** - * @brief Enable Flash memory features - * - * If the target MCU doesn't provide a feature (e.g. instruction and - * data caches on the STM32F1), the flag will be ignored. This allows - * using these flags unconditionally, with the desired effect taking - * place on targets that support them. - * - * @param feature_flags Bitwise OR of the following: - * FLASH_PREFETCH (turns on prefetcher), - * FLASH_ICACHE (turns on instruction cache), - * FLASH_DCACHE (turns on data cache). - */ -static inline void flash_enable_features(uint32 feature_flags) { - FLASH_BASE->ACR |= feature_flags; -} - -/** - * @brief Deprecated. Use flash_enable_features(FLASH_PREFETCH) instead. - */ -static inline void flash_enable_prefetch(void) { - flash_enable_features(FLASH_PREFETCH); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/fpu.h b/STM32F3/cores/maple/libmaple/include/libmaple/fpu.h deleted file mode 100644 index f8e2037d5..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/fpu.h +++ /dev/null @@ -1,56 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file libmaple/include/libmaple/fpu.h - * @author F3-port by Hanspeter Portner - * @brief Floating Point Unit (FPU) interace. - */ - -#ifndef _LIBMAPLE_FPU_H_ -#define _LIBMAPLE_FPU_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -/** - * @brief Enable floating point unit. - */ -void fpu_enable(void); - -/** - * @brief Disable floating point unit. - */ -void fpu_disable(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/fsmc.h b/STM32F3/cores/maple/libmaple/include/libmaple/fsmc.h deleted file mode 100644 index 6225feedc..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/fsmc.h +++ /dev/null @@ -1,340 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/fsmc.h - * @brief Flexible static memory controller support. - */ - -/* - * See ../notes/fsmc.txt for more info - */ - -#ifndef _LIBMAPLE_FSMC_H_ -#define _LIBMAPLE_FSMC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include - -#if !STM32_HAVE_FSMC -#error "FSMC is unavailable on your MCU" -#endif - -/* - * Register maps and devices - */ - -/** FSMC register map type */ -typedef struct fsmc_reg_map { - __io uint32 BCR1; /**< SRAM/NOR-Flash chip-select control register 1 */ - __io uint32 BTR1; /**< SRAM/NOR-Flash chip-select timing register 1 */ - __io uint32 BCR2; /**< SRAM/NOR-Flash chip-select control register 2 */ - __io uint32 BTR2; /**< SRAM/NOR-Flash chip-select timing register 2 */ - __io uint32 BCR3; /**< SRAM/NOR-Flash chip-select control register 3 */ - __io uint32 BTR3; /**< SRAM/NOR-Flash chip-select timing register 3 */ - __io uint32 BCR4; /**< SRAM/NOR-Flash chip-select control register 4 */ - __io uint32 BTR4; /**< SRAM/NOR-Flash chip-select timing register 4 */ - const uint8 RESERVED1[64]; /**< Reserved */ - __io uint32 PCR2; /**< PC Card/NAND Flash control register 2 */ - __io uint32 SR2; /**< FIFO status and interrupt register 2 */ - __io uint32 PMEM2; /**< Common memory space timing register 2 */ - __io uint32 PATT2; /**< Attribute memory space timing register 2 */ - const uint8 RESERVED2[4]; /**< Reserved */ - __io uint32 ECCR2; /**< ECC result register 2 */ - const uint8 RESERVED3[2]; - __io uint32 PCR3; /**< PC Card/NAND Flash control register 3 */ - __io uint32 SR3; /**< FIFO status and interrupt register 3 */ - __io uint32 PMEM3; /**< Common memory space timing register 3 */ - __io uint32 PATT3; /**< Attribute memory space timing register 3 */ - const uint32 RESERVED4; /**< Reserved */ - __io uint32 ECCR3; /**< ECC result register 3 */ - const uint8 RESERVED5[8]; /**< Reserved */ - __io uint32 PCR4; /**< PC Card/NAND Flash control register 4 */ - __io uint32 SR4; /**< FIFO status and interrupt register 4 */ - __io uint32 PMEM4; /**< Common memory space timing register 4 */ - __io uint32 PATT4; /**< Attribute memory space timing register 4 */ - __io uint32 PIO4; /**< I/O space timing register 4 */ - const uint8 RESERVED6[80]; /**< Reserved */ - __io uint32 BWTR1; /**< SRAM/NOR-Flash write timing register 1 */ - const uint32 RESERVED7; /**< Reserved */ - __io uint32 BWTR2; /**< SRAM/NOR-Flash write timing register 2 */ - const uint32 RESERVED8; /**< Reserved */ - __io uint32 BWTR3; /**< SRAM/NOR-Flash write timing register 3 */ - const uint32 RESERVED9; /**< Reserved */ - __io uint32 BWTR4; /**< SRAM/NOR-Flash write timing register 4 */ -} __attribute__((packed)) fsmc_reg_map; - -#define __FSMCB 0xA0000000 - -/** FSMC register map base pointer */ -#define FSMC_BASE ((struct fsmc_reg_map*)__FSMCB) - -/** FSMC NOR/PSRAM register map type */ -typedef struct fsmc_nor_psram_reg_map { - __io uint32 BCR; /**< Chip-select control register */ - __io uint32 BTR; /**< Chip-select timing register */ - const uint8 RESERVED[252]; /**< Reserved */ - __io uint32 BWTR; /**< Write timing register */ -} fsmc_nor_psram_reg_map; - -/** FSMC NOR/PSRAM base pointer 1 */ -#define FSMC_NOR_PSRAM1_BASE ((struct fsmc_nor_psram_reg_map*)__FSMCB) - -/** FSMC NOR/PSRAM base pointer 2 */ -#define FSMC_NOR_PSRAM2_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x8)) - -/** FSMC NOR/PSRAM base pointer 3 */ -#define FSMC_NOR_PSRAM3_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x10)) - -/** FSMC NOR/PSRAM base pointer 4 */ -#define FSMC_NOR_PSRAM4_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x18)) - -/* - * Register bit definitions - */ - -/* NOR/PSRAM chip-select control registers */ - -#define FSMC_BCR_CBURSTRW_BIT 19 -#define FSMC_BCR_ASYNCWAIT_BIT 15 -#define FSMC_BCR_EXTMOD_BIT 14 -#define FSMC_BCR_WAITEN_BIT 13 -#define FSMC_BCR_WREN_BIT 12 -#define FSMC_BCR_WAITCFG_BIT 11 -#define FSMC_BCR_WRAPMOD_BIT 10 -#define FSMC_BCR_WAITPOL_BIT 9 -#define FSMC_BCR_BURSTEN_BIT 8 -#define FSMC_BCR_FACCEN_BIT 6 -#define FSMC_BCR_MUXEN_BIT 1 -#define FSMC_BCR_MBKEN_BIT 0 - -#define FSMC_BCR_CBURSTRW (1U << FSMC_BCR_CBURSTRW_BIT) -#define FSMC_BCR_ASYNCWAIT (1U << FSMC_BCR_ASYNCWAIT_BIT) -#define FSMC_BCR_EXTMOD (1U << FSMC_BCR_EXTMOD_BIT) -#define FSMC_BCR_WAITEN (1U << FSMC_BCR_WAITEN_BIT) -#define FSMC_BCR_WREN (1U << FSMC_BCR_WREN_BIT) -#define FSMC_BCR_WAITCFG (1U << FSMC_BCR_WAITCFG_BIT) -#define FSMC_BCR_WRAPMOD (1U << FSMC_BCR_WRAPMOD_BIT) -#define FSMC_BCR_WAITPOL (1U << FSMC_BCR_WAITPOL_BIT) -#define FSMC_BCR_BURSTEN (1U << FSMC_BCR_BURSTEN_BIT) -#define FSMC_BCR_FACCEN (1U << FSMC_BCR_FACCEN_BIT) -#define FSMC_BCR_MWID (0x3 << 4) -#define FSMC_BCR_MWID_8BITS (0x0 << 4) -#define FSMC_BCR_MWID_16BITS (0x1 << 4) -#define FSMC_BCR_MTYP (0x3 << 2) -#define FSMC_BCR_MTYP_SRAM (0x0 << 2) -#define FSMC_BCR_MTYP_PSRAM (0x1 << 2) -#define FSMC_BCR_MTYP_NOR_FLASH (0x2 << 2) -#define FSMC_BCR_MUXEN (1U << FSMC_BCR_MUXEN_BIT) -#define FSMC_BCR_MBKEN (1U << FSMC_BCR_MBKEN_BIT) - -/* SRAM/NOR-Flash chip-select timing registers */ - -#define FSMC_BTR_ACCMOD (0x3 << 28) -#define FSMC_BTR_ACCMOD_A (0x0 << 28) -#define FSMC_BTR_ACCMOD_B (0x1 << 28) -#define FSMC_BTR_ACCMOD_C (0x2 << 28) -#define FSMC_BTR_ACCMOD_D (0x3 << 28) -#define FSMC_BTR_DATLAT (0xF << 24) -#define FSMC_BTR_CLKDIV (0xF << 20) -#define FSMC_BTR_BUSTURN (0xF << 16) -#define FSMC_BTR_DATAST (0xFF << 8) -#define FSMC_BTR_ADDHLD (0xF << 4) -#define FSMC_BTR_ADDSET 0xF - -/* SRAM/NOR-Flash write timing registers */ - -#define FSMC_BWTR_ACCMOD (0x3 << 28) -#define FSMC_BWTR_ACCMOD_A (0x0 << 28) -#define FSMC_BWTR_ACCMOD_B (0x1 << 28) -#define FSMC_BWTR_ACCMOD_C (0x2 << 28) -#define FSMC_BWTR_ACCMOD_D (0x3 << 28) -#define FSMC_BWTR_DATLAT (0xF << 24) -#define FSMC_BWTR_CLKDIV (0xF << 20) -#define FSMC_BWTR_DATAST (0xFF << 8) -#define FSMC_BWTR_ADDHLD (0xF << 4) -#define FSMC_BWTR_ADDSET 0xF - -/* NAND Flash/PC Card controller registers */ - -#define FSMC_PCR_ECCEN_BIT 6 -#define FSMC_PCR_PTYP_BIT 3 -#define FSMC_PCR_PBKEN_BIT 2 -#define FSMC_PCR_PWAITEN_BIT 1 - -#define FSMC_PCR_ECCPS (0x7 << 17) -#define FSMC_PCR_ECCPS_256B (0x0 << 17) -#define FSMC_PCR_ECCPS_512B (0x1 << 17) -#define FSMC_PCR_ECCPS_1024B (0x2 << 17) -#define FSMC_PCR_ECCPS_2048B (0x3 << 17) -#define FSMC_PCR_ECCPS_4096B (0x4 << 17) -#define FSMC_PCR_ECCPS_8192B (0x5 << 17) -#define FSMC_PCR_TAR (0xF << 13) -#define FSMC_PCR_TCLR (0xF << 9) -#define FSMC_PCR_ECCEN (1U << FSMC_PCR_ECCEN_BIT) -#define FSMC_PCR_PWID (0x3 << 4) -#define FSMC_PCR_PWID_8BITS (0x0 << 4) -#define FSMC_PCR_PWID_16BITS (0x1 << 4) -#define FSMC_PCR_PTYP (1U << FSMC_PCR_PTYP_BIT) -#define FSMC_PCR_PTYP_PC_CF_PCMCIA (0x0 << FSMC_PCR_PTYP_BIT) -#define FSMC_PCR_PTYP_NAND (0x1 << FSMC_PCR_PTYP_BIT) -#define FSMC_PCR_PBKEN (1U << FSMC_PCR_PBKEN_BIT) -#define FSMC_PCR_PWAITEN (1U << FSMC_PCR_PWAITEN_BIT) - -/* FIFO status and interrupt registers */ - -#define FSMC_SR_FEMPT_BIT 6 -#define FSMC_SR_IFEN_BIT 5 -#define FSMC_SR_ILEN_BIT 4 -#define FSMC_SR_IREN_BIT 3 -#define FSMC_SR_IFS_BIT 2 -#define FSMC_SR_ILS_BIT 1 -#define FSMC_SR_IRS_BIT 0 - -#define FSMC_SR_FEMPT (1U << FSMC_SR_FEMPT_BIT) -#define FSMC_SR_IFEN (1U << FSMC_SR_IFEN_BIT) -#define FSMC_SR_ILEN (1U << FSMC_SR_ILEN_BIT) -#define FSMC_SR_IREN (1U << FSMC_SR_IREN_BIT) -#define FSMC_SR_IFS (1U << FSMC_SR_IFS_BIT) -#define FSMC_SR_ILS (1U << FSMC_SR_ILS_BIT) -#define FSMC_SR_IRS (1U << FSMC_SR_IRS_BIT) - -/* Common memory space timing registers */ - -#define FSMC_PMEM_MEMHIZ (0xFF << 24) -#define FSMC_PMEM_MEMHOLD (0xFF << 16) -#define FSMC_PMEM_MEMWAIT (0xFF << 8) -#define FSMC_PMEM_MEMSET 0xFF - -/* Attribute memory space timing registers */ - -#define FSMC_PATT_ATTHIZ (0xFF << 24) -#define FSMC_PATT_ATTHOLD (0xFF << 16) -#define FSMC_PATT_ATTWAIT (0xFF << 8) -#define FSMC_PATT_ATTSET 0xFF - -/* I/O space timing register 4 */ - -#define FSMC_PIO_IOHIZ (0xFF << 24) -#define FSMC_PIO_IOHOLD (0xFF << 16) -#define FSMC_PIO_IOWAIT (0xFF << 8) -#define FSMC_PIO_IOSET 0xFF - -/* - * Memory bank boundary addresses - */ - -/** - * @brief Void pointer to base address of FSMC memory bank 1 (NOR/PSRAM). - * - * This bank is split into 4 regions. Each region supports interfacing - * with 1 NOR Flash, SRAM, or PSRAM chip. The base addresses of these - * regions are FSMC_NOR_PSRAM_REGIONx, for x = 1, 2, 3, 4. - */ -#define FSMC_BANK1 ((void*)0x60000000) - -/** - * @brief Void pointer to base address of FSMC memory bank 1, region 1 - * (NOR/PSRAM). - */ -#define FSMC_NOR_PSRAM_REGION1 FSMC_BANK1 - -/** - * @brief Void pointer to base address of FSMC memory bank 1, region 2 - * (NOR/PSRAM). - */ -#define FSMC_NOR_PSRAM_REGION2 ((void*)0x64000000) - -/** - * @brief Void pointer to base address of FSMC memory bank 1, region 3 - * (NOR/PSRAM). - */ -#define FSMC_NOR_PSRAM_REGION3 ((void*)0x68000000) - -/** - * @brief Void pointer to base address of FSMC memory bank 1, region 4 - * (NOR/PSRAM). - */ -#define FSMC_NOR_PSRAM_REGION4 ((void*)0x6C000000) - -/** Void pointer to base address of FSMC memory bank 2 (NAND Flash). */ -#define FSMC_BANK2 ((void*)0x70000000) - -/** Void pointer to base address of FSMC memory bank 3 (NAND Flash). */ -#define FSMC_BANK3 ((void*)0x80000000) - -/** - * @brief Void pointer to base address of FSMC memory bank 4 (PC card - * devices). - */ -#define FSMC_BANK4 ((void*)0x90000000) - -/* - * SRAM/NOR Flash routines - */ - -/** - * @brief Configure FSMC GPIOs for use with SRAM. - */ -void fsmc_sram_init_gpios(void); - -/** - * Set the DATAST bits in the given NOR/PSRAM register map's - * chip-select timing register (FSMC_BTR). - * - * @param regs NOR Flash/PSRAM register map whose chip-select timing - * register to set. - * @param datast Value to use for DATAST bits. - */ -static inline void fsmc_nor_psram_set_datast(fsmc_nor_psram_reg_map *regs, - uint8 datast) { - regs->BTR &= ~FSMC_BTR_DATAST; - regs->BTR |= datast << 8; -} - -/** - * Set the ADDHLD bits in the given NOR/PSRAM register map's chip - * select timing register (FSMC_BTRx). - * - * @param regs NOR Flash/PSRAM register map whose chip-select timing - * register to set. - * @param addset Value to use for ADDSET bits. - */ -static inline void fsmc_nor_psram_set_addset(fsmc_nor_psram_reg_map *regs, - uint8 addset) { - regs->BTR &= ~FSMC_BTR_ADDSET; - regs->BTR |= addset & 0xF; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/gpio.h b/STM32F3/cores/maple/libmaple/include/libmaple/gpio.h deleted file mode 100644 index 0cc374611..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/gpio.h +++ /dev/null @@ -1,121 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file libmaple/include/libmaple/gpio.h - * @brief General Purpose I/O (GPIO) interace. - */ - -#ifndef _LIBMAPLE_GPIO_H_ -#define _LIBMAPLE_GPIO_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - * Note: Series header must define: - * - enum gpio_pin_mode (TODO think harder about portability here) - */ -#include -#include -#include -#include - -/* - * Device type - */ - -/** GPIO device type */ -typedef struct gpio_dev { - gpio_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ - /** - * @brief (Deprecated) External interrupt port. - * Instead of dev->exti_port, use gpio_exti_port(dev). - */ - exti_cfg exti_port; -} gpio_dev; - -/* - * Portable routines - */ - -void gpio_init(gpio_dev *dev); -void gpio_init_all(void); -/* TODO flags argument version? */ -void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode); - -/** - * @brief Get a GPIO port's corresponding EXTI port configuration. - * @param dev GPIO port whose exti_cfg to return. - */ -static inline exti_cfg gpio_exti_port(gpio_dev *dev) { - return (exti_cfg)(EXTI_PA + (dev->clk_id - RCC_GPIOA)); -} - -/** - * Set or reset a GPIO pin. - * - * Pin must have previously been configured to output mode. - * - * @param dev GPIO device whose pin to set. - * @param pin Pin on to set or reset - * @param val If true, set the pin. If false, reset the pin. - */ -static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) { - val = !val; /* "set" bits are lower than "reset" bits */ - dev->regs->BSRR = (1U << pin) << (16 * val); -} - -/** - * Determine whether or not a GPIO pin is set. - * - * Pin must have previously been configured to input mode. - * - * @param dev GPIO device whose pin to test. - * @param pin Pin on dev to test. - * @return True if the pin is set, false otherwise. - */ -static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) { - return dev->regs->IDR & (1U << pin); -} - -/** - * Toggle a pin configured as output push-pull. - * @param dev GPIO device. - * @param pin Pin on dev to toggle. - */ -static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) { - dev->regs->ODR = dev->regs->ODR ^ (1U << pin); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/i2c.h b/STM32F3/cores/maple/libmaple/include/libmaple/i2c.h deleted file mode 100644 index 8452c2a27..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/i2c.h +++ /dev/null @@ -1,304 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/i2c.h - * @author F3-port by Hanspeter Portner - * @brief Inter-Integrated Circuit (I2C) peripheral support - * - * Currently master-only. Usage notes: - * - * - Enable an I2C device with i2c_master_enable(). - * - Initialize an array of struct i2c_msg to suit the bus - * transactions (reads/writes) you wish to perform. - * - Call i2c_master_xfer() to do the work. - */ - -#ifndef _LIBMAPLE_I2C_H_ -#define _LIBMAPLE_I2C_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Series header must provide: - * - * - uint32 _i2c_bus_clk(i2c_dev*): Clock frequency of dev's bus, in - * MHz. (This is for internal use only). - * - * - (optional) _I2C_HAVE_IRQ_FIXUP: Leave undefined, or define to 1. - * This is for internal use only. It's a hack to work around a - * silicon bug related to I2C IRQ pre-emption on some targets. If 1, - * the series header must also declare and implement a routine with - * this signature (it may also be provided as a macro): - * - * void _i2c_irq_priority_fixup(i2c_dev*) - * - * This will be called by i2c_enable_irq() before actually enabling - * I2C interrupts. - * - * - Reg. map base pointers, device pointer declarations. - */ - -#include -#include - -#include -#include -#include -#include - -/** - * @brief I2C message type - */ -typedef struct i2c_msg { - uint16 addr; /**< Address */ - -#define I2C_MSG_READ 0x1 -#define I2C_MSG_10BIT_ADDR 0x2 - /** - * Bitwise OR of: - * - I2C_MSG_READ (write is default) - * - I2C_MSG_10BIT_ADDR (7-bit is default) */ - uint16 flags; - - uint16 length; /**< Message length */ - uint16 xferred; /**< Messages transferred */ - uint8 *data; /**< Data */ -} i2c_msg; - -/* I2C enable options */ -#define I2C_FAST_MODE 0x1 // 400 khz -#define I2C_DUTY_16_9 0x2 // 16/9 duty ratio -/* Flag 0x4 is reserved; DO NOT USE. */ -#define I2C_BUS_RESET 0x8 // Perform a bus reset - -/* I2C error flags */ -#define I2C_ERROR_PROTOCOL (-1) -#define I2C_ERROR_TIMEOUT (-2) - -/* Main I2C API */ - -/** - * @brief Disable an I2C device - * - * This function disables the corresponding peripheral and marks dev's - * state as I2C_STATE_DISABLED. - * - * @param dev Device to disable. - */ -static inline void i2c_disable(i2c_dev *dev) { - dev->regs->CR1 &= ~I2C_CR1_PE; - dev->state = I2C_STATE_DISABLED; -} - -/** - * @brief Wait for an I2C event, or time out in case of error. - * @param dev I2C device - * @param state I2C_state state to wait for - * @param timeout Timeout, in milliseconds - * @return 0 if target state is reached, a negative value on error. - */ -extern int32 wait_for_state_change(i2c_dev *dev, - i2c_state state, - uint32 timeout); - -/** - * @brief Reset an I2C bus. - * - * Reset is accomplished by clocking out pulses until any hung slaves - * release SDA and SCL, then generating a START condition, then a STOP - * condition. - * - * @param dev I2C device - */ -extern void i2c_bus_reset(const i2c_dev *dev); - -/** - * @brief Initialize an I2C device as bus master - * @param dev Device to enable - * @param flags Bitwise or of the following I2C options: - * I2C_FAST_MODE: 400 khz operation, - * I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for - * fast mode), - * I2C_BUS_RESET: Reset the bus and clock out any hung slaves on - * initialization, - * I2C_10BIT_ADDRESSING: Enable 10-bit addressing, - * I2C_REMAP: (deprecated, STM32F1 only) Remap I2C1 to SCL/PB8 - * SDA/PB9. - */ -extern void i2c_master_enable(i2c_dev *dev, uint32 flags); - -/** - * @brief Process an i2c transaction. - * - * Transactions are composed of one or more i2c_msg's, and may be read - * or write tranfers. Multiple i2c_msg's will generate a repeated - * start in between messages. - * - * @param dev I2C device - * @param msgs Messages to send/receive - * @param num Number of messages to send/receive - * @param timeout Bus idle timeout in milliseconds before aborting the - * transfer. 0 denotes no timeout. - * @return 0 on success, - * I2C_ERROR_PROTOCOL if there was a protocol error, - * I2C_ERROR_TIMEOUT if the transfer timed out. - */ -extern int32 i2c_master_xfer(i2c_dev *dev, - i2c_msg *msgs, - uint16 num, - uint32 timeout); - -/** - * @brief Fill data register with slave address - * @param dev I2C device - * @param addr Slave address - * @param rw Read/write bit - */ -extern void i2c_send_slave_addr(i2c_dev *dev, uint32 addr, uint32 rw); - -/* Start/stop conditions */ - -/** - * @brief Generate a start condition on the bus. - * @param dev I2C device - */ -extern void i2c_start_condition(i2c_dev *dev); - -/** - * @brief Generate a stop condition on the bus - * @param dev I2C device - */ -extern void i2c_stop_condition(i2c_dev *dev); - -/* IRQ enable/disable */ - -#ifndef _I2C_HAVE_IRQ_FIXUP -/* The series header provides this if _I2C_HAVE_IRQ_FIXUP is defined, - * but we need it either way. */ -#define _i2c_irq_priority_fixup(dev) ((void)0) -#endif - -/** - * @brief Enable one or more I2C interrupts - * @param dev I2C device - * @param irqs Bitwise or of: - * I2C_IRQ_ERROR (error interrupt), - * I2C_IRQ_EVENT (event interrupt), and - * I2C_IRQ_BUFFER (buffer interrupt). - */ -extern void i2c_enable_irq(i2c_dev *dev, uint32 irqs); - -/** - * @brief Disable one or more I2C interrupts - * @param dev I2C device - * @param irqs Bitwise or of: - * I2C_IRQ_ERROR (error interrupt), - * I2C_IRQ_EVENT (event interrupt), and - * I2C_IRQ_BUFFER (buffer interrupt). - */ -extern void i2c_disable_irq(i2c_dev *dev, uint32 irqs); - -/* ACK/NACK */ - -/** - * @brief Enable I2C acknowledgment - * @param dev I2C device - */ -extern void i2c_enable_ack(i2c_dev *dev); - -/** - * @brief Disable I2C acknowledgment - * @param dev I2C device - */ -extern void i2c_disable_ack(i2c_dev *dev); - -/* GPIO control */ - -/** - * @brief Configure device GPIOs. - * - * Configure GPIO bits dev->sda_pin and dev->scl_pin on GPIO device - * dev->gpio_port for use with I2C device dev. - * - * @param dev I2C Device - * @see i2c_release_gpios() - */ -extern void i2c_config_gpios(const i2c_dev *dev); - -/** - * @brief Release GPIOs controlling an I2C bus - * - * Releases the I2C bus controlled by dev as master, and disconnects - * GPIO bits dev->sda_pin and dev->scl_pin on GPIO device - * dev->gpio_port from I2C device dev. - * - * @param dev I2C device - * @see i2c_config_gpios() - */ -extern void i2c_master_release_bus(const i2c_dev *dev); - -/* Miscellaneous low-level routines */ - -/** - * @brief Initialize an I2C device and reset its registers to their - * default values. - * @param dev Device to initialize. - */ -void i2c_init(i2c_dev *dev); - -/** - * @brief Turn on an I2C peripheral - * @param dev Device to enable - */ -static inline void i2c_peripheral_enable(i2c_dev *dev) { - dev->regs->CR1 |= I2C_CR1_PE; -} - -/** - * @brief Turn off an I2C peripheral - * @param dev Device to turn off - */ -static inline void i2c_peripheral_disable(i2c_dev *dev) { - dev->regs->CR1 &= ~I2C_CR1_PE; -} - -/** - * @brief Fill transmit register - * @param dev I2C device - * @param byte Byte to write - */ -extern void i2c_write(i2c_dev *dev, uint8 byte); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/i2c_common.h b/STM32F3/cores/maple/libmaple/include/libmaple/i2c_common.h deleted file mode 100644 index 17cabe344..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/i2c_common.h +++ /dev/null @@ -1,93 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung (from ). - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/i2c_common.h - * @author Marti Bolivar - * @brief This file is an implementation detail - * - * CONTENTS UNSTABLE. The existence of this file is an implementation - * detail. Never include it directly. If you need something from - * here, include instead. - */ - -#ifndef _LIBMAPLE_I2C_COMMON_H_ -#define _LIBMAPLE_I2C_COMMON_H_ - -#include -#include -#include - -struct gpio_dev; -struct i2c_reg_map; -struct i2c_msg; - -/** I2C device states */ -typedef enum i2c_state { - I2C_STATE_DISABLED = 0, /**< Disabled */ - I2C_STATE_IDLE = 1, /**< Idle */ - I2C_STATE_XFER_DONE = 2, /**< Done with transfer */ - I2C_STATE_BUSY = 3, /**< Busy */ - I2C_STATE_ERROR = -1 /**< Error occurred */ -} i2c_state; - -/** - * @brief I2C device type. - */ -typedef struct i2c_dev { - struct i2c_reg_map *regs; /**< Register map */ - struct i2c_msg *msg; /**< Messages */ - uint32 error_flags; /**< Error flags, set on I2C error condition */ - volatile uint32 timestamp; /**< For internal use */ - - /** - * @brief Deprecated. Use .scl_port or .sda_port instead. - * If non-null, this will be used as SDA, SCL pins' GPIO port. If - * null, then .sda_port will be used for SDA, and .sda_port for - * SDA. */ - struct gpio_dev *gpio_port; - - /** - * @brief SDA GPIO device (but see .gpio_port). - */ - struct gpio_dev *sda_port; - - /** - * @brief SCL GPIO device (but see .gpio_port). - */ - struct gpio_dev *scl_port; - - uint16 msgs_left; /**< Messages left */ - uint8 sda_pin; /**< SDA bit on gpio_port */ - uint8 scl_pin; /**< SCL bit on gpio_port */ - rcc_clk_id clk_id; /**< RCC clock information */ - nvic_irq_num ev_nvic_line; /**< Event IRQ number */ - nvic_irq_num er_nvic_line; /**< Error IRQ number */ - volatile i2c_state state; /**< Device state */ -} i2c_dev; - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/iwdg.h b/STM32F3/cores/maple/libmaple/include/libmaple/iwdg.h deleted file mode 100644 index 3a16c5500..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/iwdg.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/iwdg.h - * @author Michael Hope, Marti Bolivar - * @brief Independent watchdog support. - * - * To use the independent watchdog, first call iwdg_init() with the - * appropriate prescaler and IWDG counter reload values for your - * application. Afterwards, you must periodically call iwdg_feed() - * before the IWDG counter reaches 0 to reset the counter to its - * reload value. If you do not, the chip will reset. - * - * Once started, the independent watchdog cannot be turned off. - */ - -#ifndef _LIBMAPLE_IWDG_H_ -#define _LIBMAPLE_IWDG_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -/* - * Register map - */ - -/** Independent watchdog register map type. */ -typedef struct iwdg_reg_map { - __io uint32 KR; /**< Key register. */ - __io uint32 PR; /**< Prescaler register. */ - __io uint32 RLR; /**< Reload register. */ - __io uint32 SR; /**< Status register */ -} iwdg_reg_map; - -/** Independent watchdog base pointer */ -#define IWDG_BASE ((struct iwdg_reg_map*)0x40003000) - -/* - * Register bit definitions - */ - -/* Key register */ - -#define IWDG_KR_UNLOCK 0x5555 -#define IWDG_KR_FEED 0xAAAA -#define IWDG_KR_START 0xCCCC - -/* Prescaler register */ - -#define IWDG_PR_DIV_4 0x0 -#define IWDG_PR_DIV_8 0x1 -#define IWDG_PR_DIV_16 0x2 -#define IWDG_PR_DIV_32 0x3 -#define IWDG_PR_DIV_64 0x4 -#define IWDG_PR_DIV_128 0x5 -#define IWDG_PR_DIV_256 0x6 - -/* Status register */ - -#define IWDG_SR_RVU_BIT 1 -#define IWDG_SR_PVU_BIT 0 - -#define IWDG_SR_RVU (1U << IWDG_SR_RVU_BIT) -#define IWDG_SR_PVU (1U << IWDG_SR_PVU_BIT) - -/** - * @brief Independent watchdog prescalers. - * - * These divide the 40 kHz IWDG clock. - */ -typedef enum iwdg_prescaler { - IWDG_PRE_4 = IWDG_PR_DIV_4, /**< Divide by 4 */ - IWDG_PRE_8 = IWDG_PR_DIV_8, /**< Divide by 8 */ - IWDG_PRE_16 = IWDG_PR_DIV_16, /**< Divide by 16 */ - IWDG_PRE_32 = IWDG_PR_DIV_32, /**< Divide by 32 */ - IWDG_PRE_64 = IWDG_PR_DIV_64, /**< Divide by 64 */ - IWDG_PRE_128 = IWDG_PR_DIV_128, /**< Divide by 128 */ - IWDG_PRE_256 = IWDG_PR_DIV_256 /**< Divide by 256 */ -} iwdg_prescaler; - -void iwdg_init(iwdg_prescaler prescaler, uint16 reload); -void iwdg_feed(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/libmaple_types.h b/STM32F3/cores/maple/libmaple/include/libmaple/libmaple_types.h deleted file mode 100644 index 60dd2ff22..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/libmaple_types.h +++ /dev/null @@ -1,73 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/libmaple_types.h - * - * @brief libmaple's types, and operations on types. - */ - -#ifndef _LIBMAPLE_LIBMAPLE_TYPES_H_ -#define _LIBMAPLE_LIBMAPLE_TYPES_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; -typedef unsigned long long uint64; - -typedef signed char int8; -typedef short int16; -typedef int int32; -typedef long long int64; - -typedef void (*voidFuncPtr)(void); -typedef void (*voidArgumentFuncPtr)(void *); - -#define __io volatile -#define __attr_flash __attribute__((section (".USER_FLASH"))) -#define __packed __attribute__((__packed__)) -#define __deprecated __attribute__((__deprecated__)) -#define __weak __attribute__((weak)) -#define __always_inline inline __attribute__((always_inline)) -#define __unused __attribute__((unused)) - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef offsetof -#define offsetof(type, member) __builtin_offsetof(type, member) -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/nvic.h b/STM32F3/cores/maple/libmaple/include/libmaple/nvic.h deleted file mode 100644 index ffe385dcd..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/nvic.h +++ /dev/null @@ -1,155 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/nvic.h - * @brief Nested vectored interrupt controller support. - * - * Basic usage: - * - * @code - * // Initialise the interrupt controller and point to the vector - * // table at the start of flash. - * nvic_init(0x08000000, 0); - * // Bind in a timer interrupt handler - * timer_attach_interrupt(TIMER_CC1_INTERRUPT, handler); - * // Optionally set the priority - * nvic_irq_set_priority(NVIC_TIMER1_CC, 5); - * // All done, enable all interrupts - * nvic_globalirq_enable(); - * @endcode - */ - -#ifndef _LIBMAPLE_NVIC_H_ -#define _LIBMAPLE_NVIC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include - -/** NVIC register map type. */ -typedef struct nvic_reg_map { - __io uint32 ISER[8]; /**< Interrupt Set Enable Registers */ - /** Reserved */ - uint32 RESERVED0[24]; - - __io uint32 ICER[8]; /**< Interrupt Clear Enable Registers */ - /** Reserved */ - uint32 RESERVED1[24]; - - __io uint32 ISPR[8]; /**< Interrupt Set Pending Registers */ - /** Reserved */ - uint32 RESERVED2[24]; - - __io uint32 ICPR[8]; /**< Interrupt Clear Pending Registers */ - /** Reserved */ - uint32 RESERVED3[24]; - - __io uint32 IABR[8]; /**< Interrupt Active bit Registers */ - /** Reserved */ - uint32 RESERVED4[56]; - - __io uint8 IP[240]; /**< Interrupt Priority Registers */ - /** Reserved */ - uint32 RESERVED5[644]; - - __io uint32 STIR; /**< Software Trigger Interrupt Registers */ -} nvic_reg_map; - -/** NVIC register map base pointer. */ -#define NVIC_BASE ((struct nvic_reg_map*)0xE000E100) - -/* - * Note: The series header must define enum nvic_irq_num, which gives - * descriptive names to the interrupts and exceptions from NMI (-14) - * to the largest interrupt available in the series, where the value - * for nonnegative enumerators corresponds to its position in the - * vector table. - * - * It also must define a static inline nvic_irq_disable_all(), which - * writes 0xFFFFFFFF to all ICE registers available in the series. (We - * place the include here to give the series header access to - * NVIC_BASE, in order to let it do so). - */ -#include - -void nvic_init(uint32 address, uint32 offset); -void nvic_set_vector_table(uint32 address, uint32 offset); -void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority); -void nvic_sys_reset(); - -/** - * Enables interrupts and configurable fault handlers (clear PRIMASK). - */ -static __always_inline void nvic_globalirq_enable() { - asm volatile("cpsie i"); -} - -/** - * Disable interrupts and configurable fault handlers (set PRIMASK). - */ -static __always_inline void nvic_globalirq_disable() { - asm volatile("cpsid i"); -} - -/** - * @brief Enable interrupt irq_num - * @param irq_num Interrupt to enable - */ -static inline void nvic_irq_enable(nvic_irq_num irq_num) { - if (irq_num < 0) { - return; - } - NVIC_BASE->ISER[irq_num / 32] = BIT(irq_num % 32); -} - -/** - * @brief Disable interrupt irq_num - * @param irq_num Interrupt to disable - */ -static inline void nvic_irq_disable(nvic_irq_num irq_num) { - if (irq_num < 0) { - return; - } - NVIC_BASE->ICER[irq_num / 32] = BIT(irq_num % 32); -} - -/** - * @brief Quickly disable all interrupts. - * - * Calling this function is significantly faster than calling - * nvic_irq_disable() in a loop. - */ -static inline void nvic_irq_disable_all(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/opamp.h b/STM32F3/cores/maple/libmaple/include/libmaple/opamp.h deleted file mode 100644 index 2a0be62a4..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/opamp.h +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file libmaple/include/libmaple/fpu.h - * @author F3-port by Hanspeter Portner - * @brief Floating Point Unit (OPAMP) interace. - */ - -#ifndef _LIBMAPLE_OPAMP_H_ -#define _LIBMAPLE_OPAMP_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/pwr.h b/STM32F3/cores/maple/libmaple/include/libmaple/pwr.h deleted file mode 100644 index e4b5b0d80..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/pwr.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/pwr.h - * @brief Power control (PWR). - */ - -#ifndef _LIBMAPLE_PWR_H_ -#define _LIBMAPLE_PWR_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/** Power interface register map. */ -typedef struct pwr_reg_map { - __io uint32 CR; /**< Control register */ - __io uint32 CSR; /**< Control and status register */ -} pwr_reg_map; - -/** Power peripheral register map base pointer. */ -#define PWR_BASE ((struct pwr_reg_map*)0x40007000) - -/* - * Register bit definitions - */ - -/* Control register */ - -/** Disable backup domain write protection bit */ -#define PWR_CR_DBP_BIT 8 -/** Power voltage detector enable bit */ -#define PWR_CR_PVDE_BIT 4 -/** Clear standby flag bit */ -#define PWR_CR_CSBF_BIT 3 -/** Clear wakeup flag bit */ -#define PWR_CR_CWUF_BIT 2 -/** Power down deepsleep bit */ -#define PWR_CR_PDDS_BIT 1 -/** Low-power deepsleep bit */ -#define PWR_CR_LPDS_BIT 0 - -/** Disable backup domain write protection */ -#define PWR_CR_DBP (1U << PWR_CR_DBP_BIT) -/** Power voltage detector (PVD) level selection */ -#define PWR_CR_PLS (0x7 << 5) -/** Power voltage detector enable */ -#define PWR_CR_PVDE (1U << PWR_CR_PVDE_BIT) -/** Clear standby flag */ -#define PWR_CR_CSBF (1U << PWR_CR_CSBF_BIT) -/** Clear wakeup flag */ -#define PWR_CR_CWUF (1U << PWR_CR_CWUF_BIT) -/** Power down deepsleep */ -#define PWR_CR_PDDS (1U << PWR_CR_PDDS_BIT) -/** Low-power deepsleep */ -#define PWR_CR_LPDS (1U << PWR_CR_LPDS_BIT) - -/* Control and status register */ - -/** Enable wakeup pin bit */ -#define PWR_CSR_EWUP_BIT 8 -/** PVD output bit */ -#define PWR_CSR_PVDO_BIT 2 -/** Standby flag bit */ -#define PWR_CSR_SBF_BIT 1 -/** Wakeup flag bit */ -#define PWR_CSR_WUF_BIT 0 - -/** Enable wakeup pin */ -#define PWR_CSR_EWUP (1U << PWR_CSR_EWUP_BIT) -/** PVD output */ -#define PWR_CSR_PVDO (1U << PWR_CSR_PVDO_BIT) -/** Standby flag */ -#define PWR_CSR_SBF (1U << PWR_CSR_SBF_BIT) -/** Wakeup flag */ -#define PWR_CSR_WUF (1U << PWR_CSR_WUF_BIT) - -/* - * Convenience functions - */ - -void pwr_init(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/rcc.h b/STM32F3/cores/maple/libmaple/include/libmaple/rcc.h deleted file mode 100644 index ea16803e7..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/rcc.h +++ /dev/null @@ -1,175 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/rcc.h - * @brief Reset and Clock Control (RCC) interface. - */ - -#ifndef _LIBMAPLE_RCC_H_ -#define _LIBMAPLE_RCC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -/* Put the SYSCLK sources before the series header is included, as it - * might need them. */ -/** - * @brief SYSCLK sources - * @see rcc_switch_sysclk() - */ -typedef enum rcc_sysclk_src { - RCC_CLKSRC_HSI = 0x0, - RCC_CLKSRC_HSE = 0x1, - RCC_CLKSRC_PLL = 0x2, -} rcc_sysclk_src; - -#include - -/* Note: Beyond the usual (registers, etc.), it's up to the series - * header to define the following types: - * - * - enum rcc_clk: Available system and secondary clock sources, - * e.g. RCC_CLK_HSE, RCC_CLK_PLL, RCC_CLK_LSE. - * - * Note that the inclusion of secondary clock sources (like LSI and - * LSE) makes enum rcc_clk different from the SYSCLK sources, which - * are defined in this header as enum rcc_sysclk_src. - * - * IMPORTANT NOTE TO IMPLEMENTORS: If you are adding support for a - * new STM32 series, see the comment near rcc_clk_reg() in - * libmaple/rcc.c for information on how to choose these values so - * that rcc_turn_on_clk() etc. will work on your series. - * - * - enum rcc_clk_id: For each available peripheral. These are widely used - * as unique IDs (TODO extricate from RCC?). Peripherals which are - * common across STM32 series should use the same token for their - * rcc_clk_id in each series header. - * - * - enum rcc_clk_domain: For each clock domain. This is returned by - * rcc_dev_clk(). For instance, each AHB and APB is a clock domain. - * - * - enum rcc_prescaler: And a suitable set of dividers for - * rcc_set_prescaler(). - * - * - enum rcc_pllsrc: For each PLL source. Same source, same token. - * - * - A target-dependent type to be pointed to by the data field in a - * struct rcc_pll_cfg. - */ - -#ifdef __DOXYGEN__ -/** RCC register map base pointer */ -#define RCC_BASE -#endif - -/* Clock prescaler management. */ - -/** - * @brief Set the divider on a peripheral prescaler - * @param prescaler prescaler to set - * @param divider prescaler divider - */ -extern void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider); - -/* SYSCLK. */ - -void rcc_switch_sysclk(rcc_sysclk_src sysclk_src); - -/* PLL configuration */ - -/** - * @brief Specifies a configuration for the main PLL. - */ -typedef struct rcc_pll_cfg { - rcc_pllsrc pllsrc; /**< PLL source */ - - /** Series-specific configuration data. */ - void *data; -} rcc_pll_cfg; - -/** - * @brief Configure the main PLL. - * - * You may only call this function while the PLL is disabled. - * - * @param pll_cfg Desired PLL configuration. The contents of this - * struct depend entirely on the target. - */ -extern void rcc_configure_pll(rcc_pll_cfg *pll_cfg); - -/* System and secondary clock sources. */ - -void rcc_turn_on_clk(rcc_clk clock); -void rcc_turn_off_clk(rcc_clk clock); -int rcc_is_clk_on(rcc_clk clock); -int rcc_is_clk_ready(rcc_clk clock); - -/* Peripheral clock lines and clock domains. */ - -/** - * @brief Turn on the clock line on a peripheral - * @param id Clock ID of the peripheral to turn on. - */ -extern void rcc_clk_enable(rcc_clk_id id); - -/** - * @brief Reset a peripheral. - * - * Caution: not all rcc_clk_id values refer to a peripheral which can - * be reset. (Only rcc_clk_ids for peripherals with bits in an RCC - * reset register can be used here.) - * - * @param id Clock ID of the peripheral to reset. - */ -extern void rcc_reset_dev(rcc_clk_id id); - -rcc_clk_domain rcc_dev_clk(rcc_clk_id id); - -/* Clock security system */ - -/** - * @brief Enable the clock security system (CSS). - */ -static inline void rcc_enable_css() { - RCC_BASE->CR |= RCC_CR_CSSON; -} - -/** - * @brief Disable the clock security system (CSS). - */ -static inline void rcc_disable_css() { - RCC_BASE->CR &= ~RCC_CR_CSSON; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/ring_buffer.h b/STM32F3/cores/maple/libmaple/include/libmaple/ring_buffer.h deleted file mode 100644 index e02e6e727..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/ring_buffer.h +++ /dev/null @@ -1,188 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/ring_buffer.h - * @brief Simple circular buffer - * - * This implementation is not thread-safe. In particular, none of - * these functions is guaranteed re-entrant. - */ - -#ifndef _LIBMAPLE_RING_BUFFER_H_ -#define _LIBMAPLE_RING_BUFFER_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -/** - * Ring buffer type. - * - * The buffer is empty when head == tail. - * - * The buffer is full when the head is one byte in front of the tail, - * modulo buffer length. - * - * One byte is left free to distinguish empty from full. */ -typedef struct ring_buffer { - volatile uint8 *buf; /**< Buffer items are stored into */ - uint16 head; /**< Index of the next item to remove */ - uint16 tail; /**< Index where the next item will get inserted */ - uint16 size; /**< Buffer capacity minus one */ -} ring_buffer; - -/** - * Initialise a ring buffer. - * - * @param rb Instance to initialise - * - * @param size Number of items in buf. The ring buffer will always - * leave one element unoccupied, so the maximum number of - * elements it can store will be size - 1. Thus, size - * must be at least 2. - * - * @param buf Buffer to store items into - */ -static inline void rb_init(ring_buffer *rb, uint16 size, uint8 *buf) { - rb->head = 0; - rb->tail = 0; - rb->size = size - 1; - rb->buf = buf; -} - -/** - * @brief Return the number of elements stored in the ring buffer. - * @param rb Buffer whose elements to count. - */ -static inline uint16 rb_full_count(ring_buffer *rb) { - __io ring_buffer *arb = rb; - int32 size = arb->tail - arb->head; - if (arb->tail < arb->head) { - size += arb->size + 1; - } - return (uint16)size; -} - -/** - * @brief Returns true if and only if the ring buffer is full. - * @param rb Buffer to test. - */ -static inline int rb_is_full(ring_buffer *rb) { - return (rb->tail + 1 == rb->head) || - (rb->tail == rb->size && rb->head == 0); -} - -/** - * @brief Returns true if and only if the ring buffer is empty. - * @param rb Buffer to test. - */ -static inline int rb_is_empty(ring_buffer *rb) { - return rb->head == rb->tail; -} - -/** - * Append element onto the end of a ring buffer. - * @param rb Buffer to append onto. - * @param element Value to append. - */ -static inline void rb_insert(ring_buffer *rb, uint8 element) { - rb->buf[rb->tail] = element; - rb->tail = (rb->tail == rb->size) ? 0 : rb->tail + 1; -} - -/** - * @brief Remove and return the first item from a ring buffer. - * @param rb Buffer to remove from, must contain at least one element. - */ -static inline uint8 rb_remove(ring_buffer *rb) { - uint8 ch = rb->buf[rb->head]; - rb->head = (rb->head == rb->size) ? 0 : rb->head + 1; - return ch; -} - -/** - * @brief Attempt to remove the first item from a ring buffer. - * - * If the ring buffer is nonempty, removes and returns its first item. - * If it is empty, does nothing and returns a negative value. - * - * @param rb Buffer to attempt to remove from. - */ -static inline int16 rb_safe_remove(ring_buffer *rb) { - return rb_is_empty(rb) ? -1 : rb_remove(rb); -} - -/** - * @brief Attempt to insert an element into a ring buffer. - * - * @param rb Buffer to insert into. - * @param element Value to insert into rb. - * @sideeffect If rb is not full, appends element onto buffer. - * @return If element was appended, then true; otherwise, false. */ -static inline int rb_safe_insert(ring_buffer *rb, uint8 element) { - if (rb_is_full(rb)) { - return 0; - } - rb_insert(rb, element); - return 1; -} - -/** - * @brief Append an item onto the end of a non-full ring buffer. - * - * If the buffer is full, removes its first item, then inserts the new - * element at the end. - * - * @param rb Ring buffer to insert into. - * @param element Value to insert into ring buffer. - * @return On success, returns -1. If an element was popped, returns - * the popped value. - */ -static inline int rb_push_insert(ring_buffer *rb, uint8 element) { - int ret = -1; - if (rb_is_full(rb)) { - ret = rb_remove(rb); - } - rb_insert(rb, element); - return ret; -} - -/** - * @brief Discard all items from a ring buffer. - * @param rb Ring buffer to discard all items from. - */ -static inline void rb_reset(ring_buffer *rb) { - rb->tail = rb->head; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/scb.h b/STM32F3/cores/maple/libmaple/include/libmaple/scb.h deleted file mode 100644 index c42a0f2a0..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/scb.h +++ /dev/null @@ -1,214 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011-2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/scb.h - * @brief System control block header - */ - -/* - * FIXME: STM32F2? - */ - -#ifndef _LIBMAPLE_SCB_H_ -#define _LIBMAPLE_SCB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* - * Register map and base pointer - */ - -/** System control block register map type */ -typedef struct scb_reg_map { - __io uint32 CPUID; /**< CPU ID Base Register */ - __io uint32 ICSR; /**< Interrupt Control State Register */ - __io uint32 VTOR; /**< Vector Table Offset Register */ - __io uint32 AIRCR; /**< Application Interrupt / Reset Control Register */ - __io uint32 SCR; /**< System Control Register */ - __io uint32 CCR; /**< Configuration and Control Register */ - __io uint8 SHP[12]; /**< System Handler Priority Registers - (4-7, 8-11, 12-15) */ - __io uint32 SHCSR; /**< System Handler Control and State Register */ - __io uint32 CFSR; /**< Configurable Fault Status Register */ - __io uint32 HFSR; /**< Hard Fault Status Register */ - /* DFSR is not documented by ST in PM0056 (as of Revision 4), but - * there's a 4 byte hole in the SCB register map docs right where - * it belongs. Since it's specified as "always implemented" in - * the ARM v7-M ARM, I'm assuming its absence is a bug in the ST - * doc, but I haven't proven it. [mbolivar] */ - __io uint32 DFSR; /**< Debug Fault Status Register */ - __io uint32 MMFAR; /**< Mem Manage Address Register */ - __io uint32 BFAR; /**< Bus Fault Address Register */ -#if 0 - /* The following registers are implementation-defined according to - * ARM v7-M, and I can't find evidence of their existence in ST's - * docs. I'm removing them. Feel free to yell at me if they do - * exist. [mbolivar] - */ - __io uint32 AFSR; /**< Auxiliary Fault Status Register */ - __io uint32 PFR[2]; /**< Processor Feature Register */ - __io uint32 DFR; /**< Debug Feature Register */ - __io uint32 AFR; /**< Auxiliary Feature Register */ - __io uint32 MMFR[4]; /**< Memory Model Feature Register */ - __io uint32 ISAR[5]; /**< ISA Feature Register */ -#endif -} scb_reg_map; - -/** System control block register map base pointer */ -#define SCB_BASE ((struct scb_reg_map*)0xE000ED00) - -/* - * Register bit definitions - */ - -/* No SCB_REG_FIELD_BIT macros as the relevant addresses are not in a - * bit-band region. */ - -/* CPUID base register (SCB_CPUID) */ - -#define SCB_CPUID_IMPLEMENTER (0xFF << 24) -#define SCB_CPUID_VARIANT (0xF << 20) -#define SCB_CPUID_CONSTANT (0xF << 16) -#define SCB_CPUID_PARTNO (0xFFF << 4) -#define SCB_CPUID_REVISION 0xF - -/* Interrupt control state register (SCB_ICSR) */ - -#define SCB_ICSR_NMIPENDSET (1U << 31) -#define SCB_ICSR_PENDSVSET (1U << 28) -#define SCB_ICSR_PENDSVCLR (1U << 27) -#define SCB_ICSR_PENDSTSET (1U << 26) -#define SCB_ICSR_PENDSTCLR (1U << 25) -#define SCB_ICSR_ISRPENDING (1U << 22) -#define SCB_ICSR_VECTPENDING (0x3FF << 12) -#define SCB_ICSR_RETOBASE (1U << 11) -#define SCB_ICSR_VECTACTIVE 0xFF - -/* Vector table offset register (SCB_VTOR) */ - -#define SCB_VTOR_TBLOFF (0x1FFFFF << 9) - -/* Application interrupt and reset control register (SCB_AIRCR) */ - -#define SCB_AIRCR_VECTKEYSTAT (0x5FA << 16) -#define SCB_AIRCR_VECTKEY (0x5FA << 16) -#define SCB_AIRCR_ENDIANNESS (1U << 15) -#define SCB_AIRCR_PRIGROUP (0x3 << 8) -#define SCB_AIRCR_SYSRESETREQ (1U << 2) -#define SCB_AIRCR_VECTCLRACTIVE (1U << 1) -#define SCB_AIRCR_VECTRESET (1U << 0) - -/* System control register (SCB_SCR) */ - -#define SCB_SCR_SEVONPEND (1U << 4) -#define SCB_SCR_SLEEPDEEP (1U << 2) -#define SCB_SCR_SLEEPONEXIT (1U << 1) - -/* Configuration and Control Register (SCB_CCR) */ - -#define SCB_CCR_STKALIGN (1U << 9) -#define SCB_CCR_BFHFNMIGN (1U << 8) -#define SCB_CCR_DIV_0_TRP (1U << 4) -#define SCB_CCR_UNALIGN_TRP (1U << 3) -#define SCB_CCR_USERSETMPEND (1U << 1) -#define SCB_CCR_NONBASETHRDENA (1U << 0) - -/* System handler priority registers (SCB_SHPRx) */ - -#define SCB_SHPR1_PRI6 (0xFF << 16) -#define SCB_SHPR1_PRI5 (0xFF << 8) -#define SCB_SHPR1_PRI4 0xFF - -#define SCB_SHPR2_PRI11 (0xFF << 24) - -#define SCB_SHPR3_PRI15 (0xFF << 24) -#define SCB_SHPR3_PRI14 (0xFF << 16) - -/* System Handler Control and state register (SCB_SHCSR) */ - -#define SCB_SHCSR_USGFAULTENA (1U << 18) -#define SCB_SHCSR_BUSFAULTENA (1U << 17) -#define SCB_SHCSR_MEMFAULTENA (1U << 16) -#define SCB_SHCSR_SVCALLPENDED (1U << 15) -#define SCB_SHCSR_BUSFAULTPENDED (1U << 14) -#define SCB_SHCSR_MEMFAULTPENDED (1U << 13) -#define SCB_SHCSR_USGFAULTPENDED (1U << 12) -#define SCB_SHCSR_SYSTICKACT (1U << 11) -#define SCB_SHCSR_PENDSVACT (1U << 10) -#define SCB_SHCSR_MONITORACT (1U << 8) -#define SCB_SHCSR_SVCALLACT (1U << 7) -#define SCB_SHCSR_USGFAULTACT (1U << 3) -#define SCB_SHCSR_BUSFAULTACT (1U << 1) -#define SCB_SHCSR_MEMFAULTACT (1U << 0) - -/* Configurable fault status register (SCB_CFSR) */ - -#define SCB_CFSR_DIVBYZERO (1U << 25) -#define SCB_CFSR_UNALIGNED (1U << 24) -#define SCB_CFSR_NOCP (1U << 19) -#define SCB_CFSR_INVPC (1U << 18) -#define SCB_CFSR_INVSTATE (1U << 17) -#define SCB_CFSR_UNDEFINSTR (1U << 16) -#define SCB_CFSR_BFARVALID (1U << 15) -#define SCB_CFSR_STKERR (1U << 12) -#define SCB_CFSR_UNSTKERR (1U << 11) -#define SCB_CFSR_IMPRECISERR (1U << 10) -#define SCB_CFSR_PRECISERR (1U << 9) -#define SCB_CFSR_IBUSERR (1U << 8) -#define SCB_CFSR_MMARVALID (1U << 7) -#define SCB_CFSR_MSTKERR (1U << 4) -#define SCB_CFSR_MUNSTKERR (1U << 3) -#define SCB_CFSR_DACCVIOL (1U << 1) -#define SCB_CFSR_IACCVIOL (1U << 0) - -/* Hard Fault Status Register (SCB_HFSR) */ - -#define SCB_HFSR_DEBUG_VT (1U << 31) -#define SCB_CFSR_FORCED (1U << 30) -#define SCB_CFSR_VECTTBL (1U << 1) - -/* Debug Fault Status Register */ - -/* Not specified by PM0056, but required by ARM. The bit definitions - * here are based on the names given in the ARM v7-M ARM. */ - -#define SCB_DFSR_EXTERNAL (1U << 4) -#define SCB_DFSR_VCATCH (1U << 3) -#define SCB_DFSR_DWTTRAP (1U << 2) -#define SCB_DFSR_BKPT (1U << 1) -#define SCB_DFSR_HALTED (1U << 0) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/spi.h b/STM32F3/cores/maple/libmaple/include/libmaple/spi.h deleted file mode 100644 index e688e4f9f..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/spi.h +++ /dev/null @@ -1,487 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/spi.h - * @author Marti Bolivar , - * F3-port by Hanspeter Portner - * @brief Serial Peripheral Interface (SPI) and Integrated - * Interchip Sound (I2S) peripheral support. - * - * I2S support is currently limited to register maps and bit definitions. - */ - -#ifndef _LIBMAPLE_SPI_H_ -#define _LIBMAPLE_SPI_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include - -/* - * Register maps - */ - -/** SPI register map type. */ -typedef struct spi_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SR; /**< Status register */ - __io uint32 DR; /**< Data register */ - __io uint32 CRCPR; /**< CRC polynomial register */ - __io uint32 RXCRCR; /**< RX CRC register */ - __io uint32 TXCRCR; /**< TX CRC register */ - __io uint32 I2SCFGR; /**< I2S configuration register */ - __io uint32 I2SPR; /**< I2S prescaler register */ -} spi_reg_map; - -/* - * Register bit definitions - */ - -/* Control register 1 */ - -#define SPI_CR1_BIDIMODE_BIT 15 -#define SPI_CR1_BIDIOE_BIT 14 -#define SPI_CR1_CRCEN_BIT 13 -#define SPI_CR1_CRCNEXT_BIT 12 -#define SPI_CR1_DFF_BIT 11 /* FIXME F3 incompatibility */ -#define SPI_CR1_RXONLY_BIT 10 -#define SPI_CR1_SSM_BIT 9 -#define SPI_CR1_SSI_BIT 8 -#define SPI_CR1_LSBFIRST_BIT 7 -#define SPI_CR1_SPE_BIT 6 -#define SPI_CR1_MSTR_BIT 2 -#define SPI_CR1_CPOL_BIT 1 -#define SPI_CR1_CPHA_BIT 0 - -#define SPI_CR1_BIDIMODE (1U << SPI_CR1_BIDIMODE_BIT) -#define SPI_CR1_BIDIMODE_2_LINE (0x0 << SPI_CR1_BIDIMODE_BIT) -#define SPI_CR1_BIDIMODE_1_LINE (0x1 << SPI_CR1_BIDIMODE_BIT) -#define SPI_CR1_BIDIOE (1U << SPI_CR1_BIDIOE_BIT) -#define SPI_CR1_CRCEN (1U << SPI_CR1_CRCEN_BIT) -#define SPI_CR1_CRCNEXT (1U << SPI_CR1_CRCNEXT_BIT) -#define SPI_CR1_DFF (1U << SPI_CR1_DFF_BIT) -#define SPI_CR1_DFF_8_BIT (0x0 << SPI_CR1_DFF_BIT) -#define SPI_CR1_DFF_16_BIT (0x1 << SPI_CR1_DFF_BIT) -#define SPI_CR1_RXONLY (1U << SPI_CR1_RXONLY_BIT) -#define SPI_CR1_SSM (1U << SPI_CR1_SSM_BIT) -#define SPI_CR1_SSI (1U << SPI_CR1_SSI_BIT) -#define SPI_CR1_LSBFIRST (1U << SPI_CR1_LSBFIRST_BIT) -#define SPI_CR1_SPE (1U << SPI_CR1_SPE_BIT) -#define SPI_CR1_BR (0x7 << 3) -#define SPI_CR1_BR_PCLK_DIV_2 (0x0 << 3) -#define SPI_CR1_BR_PCLK_DIV_4 (0x1 << 3) -#define SPI_CR1_BR_PCLK_DIV_8 (0x2 << 3) -#define SPI_CR1_BR_PCLK_DIV_16 (0x3 << 3) -#define SPI_CR1_BR_PCLK_DIV_32 (0x4 << 3) -#define SPI_CR1_BR_PCLK_DIV_64 (0x5 << 3) -#define SPI_CR1_BR_PCLK_DIV_128 (0x6 << 3) -#define SPI_CR1_BR_PCLK_DIV_256 (0x7 << 3) -#define SPI_CR1_MSTR (1U << SPI_CR1_MSTR_BIT) -#define SPI_CR1_CPOL (1U << SPI_CR1_CPOL_BIT) -#define SPI_CR1_CPOL_LOW (0x0 << SPI_CR1_CPOL_BIT) -#define SPI_CR1_CPOL_HIGH (0x1 << SPI_CR1_CPOL_BIT) -#define SPI_CR1_CPHA (1U << SPI_CR1_CPHA_BIT) - -/* Control register 2 */ - -#define SPI_CR2_TXEIE_BIT 7 -#define SPI_CR2_RXNEIE_BIT 6 -#define SPI_CR2_ERRIE_BIT 5 -#define SPI_CR2_SSOE_BIT 2 -#define SPI_CR2_TXDMAEN_BIT 1 -#define SPI_CR2_RXDMAEN_BIT 0 - -#define SPI_CR2_TXEIE (1U << SPI_CR2_TXEIE_BIT) -#define SPI_CR2_RXNEIE (1U << SPI_CR2_RXNEIE_BIT) -#define SPI_CR2_ERRIE (1U << SPI_CR2_ERRIE_BIT) -#define SPI_CR2_SSOE (1U << SPI_CR2_SSOE_BIT) -#define SPI_CR2_TXDMAEN (1U << SPI_CR2_TXDMAEN_BIT) -#define SPI_CR2_RXDMAEN (1U << SPI_CR2_RXDMAEN_BIT) - -/* Status register */ - -#define SPI_SR_BSY_BIT 7 -#define SPI_SR_OVR_BIT 6 -#define SPI_SR_MODF_BIT 5 -#define SPI_SR_CRCERR_BIT 4 -#define SPI_SR_UDR_BIT 3 -#define SPI_SR_CHSIDE_BIT 2 -#define SPI_SR_TXE_BIT 1 -#define SPI_SR_RXNE_BIT 0 - -#define SPI_SR_BSY (1U << SPI_SR_BSY_BIT) -#define SPI_SR_OVR (1U << SPI_SR_OVR_BIT) -#define SPI_SR_MODF (1U << SPI_SR_MODF_BIT) -#define SPI_SR_CRCERR (1U << SPI_SR_CRCERR_BIT) -#define SPI_SR_UDR (1U << SPI_SR_UDR_BIT) -#define SPI_SR_CHSIDE (1U << SPI_SR_CHSIDE_BIT) -#define SPI_SR_CHSIDE_LEFT (0x0 << SPI_SR_CHSIDE_BIT) -#define SPI_SR_CHSIDE_RIGHT (0x1 << SPI_SR_CHSIDE_BIT) -#define SPI_SR_TXE (1U << SPI_SR_TXE_BIT) -#define SPI_SR_RXNE (1U << SPI_SR_RXNE_BIT) - -/* I2S configuration register */ - -#define SPI_I2SCFGR_I2SMOD_BIT 11 -#define SPI_I2SCFGR_I2SE_BIT 10 -#define SPI_I2SCFGR_PCMSYNC_BIT 7 -#define SPI_I2SCFGR_CKPOL_BIT 3 -#define SPI_I2SCFGR_CHLEN_BIT 0 - -#define SPI_I2SCFGR_I2SMOD (1U << SPI_I2SCFGR_I2SMOD_BIT) -#define SPI_I2SCFGR_I2SMOD_SPI (0x0 << SPI_I2SCFGR_I2SMOD_BIT) -#define SPI_I2SCFGR_I2SMOD_I2S (0x1 << SPI_I2SCFGR_I2SMOD_BIT) -#define SPI_I2SCFGR_I2SE (1U << SPI_I2SCFGR_I2SE_BIT) -#define SPI_I2SCFGR_I2SCFG (0x3 << 8) -#define SPI_I2SCFGR_I2SCFG_SLAVE_TX (0x0 << 8) -#define SPI_I2SCFGR_I2SCFG_SLAVE_RX (0x1 << 8) -#define SPI_I2SCFGR_I2SCFG_MASTER_TX (0x2 << 8) -#define SPI_I2SCFGR_I2SCFG_MASTER_RX (0x3 << 8) -#define SPI_I2SCFGR_PCMSYNC (1U << SPI_I2SCFGR_PCMSYNC_BIT) -#define SPI_I2SCFGR_PCMSYNC_SHORT (0x0 << SPI_I2SCFGR_PCMSYNC_BIT) -#define SPI_I2SCFGR_PCMSYNC_LONG (0x1 << SPI_I2SCFGR_PCMSYNC_BIT) -#define SPI_I2SCFGR_I2SSTD (0x3 << 4) -#define SPI_I2SCFGR_I2SSTD_PHILLIPS (0x0 << 4) -#define SPI_I2SCFGR_I2SSTD_MSB (0x1 << 4) -#define SPI_I2SCFGR_I2SSTD_LSB (0x2 << 4) -#define SPI_I2SCFGR_I2SSTD_PCM (0x3 << 4) -#define SPI_I2SCFGR_CKPOL (1U << SPI_I2SCFGR_CKPOL_BIT) -#define SPI_I2SCFGR_CKPOL_LOW (0x0 << SPI_I2SCFGR_CKPOL_BIT) -#define SPI_I2SCFGR_CKPOL_HIGH (0x1 << SPI_I2SCFGR_CKPOL_BIT) -#define SPI_I2SCFGR_DATLEN (0x3 << 1) -#define SPI_I2SCFGR_DATLEN_16_BIT (0x0 << 1) -#define SPI_I2SCFGR_DATLEN_24_BIT (0x1 << 1) -#define SPI_I2SCFGR_DATLEN_32_BIT (0x2 << 1) -#define SPI_I2SCFGR_CHLEN (1U << SPI_I2SCFGR_CHLEN_BIT) -#define SPI_I2SCFGR_CHLEN_16_BIT (0x0 << SPI_I2SCFGR_CHLEN_BIT) -#define SPI_I2SCFGR_CHLEN_32_BIT (0x1 << SPI_I2SCFGR_CHLEN_BIT) - -/* I2S prescaler register */ - -#define SPI_I2SPR_MCKOE_BIT 9 -#define SPI_I2SPR_ODD_BIT 8 - -#define SPI_I2SPR_MCKOE (1U << SPI_I2SPR_MCKOE_BIT) -#define SPI_I2SPR_ODD (1U << SPI_I2SPR_ODD_BIT) -#define SPI_I2SPR_I2SDIV 0xFF - -/* - * Devices - */ - -/** SPI device type */ -typedef struct spi_dev { - spi_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ - nvic_irq_num irq_num; /**< NVIC interrupt number */ -} spi_dev; - -/* - * SPI Convenience functions - */ - -void spi_init(spi_dev *dev); - -struct gpio_dev; -/** - * @brief Configure GPIO bit modes for use as a SPI port's pins. - * - * @param dev SPI device - * @param as_master If true, configure as bus master; otherwise, as slave. - * @param nss_dev NSS pin's GPIO device - * @param nss_bit NSS pin's GPIO bit on nss_dev - * @param comm_dev SCK, MISO, MOSI pins' GPIO device - * @param sck_bit SCK pin's GPIO bit on comm_dev - * @param miso_bit MISO pin's GPIO bit on comm_dev - * @param mosi_bit MOSI pin's GPIO bit on comm_dev - */ -extern void spi_config_gpios(spi_dev *dev, - uint8 as_master, - struct gpio_dev *nss_dev, - uint8 nss_bit, - struct gpio_dev *comm_dev, - uint8 sck_bit, - uint8 miso_bit, - uint8 mosi_bit); - -/** - * @brief SPI mode configuration. - * - * A SPI mode determines a combination of the idle state of the clock - * line (the clock polarity, or "CPOL"), and which clock edge triggers - * data capture (the clock phase, or "CPHA"). - */ -typedef enum spi_mode { - /** Clock idles low, data captured on rising edge (first transition) */ - SPI_MODE_LOW_RISING = 0, - /** Clock idles low, data captured on falling edge (second transition) */ - SPI_MODE_LOW_FALLING = 1, - /** Clock idles high, data captured on falling edge (first transition) */ - SPI_MODE_HIGH_FALLING = 2, - /** Clock idles high, data captured on rising edge (second transition) */ - SPI_MODE_HIGH_RISING = 3, - - SPI_MODE_0 = SPI_MODE_LOW_RISING, /**< Same as SPI_MODE_LOW_RISING */ - SPI_MODE_1 = SPI_MODE_LOW_FALLING, /**< Same as SPI_MODE_LOW_FALLING */ - SPI_MODE_2 = SPI_MODE_HIGH_FALLING, /**< Same as SPI_MODE_HIGH_FALLING */ - SPI_MODE_3 = SPI_MODE_HIGH_RISING, /**< Same as SPI_MODE_HIGH_RISING */ -} spi_mode; - -/** - * @brief SPI baud rate configuration, as a divisor of f_PCLK, the - * PCLK clock frequency. - */ -typedef enum spi_baud_rate { - SPI_BAUD_PCLK_DIV_2 = SPI_CR1_BR_PCLK_DIV_2, /**< f_PCLK/2 */ - SPI_BAUD_PCLK_DIV_4 = SPI_CR1_BR_PCLK_DIV_4, /**< f_PCLK/4 */ - SPI_BAUD_PCLK_DIV_8 = SPI_CR1_BR_PCLK_DIV_8, /**< f_PCLK/8 */ - SPI_BAUD_PCLK_DIV_16 = SPI_CR1_BR_PCLK_DIV_16, /**< f_PCLK/16 */ - SPI_BAUD_PCLK_DIV_32 = SPI_CR1_BR_PCLK_DIV_32, /**< f_PCLK/32 */ - SPI_BAUD_PCLK_DIV_64 = SPI_CR1_BR_PCLK_DIV_64, /**< f_PCLK/64 */ - SPI_BAUD_PCLK_DIV_128 = SPI_CR1_BR_PCLK_DIV_128, /**< f_PCLK/128 */ - SPI_BAUD_PCLK_DIV_256 = SPI_CR1_BR_PCLK_DIV_256, /**< f_PCLK/256 */ -} spi_baud_rate; - -/** - * @brief SPI initialization flags. - * @see spi_master_enable() - * @see spi_slave_enable() - */ -typedef enum spi_cfg_flag { - SPI_BIDIMODE = SPI_CR1_BIDIMODE, /**< Bidirectional mode enable */ - SPI_BIDIOE = SPI_CR1_BIDIOE, /**< Output enable in bidirectional - mode */ - SPI_CRCEN = SPI_CR1_CRCEN, /**< Cyclic redundancy check (CRC) - enable */ - SPI_DFF_8_BIT = SPI_CR1_DFF_8_BIT, /**< 8-bit data frame format (this is - the default) */ - SPI_DFF_16_BIT = SPI_CR1_DFF_16_BIT, /**< 16-bit data frame format */ - SPI_RX_ONLY = SPI_CR1_RXONLY, /**< Receive only */ - SPI_SW_SLAVE = SPI_CR1_SSM, /**< Software slave management */ - SPI_SOFT_SS = SPI_CR1_SSI, /**< Software (internal) slave - select. This flag only has an - effect when used in combination - with SPI_SW_SLAVE. */ - SPI_FRAME_LSB = SPI_CR1_LSBFIRST, /**< LSB-first (little-endian) frame - format */ - SPI_FRAME_MSB = 0, /**< MSB-first (big-endian) frame - format (this is the default) */ -} spi_cfg_flag; - -void spi_master_enable(spi_dev *dev, - spi_baud_rate baud, - spi_mode mode, - uint32 flags); - -void spi_slave_enable(spi_dev *dev, - spi_mode mode, - uint32 flags); - -uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len); - -/** - * @brief Call a function on each SPI port - * @param fn Function to call. - */ -extern void spi_foreach(void (*fn)(spi_dev*)); - -void spi_peripheral_enable(spi_dev *dev); -void spi_peripheral_disable(spi_dev *dev); - -void spi_tx_dma_enable(spi_dev *dev); -void spi_tx_dma_disable(spi_dev *dev); - -void spi_rx_dma_enable(spi_dev *dev); -void spi_rx_dma_disable(spi_dev *dev); - -/** - * @brief Determine if a SPI peripheral is enabled. - * @param dev SPI device - * @return True, if and only if dev's peripheral is enabled. - */ -static inline uint8 spi_is_enabled(spi_dev *dev) { - return dev->regs->CR1 & SPI_CR1_SPE_BIT; -} - -/** - * @brief Disable all SPI peripherals - */ -static inline void spi_peripheral_disable_all(void) { - spi_foreach(spi_peripheral_disable); -} - -/** Available SPI interrupts */ -typedef enum spi_interrupt { - SPI_TXE_INTERRUPT = SPI_CR2_TXEIE, /**< TX buffer empty interrupt */ - SPI_RXNE_INTERRUPT = SPI_CR2_RXNEIE, /**< RX buffer not empty interrupt */ - SPI_ERR_INTERRUPT = SPI_CR2_ERRIE /**< - * Error interrupt (CRC, overrun, - * and mode fault errors for SPI; - * underrun, overrun errors for I2S) - */ -} spi_interrupt; - -/** - * @brief Mask for all spi_interrupt values - * @see spi_interrupt - */ -#define SPI_INTERRUPTS_ALL (SPI_TXE_INTERRUPT | \ - SPI_RXNE_INTERRUPT | \ - SPI_ERR_INTERRUPT) - -/** - * @brief Enable SPI interrupt requests - * @param dev SPI device - * @param interrupt_flags Bitwise OR of spi_interrupt values to enable - * @see spi_interrupt - */ -static inline void spi_irq_enable(spi_dev *dev, uint32 interrupt_flags) { - dev->regs->CR2 |= interrupt_flags; - nvic_irq_enable(dev->irq_num); -} - -/** - * @brief Disable SPI interrupt requests - * @param dev SPI device - * @param interrupt_flags Bitwise OR of spi_interrupt values to disable - * @see spi_interrupt - */ -static inline void spi_irq_disable(spi_dev *dev, uint32 interrupt_flags) { - dev->regs->CR2 &= ~interrupt_flags; -} - -/** - * @brief Get the data frame format flags with which a SPI port is - * configured. - * @param dev SPI device whose data frame format to get. - * @return SPI_DFF_8_BIT, if dev has an 8-bit data frame format. - * Otherwise, SPI_DFF_16_BIT. - */ -static inline spi_cfg_flag spi_dff(spi_dev *dev) { - return ((dev->regs->CR1 & SPI_CR1_DFF) == SPI_CR1_DFF_8_BIT ? - SPI_DFF_8_BIT : - SPI_DFF_16_BIT); -} - -/** - * @brief Determine whether the device's peripheral receive (RX) - * register is empty. - * @param dev SPI device - * @return true, iff dev's RX register is empty. - */ -static inline uint8 spi_is_rx_nonempty(spi_dev *dev) { - return dev->regs->SR & SPI_SR_RXNE; -} - -/** - * @brief Retrieve the contents of the device's peripheral receive - * (RX) register. - * - * You may only call this function when the RX register is nonempty. - * Calling this function clears the contents of the RX register. - * - * @param dev SPI device - * @return Contents of dev's peripheral RX register - * @see spi_is_rx_reg_nonempty() - */ -extern uint16 spi_rx_reg(spi_dev *dev); - -/** - * @brief Determine whether the device's peripheral transmit (TX) - * register is empty. - * @param dev SPI device - * @return true, iff dev's TX register is empty. - */ -static inline uint8 spi_is_tx_empty(spi_dev *dev) { - return dev->regs->SR & SPI_SR_TXE; -} - -/** - * @brief Nonblocking SPI transmit. - * @param dev SPI port to use for transmission - * @param buf Buffer to transmit. The sizeof buf's elements are - * inferred from dev's data frame format (i.e., are - * correctly treated as 8-bit or 16-bit quantities). - * @param len Maximum number of elements to transmit. - * @return Number of elements transmitted. - */ -extern uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len); - -/** - * @brief Load a value into the device's peripheral transmit (TX) register. - * - * You may only call this function when the TX register is empty. - * Calling this function loads val into the peripheral's TX register. - * If the device is properly configured, this will initiate a - * transmission, the completion of which will cause the TX register to - * be empty again. - * - * @param dev SPI device - * @param val Value to load into the TX register. If the SPI data - * frame format is 8 bit, the value must be right-aligned. - * @see spi_is_tx_reg_empty() - * @see spi_init() - * @see spi_master_enable() - * @see spi_slave_enable() - */ -static inline void spi_tx_reg(spi_dev *dev, uint16 val) { - dev->regs->DR = val; /* FIXME F3 incompatibility */ -} - -/** - * @brief Determine whether the device's peripheral busy (SPI_SR_BSY) - * flag is set. - * @param dev SPI device - * @return true, iff dev's BSY flag is set. - */ -static inline uint8 spi_is_busy(spi_dev *dev) { - return dev->regs->SR & SPI_SR_BSY; -} - -/* - * SPI auxiliary routines - */ - -extern void spi_reconfigure(spi_dev *dev, uint32 cr1_config); - -/* - * I2S convenience functions (TODO) - */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/stm32.h b/STM32F3/cores/maple/libmaple/include/libmaple/stm32.h deleted file mode 100644 index f7ced236b..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/stm32.h +++ /dev/null @@ -1,239 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010, 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/stm32.h - * @brief STM32 chip header - * - * This header supplies various chip-specific values for the current - * build target. It's useful both to abstract away hardware details - * (e.g. through use of STM32_NR_INTERRUPTS) and to decide what to do - * when you want something nonportable (e.g. by checking - * STM32_MCU_SERIES). - */ - -#ifndef _LIBMAPLE_STM32_H_ -#define _LIBMAPLE_STM32_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * STM32 series identifiers. - * - * Don't make these into an enum; the preprocessor needs them. - */ - -/** STM32F1 series. */ -#define STM32_SERIES_F1 0 -/** STM32F2 series. */ -#define STM32_SERIES_F2 1 -/** STM32L1 series. */ -#define STM32_SERIES_L1 2 -/** STM32F3 series. */ -#define STM32_SERIES_F3 3 -/** STM32F4 series. */ -#define STM32_SERIES_F4 4 - -/* The series header is responsible for defining: - * - * - Everything in the following __DOXYGEN__ conditional block. - * - * - STM32_HAVE_FSMC: 1 if the MCU has the FSMC peripheral, and 0 - * otherwise. - * - * - STM32_HAVE_USB: 1 if the MCU has a USB peripheral, and 0 - * otherwise. - */ -#include - -/* Ensure the series header isn't broken. */ -#if (!defined(STM32_PCLK1) || \ - !defined(STM32_PCLK2) || \ - !defined(STM32_MCU_SERIES) || \ - !defined(STM32_NR_INTERRUPTS) || \ - !defined(STM32_NR_GPIO_PORTS) || \ - !defined(STM32_TIMER_MASK) || \ - !defined(STM32_DELAY_US_MULT) || \ - !defined(STM32_SRAM_END) || \ - !defined(STM32_HAVE_DAC) || \ - !defined(STM32_HAVE_FSMC) || \ - !defined(STM32_HAVE_USB)) -#error "Bad STM32F1 configuration. Check header for your MCU." -#endif - -/* - * Derived macros - */ - -/* FIXME [0.0.13] add this to ReST API page */ -/** - * @brief Statically determine whether a timer is present. - * - * Given a constant timer number n (starting from 1), this macro has a - * nonzero value exactly when TIMERn is available. - */ -#define STM32_HAVE_TIMER(n) (STM32_TIMER_MASK & (1 << (n))) - -/* - * Doxygen for functionality provided by series header. - */ - -#ifdef __DOXYGEN__ - -/* - * Clock configuration. - * - * These defines depend upon how the MCU is configured. Because of - * the potential for a mismatch between them and the actual clock - * configuration, keep their number to a minimum. - */ - -/** - * @brief APB1 clock speed, in Hz. - */ -#define STM32_PCLK1 - -/** - * @brief APB2 clock speed, in Hz. - */ -#define STM32_PCLK2 - -/** @brief Deprecated. Use STM32_PCLK1 instead. */ -#define PCLK1 -/** @brief Deprecated. Use STM32_PCLK2 instead. */ -#define PCLK2 - -/* - * Series- and MCU-specific values. - */ - -/** - * @brief STM32 series value for the MCU being targeted. - * - * At time of writing, allowed values are: STM32_SERIES_F1, - * STM32_SERIES_F2. This set of values will expand as libmaple adds - * support for more STM32 series MCUs. - */ -#define STM32_MCU_SERIES - -/** - * @brief Number of interrupts in the vector table. - * - * This does not include Cortex-M interrupts (NMI, HardFault, etc.). - */ -#define STM32_NR_INTERRUPTS - -/** - * Number of GPIO ports. - */ -#define STM32_NR_GPIO_PORTS - -/* FIXME [0.0.13] add this to ReST API page */ -/** - * @brief Bitmask of timers available on the MCU. - * - * That is, if TIMERn is available, then STM32_TIMER_MASK & (1 << n) - * will be nonzero. For example, a nonzero value of "STM32_TIMER_MASK - * & 0x2" means TIMER1 is available. - * - * A bitmask is necessary as some STM32 MCUs have "holes" in the range - * of available timers. - */ -#define STM32_TIMER_MASK - -/** - * @brief Multiplier to convert microseconds into loop iterations - * in delay_us(). - * - * @see delay_us() - */ -#define STM32_DELAY_US_MULT - -/** - * @brief Pointer to end of built-in SRAM. - * - * Points to the address which is 1 byte past the last valid - * SRAM address. - */ -#define STM32_SRAM_END - -/** - * @brief 1 if the target MCU has a DAC, and 0 otherwise. - */ -#define STM32_HAVE_DAC - -/** - * @brief 1 if the target MCU has the FSMC peripheral, and 0 otherwise. - * - * Note that the feature set of the FSMC peripheral is restricted on - * some MCUs. - */ -#define STM32_HAVE_FSMC - -/** - * @brief 1 if the target MCU has a USB peripheral, and 0 otherwise. - * - * Note that a variety of USB peripherals are available across the - * different series, with widely varying feature sets and programming - * interfaces. This macro will be 1 if any such peripheral is present. - */ -#define STM32_HAVE_USB - -#endif /* __DOXYGEN__ */ - -/* - * The following are for backwards compatibility only. - */ - -/* PCLK1 and PCLK2 are for backwards compatibility only; don't use in - * new code. */ -#ifndef PCLK1 -#define PCLK1 STM32_PCLK1 -#endif -#if PCLK1 != STM32_PCLK1 -#error "PCLK1 (which is deprecated) differs from STM32_PCLK1." -#endif -#ifndef PCLK2 -#define PCLK2 STM32_PCLK2 -#endif -#if PCLK2 != STM32_PCLK2 -#error "PCLK2 (which is deprecated) differs from STM32_PCLK2." -#endif - -/** @brief Deprecated. Use STM32_NR_INTERRUPTS instead. */ -#define NR_INTERRUPTS STM32_NR_INTERRUPTS -/** @brief Deprecated. Use STM32_NR_GPIO_PORTS instead. */ -#define NR_GPIO_PORTS STM32_NR_GPIO_PORTS -/** @brief Deprecated. Use STM32_DELAY_US_MULT instead. */ -#define DELAY_US_MULT STM32_DELAY_US_MULT - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/syscfg.h b/STM32F3/cores/maple/libmaple/include/libmaple/syscfg.h deleted file mode 100644 index b8c901f85..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/syscfg.h +++ /dev/null @@ -1,116 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/syscfg.h - * @author F3-port by Hanspeter Portner - * @brief System configuration controller (SYSCFG) - * - * Availability: STM32F2, STM32F3, STM32F4. - */ - -#ifndef _LIBMAPLE_SYSCFG_H_ -#define _LIBMAPLE_SYSCFG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/* External interrupt configuration register 1 */ - -#define SYSCFG_EXTICR1_EXTI0 0xF -#define SYSCFG_EXTICR1_EXTI1 0xF0 -#define SYSCFG_EXTICR1_EXTI2 0xF00 -#define SYSCFG_EXTICR1_EXTI3 0xF000 - -/* External interrupt configuration register 2 */ - -#define SYSCFG_EXTICR2_EXTI4 0xF -#define SYSCFG_EXTICR2_EXTI5 0xF0 -#define SYSCFG_EXTICR2_EXTI6 0xF00 -#define SYSCFG_EXTICR2_EXTI7 0xF000 - -/* External interrupt configuration register 3 */ - -#define SYSCFG_EXTICR3_EXTI8 0xF -#define SYSCFG_EXTICR3_EXTI9 0xF0 -#define SYSCFG_EXTICR3_EXTI10 0xF00 -#define SYSCFG_EXTICR3_EXTI11 0xF000 - -/* External interrupt configuration register 4 */ - -#define SYSCFG_EXTICR4_EXTI12 0xF -#define SYSCFG_EXTICR4_EXTI13 0xF0 -#define SYSCFG_EXTICR4_EXTI14 0xF00 -#define SYSCFG_EXTICR4_EXTI15 0xF000 - -/* - * Routines - */ - -/** - * @brief Initialize the SYSCFG peripheral. - */ -void syscfg_init(void); - -/** - * @brief System memory mode - * These values specify what memory to map to address 0x00000000. - * @see syscfg_set_mem_mode - */ -typedef enum syscfg_mem_mode { - /** Main flash memory is mapped at 0x0. */ - SYSCFG_MEM_MODE_FLASH = 0x0, - /** System flash (i.e. ST's baked-in bootloader) is mapped at 0x0. */ - SYSCFG_MEM_MODE_SYSTEM_FLASH = 0x1, - /** FSMC bank 1 (NOR/PSRAM 1 and 2) is mapped at 0x0. */ - SYSCFG_MEM_MODE_FSMC_BANK_1 = 0x2, - /** Embedded SRAM (i.e., not backup SRAM) is mapped at 0x0. */ - SYSCFG_MEM_MODE_SRAM = 0x3, -} syscfg_mem_mode; - - -/** - * @brief Set the memory to be mapped at address 0x00000000. - * - * This function can be used to override the BOOT pin - * configuration. Some restrictions apply; see your chip's reference - * manual for the details. - * - * @param mode Mode to set - * @see syscfg_mem_mode - */ -void syscfg_set_mem_mode(syscfg_mem_mode); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/systick.h b/STM32F3/cores/maple/libmaple/include/libmaple/systick.h deleted file mode 100644 index 551f8000a..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/systick.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/systick.h - * @brief System timer definitions - */ - -#ifndef _LIBMAPLE_SYSTICK_H_ -#define _LIBMAPLE_SYSTICK_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include - -/** SysTick register map type */ -typedef struct systick_reg_map { - __io uint32 CSR; /**< Control and status register */ - __io uint32 RVR; /**< Reload value register */ - __io uint32 CNT; /**< Current value register ("count") */ - __io uint32 CVR; /**< Calibration value register */ -} systick_reg_map; - -/** SysTick register map base pointer */ -#define SYSTICK_BASE ((struct systick_reg_map*)0xE000E010) - -/* - * Register bit definitions. - */ - -/* Control and status register */ - -#define SYSTICK_CSR_COUNTFLAG BIT(16) -#define SYSTICK_CSR_CLKSOURCE BIT(2) -#define SYSTICK_CSR_CLKSOURCE_EXTERNAL 0 -#define SYSTICK_CSR_CLKSOURCE_CORE BIT(2) -#define SYSTICK_CSR_TICKINT BIT(1) -#define SYSTICK_CSR_TICKINT_PEND BIT(1) -#define SYSTICK_CSR_TICKINT_NO_PEND 0 -#define SYSTICK_CSR_ENABLE BIT(0) -#define SYSTICK_CSR_ENABLE_MULTISHOT BIT(0) -#define SYSTICK_CSR_ENABLE_DISABLED 0 - -/* Calibration value register */ - -#define SYSTICK_CVR_NOREF BIT(31) -#define SYSTICK_CVR_SKEW BIT(30) -#define SYSTICK_CVR_TENMS 0xFFFFFF - -/** System elapsed time, in milliseconds */ -extern volatile uint32 systick_uptime_millis; - -/** - * @brief Returns the system uptime, in milliseconds. - */ -static inline uint32 systick_uptime(void) { - return systick_uptime_millis; -} - - -void systick_init(uint32 reload_val); -void systick_disable(); -void systick_enable(); - -/** - * @brief Returns the current value of the SysTick counter. - */ -static inline uint32 systick_get_count(void) { - return SYSTICK_BASE->CNT; -} - -/** - * @brief Check for underflow. - * - * This function returns 1 if the SysTick timer has counted to 0 since - * the last time it was called. However, any reads of any part of the - * SysTick Control and Status Register SYSTICK_BASE->CSR will - * interfere with this functionality. See the ARM Cortex M3 Technical - * Reference Manual for more details (e.g. Table 8-3 in revision r1p1). - */ -static inline uint32 systick_check_underflow(void) { - return SYSTICK_BASE->CSR & SYSTICK_CSR_COUNTFLAG; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/timer.h b/STM32F3/cores/maple/libmaple/include/libmaple/timer.h deleted file mode 100644 index 9167f7d7e..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/timer.h +++ /dev/null @@ -1,1119 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/timer.h - * @author Marti Bolivar - * @brief Timer interface. - */ - -#ifndef _LIBMAPLE_TIMER_H_ -#define _LIBMAPLE_TIMER_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include -#include -#include -#include - -/* - * Register maps - */ - -/** Advanced control timer register map type */ -typedef struct timer_adv_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SMCR; /**< Slave mode control register */ - __io uint32 DIER; /**< DMA/interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - __io uint32 CCMR1; /**< Capture/compare mode register 1 */ - __io uint32 CCMR2; /**< Capture/compare mode register 2 */ - __io uint32 CCER; /**< Capture/compare enable register */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ - __io uint32 RCR; /**< Repetition counter register */ - __io uint32 CCR1; /**< Capture/compare register 1 */ - __io uint32 CCR2; /**< Capture/compare register 2 */ - __io uint32 CCR3; /**< Capture/compare register 3 */ - __io uint32 CCR4; /**< Capture/compare register 4 */ - __io uint32 BDTR; /**< Break and dead-time register */ - __io uint32 DCR; /**< DMA control register */ - __io uint32 DMAR; /**< DMA address for full transfer */ -} timer_adv_reg_map; - -/* General purpose timer register map type: intentionally omitted. - * - * General purpose timers differ slightly across series, so leave it - * up to the series header to define struct timer_gen_reg_map. */ - -/** Basic timer register map type */ -typedef struct timer_bas_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - const uint32 RESERVED1; /**< Reserved */ - __io uint32 DIER; /**< DMA/interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - const uint32 RESERVED2; /**< Reserved */ - const uint32 RESERVED3; /**< Reserved */ - const uint32 RESERVED4; /**< Reserved */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ -} timer_bas_reg_map; - -/* - * Timer devices - */ - -/** - * @brief Timer register map type. - * - * Just holds a pointer to the correct type of register map, based on - * the timer's type. - */ -typedef union timer_reg_map { - timer_adv_reg_map *adv; /**< Advanced register map */ - timer_gen_reg_map *gen; /**< General purpose register map */ - timer_bas_reg_map *bas; /**< Basic register map */ -} timer_reg_map; - -/** - * @brief Timer type - * - * Type marker for timer_dev. - * - * @see timer_dev - */ -typedef enum timer_type { - TIMER_ADVANCED, /**< Advanced type */ - TIMER_GENERAL, /**< General purpose type */ - TIMER_BASIC, /**< Basic type */ -} timer_type; - -/** Timer device type */ -typedef struct timer_dev { - timer_reg_map regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ - timer_type type; /**< Timer's type */ - voidFuncPtr handlers[]; /**< - * Don't touch these. Use these instead: - * @see timer_attach_interrupt() - * @see timer_detach_interrupt() */ -} timer_dev; - -#if STM32_HAVE_TIMER(1) -extern timer_dev *TIMER1; -#endif -#if STM32_HAVE_TIMER(2) -extern timer_dev *TIMER2; -#endif -#if STM32_HAVE_TIMER(3) -extern timer_dev *TIMER3; -#endif -#if STM32_HAVE_TIMER(4) -extern timer_dev *TIMER4; -#endif -#if STM32_HAVE_TIMER(5) -extern timer_dev *TIMER5; -#endif -#if STM32_HAVE_TIMER(6) -extern timer_dev *TIMER6; -#endif -#if STM32_HAVE_TIMER(7) -extern timer_dev *TIMER7; -#endif -#if STM32_HAVE_TIMER(8) -extern timer_dev *TIMER8; -#endif -#if STM32_HAVE_TIMER(9) -extern timer_dev *TIMER9; -#endif -#if STM32_HAVE_TIMER(10) -extern timer_dev *TIMER10; -#endif -#if STM32_HAVE_TIMER(11) -extern timer_dev *TIMER11; -#endif -#if STM32_HAVE_TIMER(12) -extern timer_dev *TIMER12; -#endif -#if STM32_HAVE_TIMER(13) -extern timer_dev *TIMER13; -#endif -#if STM32_HAVE_TIMER(14) -extern timer_dev *TIMER14; -#endif -#if STM32_HAVE_TIMER(15) -extern timer_dev *TIMER15; -#endif -#if STM32_HAVE_TIMER(16) -extern timer_dev *TIMER16; -#endif -#if STM32_HAVE_TIMER(17) -extern timer_dev *TIMER17; -#endif - -/* - * Register bit definitions - */ - -/* Control register 1 (CR1) */ - -#define TIMER_CR1_ARPE_BIT 7 -#define TIMER_CR1_DIR_BIT 4 -#define TIMER_CR1_OPM_BIT 3 -#define TIMER_CR1_URS_BIT 2 -#define TIMER_CR1_UDIS_BIT 1 -#define TIMER_CR1_CEN_BIT 0 - -#define TIMER_CR1_CKD (0x3 << 8) -#define TIMER_CR1_CKD_1TCKINT (0x0 << 8) -#define TIMER_CR1_CKD_2TCKINT (0x1 << 8) -#define TIMER_CR1_CKD_4TICKINT (0x2 << 8) -#define TIMER_CR1_ARPE (1U << TIMER_CR1_ARPE_BIT) -#define TIMER_CR1_CKD_CMS (0x3 << 5) -#define TIMER_CR1_CKD_CMS_EDGE (0x0 << 5) -#define TIMER_CR1_CKD_CMS_CENTER1 (0x1 << 5) -#define TIMER_CR1_CKD_CMS_CENTER2 (0x2 << 5) -#define TIMER_CR1_CKD_CMS_CENTER3 (0x3 << 5) -#define TIMER_CR1_DIR (1U << TIMER_CR1_DIR_BIT) -#define TIMER_CR1_OPM (1U << TIMER_CR1_OPM_BIT) -#define TIMER_CR1_URS (1U << TIMER_CR1_URS_BIT) -#define TIMER_CR1_UDIS (1U << TIMER_CR1_UDIS_BIT) -#define TIMER_CR1_CEN (1U << TIMER_CR1_CEN_BIT) - -/* Control register 2 (CR2) */ - -#define TIMER_CR2_OIS4_BIT 14 -#define TIMER_CR2_OIS3N_BIT 13 -#define TIMER_CR2_OIS3_BIT 12 -#define TIMER_CR2_OIS2N_BIT 11 -#define TIMER_CR2_OIS2_BIT 10 -#define TIMER_CR2_OIS1N_BIT 9 -#define TIMER_CR2_OIS1_BIT 8 -#define TIMER_CR2_TI1S_BIT 7 -#define TIMER_CR2_CCDS_BIT 3 -#define TIMER_CR2_CCUS_BIT 2 -#define TIMER_CR2_CCPC_BIT 0 - -#define TIMER_CR2_OIS4 (1U << TIMER_CR2_OIS4_BIT) -#define TIMER_CR2_OIS3N (1U << TIMER_CR2_OIS3N_BIT) -#define TIMER_CR2_OIS3 (1U << TIMER_CR2_OIS3_BIT) -#define TIMER_CR2_OIS2N (1U << TIMER_CR2_OIS2N_BIT) -#define TIMER_CR2_OIS2 (1U << TIMER_CR2_OIS2_BIT) -#define TIMER_CR2_OIS1N (1U << TIMER_CR2_OIS1N_BIT) -#define TIMER_CR2_OIS1 (1U << TIMER_CR2_OIS1_BIT) -#define TIMER_CR2_TI1S (1U << TIMER_CR2_TI1S_BIT) -#define TIMER_CR2_MMS (0x7 << 4) -#define TIMER_CR2_MMS_RESET (0x0 << 4) -#define TIMER_CR2_MMS_ENABLE (0x1 << 4) -#define TIMER_CR2_MMS_UPDATE (0x2 << 4) -#define TIMER_CR2_MMS_COMPARE_PULSE (0x3 << 4) -#define TIMER_CR2_MMS_COMPARE_OC1REF (0x4 << 4) -#define TIMER_CR2_MMS_COMPARE_OC2REF (0x5 << 4) -#define TIMER_CR2_MMS_COMPARE_OC3REF (0x6 << 4) -#define TIMER_CR2_MMS_COMPARE_OC4REF (0x7 << 4) -#define TIMER_CR2_CCDS (1U << TIMER_CR2_CCDS_BIT) -#define TIMER_CR2_CCUS (1U << TIMER_CR2_CCUS_BIT) -#define TIMER_CR2_CCPC (1U << TIMER_CR2_CCPC_BIT) - -/* Slave mode control register (SMCR) */ - -#define TIMER_SMCR_ETP_BIT 15 -#define TIMER_SMCR_ECE_BIT 14 -#define TIMER_SMCR_MSM_BIT 7 - -#define TIMER_SMCR_ETP (1U << TIMER_SMCR_ETP_BIT) -#define TIMER_SMCR_ECE (1U << TIMER_SMCR_ECE_BIT) -#define TIMER_SMCR_ETPS (0x3 << 12) -#define TIMER_SMCR_ETPS_OFF (0x0 << 12) -#define TIMER_SMCR_ETPS_DIV2 (0x1 << 12) -#define TIMER_SMCR_ETPS_DIV4 (0x2 << 12) -#define TIMER_SMCR_ETPS_DIV8 (0x3 << 12) -#define TIMER_SMCR_ETF (0xF << 12) -#define TIMER_SMCR_MSM (1U << TIMER_SMCR_MSM_BIT) -#define TIMER_SMCR_TS (0x3 << 4) -#define TIMER_SMCR_TS_ITR0 (0x0 << 4) -#define TIMER_SMCR_TS_ITR1 (0x1 << 4) -#define TIMER_SMCR_TS_ITR2 (0x2 << 4) -#define TIMER_SMCR_TS_ITR3 (0x3 << 4) -#define TIMER_SMCR_TS_TI1F_ED (0x4 << 4) -#define TIMER_SMCR_TS_TI1FP1 (0x5 << 4) -#define TIMER_SMCR_TS_TI2FP2 (0x6 << 4) -#define TIMER_SMCR_TS_ETRF (0x7 << 4) -#define TIMER_SMCR_SMS 0x3 -#define TIMER_SMCR_SMS_DISABLED 0x0 -#define TIMER_SMCR_SMS_ENCODER1 0x1 -#define TIMER_SMCR_SMS_ENCODER2 0x2 -#define TIMER_SMCR_SMS_ENCODER3 0x3 -#define TIMER_SMCR_SMS_RESET 0x4 -#define TIMER_SMCR_SMS_GATED 0x5 -#define TIMER_SMCR_SMS_TRIGGER 0x6 -#define TIMER_SMCR_SMS_EXTERNAL 0x7 - -/* DMA/Interrupt enable register (DIER) */ - -#define TIMER_DIER_TDE_BIT 14 -#define TIMER_DIER_COMDE_BIT 13 -#define TIMER_DIER_CC4DE_BIT 12 -#define TIMER_DIER_CC3DE_BIT 11 -#define TIMER_DIER_CC2DE_BIT 10 -#define TIMER_DIER_CC1DE_BIT 9 -#define TIMER_DIER_UDE_BIT 8 -#define TIMER_DIER_BIE_BIT 7 -#define TIMER_DIER_TIE_BIT 6 -#define TIMER_DIER_COMIE_BIT 5 -#define TIMER_DIER_CC4IE_BIT 4 -#define TIMER_DIER_CC3IE_BIT 3 -#define TIMER_DIER_CC2IE_BIT 2 -#define TIMER_DIER_CC1IE_BIT 1 -#define TIMER_DIER_UIE_BIT 0 - -#define TIMER_DIER_TDE (1U << TIMER_DIER_TDE_BIT) -#define TIMER_DIER_COMDE (1U << TIMER_DIER_COMDE_BIT) -#define TIMER_DIER_CC4DE (1U << TIMER_DIER_CC4DE_BIT) -#define TIMER_DIER_CC3DE (1U << TIMER_DIER_CC3DE_BIT) -#define TIMER_DIER_CC2DE (1U << TIMER_DIER_CC2DE_BIT) -#define TIMER_DIER_CC1DE (1U << TIMER_DIER_CC1DE_BIT) -#define TIMER_DIER_UDE (1U << TIMER_DIER_UDE_BIT) -#define TIMER_DIER_BIE (1U << TIMER_DIER_BIE_BIT) -#define TIMER_DIER_TIE (1U << TIMER_DIER_TIE_BIT) -#define TIMER_DIER_COMIE (1U << TIMER_DIER_COMIE_BIT) -#define TIMER_DIER_CC4IE (1U << TIMER_DIER_CC4IE_BIT) -#define TIMER_DIER_CC3IE (1U << TIMER_DIER_CC3IE_BIT) -#define TIMER_DIER_CC2IE (1U << TIMER_DIER_CC2IE_BIT) -#define TIMER_DIER_CC1IE (1U << TIMER_DIER_CC1IE_BIT) -#define TIMER_DIER_UIE (1U << TIMER_DIER_UIE_BIT) - -/* Status register (SR) */ - -#define TIMER_SR_CC4OF_BIT 12 -#define TIMER_SR_CC3OF_BIT 11 -#define TIMER_SR_CC2OF_BIT 10 -#define TIMER_SR_CC1OF_BIT 9 -#define TIMER_SR_BIF_BIT 7 -#define TIMER_SR_TIF_BIT 6 -#define TIMER_SR_COMIF_BIT 5 -#define TIMER_SR_CC4IF_BIT 4 -#define TIMER_SR_CC3IF_BIT 3 -#define TIMER_SR_CC2IF_BIT 2 -#define TIMER_SR_CC1IF_BIT 1 -#define TIMER_SR_UIF_BIT 0 - -#define TIMER_SR_CC4OF (1U << TIMER_SR_CC4OF_BIT) -#define TIMER_SR_CC3OF (1U << TIMER_SR_CC3OF_BIT) -#define TIMER_SR_CC2OF (1U << TIMER_SR_CC2OF_BIT) -#define TIMER_SR_CC1OF (1U << TIMER_SR_CC1OF_BIT) -#define TIMER_SR_BIF (1U << TIMER_SR_BIF_BIT) -#define TIMER_SR_TIF (1U << TIMER_SR_TIF_BIT) -#define TIMER_SR_COMIF (1U << TIMER_SR_COMIF_BIT) -#define TIMER_SR_CC4IF (1U << TIMER_SR_CC4IF_BIT) -#define TIMER_SR_CC3IF (1U << TIMER_SR_CC3IF_BIT) -#define TIMER_SR_CC2IF (1U << TIMER_SR_CC2IF_BIT) -#define TIMER_SR_CC1IF (1U << TIMER_SR_CC1IF_BIT) -#define TIMER_SR_UIF (1U << TIMER_SR_UIF_BIT) - -/* Event generation register (EGR) */ - -#define TIMER_EGR_BG_BIT 7 -#define TIMER_EGR_TG_BIT 6 -#define TIMER_EGR_COMG_BIT 5 -#define TIMER_EGR_CC4G_BIT 4 -#define TIMER_EGR_CC3G_BIT 3 -#define TIMER_EGR_CC2G_BIT 2 -#define TIMER_EGR_CC1G_BIT 1 -#define TIMER_EGR_UG_BIT 0 - -#define TIMER_EGR_BG (1U << TIMER_EGR_BG_BIT) -#define TIMER_EGR_TG (1U << TIMER_EGR_TG_BIT) -#define TIMER_EGR_COMG (1U << TIMER_EGR_COMG_BIT) -#define TIMER_EGR_CC4G (1U << TIMER_EGR_CC4G_BIT) -#define TIMER_EGR_CC3G (1U << TIMER_EGR_CC3G_BIT) -#define TIMER_EGR_CC2G (1U << TIMER_EGR_CC2G_BIT) -#define TIMER_EGR_CC1G (1U << TIMER_EGR_CC1G_BIT) -#define TIMER_EGR_UG (1U << TIMER_EGR_UG_BIT) - -/* Capture/compare mode registers, common values */ - -#define TIMER_CCMR_CCS_OUTPUT 0x0 -#define TIMER_CCMR_CCS_INPUT_TI1 0x1 -#define TIMER_CCMR_CCS_INPUT_TI2 0x2 -#define TIMER_CCMR_CCS_INPUT_TRC 0x3 - -/* Capture/compare mode register 1 (CCMR1) */ - -#define TIMER_CCMR1_OC2CE_BIT 15 -#define TIMER_CCMR1_OC2PE_BIT 11 -#define TIMER_CCMR1_OC2FE_BIT 10 -#define TIMER_CCMR1_OC1CE_BIT 7 -#define TIMER_CCMR1_OC1PE_BIT 3 -#define TIMER_CCMR1_OC1FE_BIT 2 - -#define TIMER_CCMR1_OC2CE (1U << TIMER_CCMR1_OC2CE_BIT) -#define TIMER_CCMR1_OC2M (0x3 << 12) -#define TIMER_CCMR1_IC2F (0xF << 12) -#define TIMER_CCMR1_OC2PE (1U << TIMER_CCMR1_OC2PE_BIT) -#define TIMER_CCMR1_OC2FE (1U << TIMER_CCMR1_OC2FE_BIT) -#define TIMER_CCMR1_IC2PSC (0x3 << 10) -#define TIMER_CCMR1_CC2S (0x3 << 8) -#define TIMER_CCMR1_CC2S_OUTPUT (TIMER_CCMR_CCS_OUTPUT << 8) -#define TIMER_CCMR1_CC2S_INPUT_TI1 (TIMER_CCMR_CCS_INPUT_TI1 << 8) -#define TIMER_CCMR1_CC2S_INPUT_TI2 (TIMER_CCMR_CCS_INPUT_TI2 << 8) -#define TIMER_CCMR1_CC2S_INPUT_TRC (TIMER_CCMR_CCS_INPUT_TRC << 8) -#define TIMER_CCMR1_OC1CE (1U << TIMER_CCMR1_OC1CE_BIT) -#define TIMER_CCMR1_OC1M (0x3 << 4) -#define TIMER_CCMR1_IC1F (0xF << 4) -#define TIMER_CCMR1_OC1PE (1U << TIMER_CCMR1_OC1PE_BIT) -#define TIMER_CCMR1_OC1FE (1U << TIMER_CCMR1_OC1FE_BIT) -#define TIMER_CCMR1_IC1PSC (0x3 << 2) -#define TIMER_CCMR1_CC1S 0x3 -#define TIMER_CCMR1_CC1S_OUTPUT TIMER_CCMR_CCS_OUTPUT -#define TIMER_CCMR1_CC1S_INPUT_TI1 TIMER_CCMR_CCS_INPUT_TI1 -#define TIMER_CCMR1_CC1S_INPUT_TI2 TIMER_CCMR_CCS_INPUT_TI2 -#define TIMER_CCMR1_CC1S_INPUT_TRC TIMER_CCMR_CCS_INPUT_TRC - -/* Capture/compare mode register 2 (CCMR2) */ - -#define TIMER_CCMR2_OC4CE_BIT 15 -#define TIMER_CCMR2_OC4PE_BIT 11 -#define TIMER_CCMR2_OC4FE_BIT 10 -#define TIMER_CCMR2_OC3CE_BIT 7 -#define TIMER_CCMR2_OC3PE_BIT 3 -#define TIMER_CCMR2_OC3FE_BIT 2 - -#define TIMER_CCMR2_OC4CE (1U << TIMER_CCMR2_OC4CE_BIT) -#define TIMER_CCMR2_OC4M (0x3 << 12) -#define TIMER_CCMR2_IC4F (0xF << 12) -#define TIMER_CCMR2_OC4PE (1U << TIMER_CCMR2_OC4PE_BIT) -#define TIMER_CCMR2_OC4FE (1U << TIMER_CCMR2_OC4FE_BIT) -#define TIMER_CCMR2_IC4PSC (0x3 << 10) -#define TIMER_CCMR2_CC4S (0x3 << 8) -#define TIMER_CCMR2_CC4S_OUTPUT (TIMER_CCMR_CCS_OUTPUT << 8) -#define TIMER_CCMR2_CC4S_INPUT_TI1 (TIMER_CCMR_CCS_INPUT_TI1 << 8) -#define TIMER_CCMR2_CC4S_INPUT_TI2 (TIMER_CCMR_CCS_INPUT_TI2 << 8) -#define TIMER_CCMR2_CC4S_INPUT_TRC (TIMER_CCMR_CCS_INPUT_TRC << 8) -#define TIMER_CCMR2_OC3CE (1U << TIMER_CCMR2_OC3CE_BIT) -#define TIMER_CCMR2_OC3M (0x3 << 4) -#define TIMER_CCMR2_IC3F (0xF << 4) -#define TIMER_CCMR2_OC3PE (1U << TIMER_CCMR2_OC3PE_BIT) -#define TIMER_CCMR2_OC3FE (1U << TIMER_CCMR2_OC3FE_BIT) -#define TIMER_CCMR2_IC3PSC (0x3 << 2) -#define TIMER_CCMR2_CC3S 0x3 -#define TIMER_CCMR2_CC3S_OUTPUT TIMER_CCMR_CCS_OUTPUT -#define TIMER_CCMR2_CC3S_INPUT_TI1 TIMER_CCMR_CCS_INPUT_TI1 -#define TIMER_CCMR2_CC3S_INPUT_TI2 TIMER_CCMR_CCS_INPUT_TI2 -#define TIMER_CCMR2_CC3S_INPUT_TRC TIMER_CCMR_CCS_INPUT_TRC - -/* Capture/compare enable register (CCER) */ - -#define TIMER_CCER_CC4P_BIT 13 -#define TIMER_CCER_CC4E_BIT 12 -#define TIMER_CCER_CC3NP_BIT 11 -#define TIMER_CCER_CC3NE_BIT 10 -#define TIMER_CCER_CC3P_BIT 9 -#define TIMER_CCER_CC3E_BIT 8 -#define TIMER_CCER_CC2NP_BIT 7 -#define TIMER_CCER_CC2NE_BIT 6 -#define TIMER_CCER_CC2P_BIT 5 -#define TIMER_CCER_CC2E_BIT 4 -#define TIMER_CCER_CC1NP_BIT 3 -#define TIMER_CCER_CC1NE_BIT 2 -#define TIMER_CCER_CC1P_BIT 1 -#define TIMER_CCER_CC1E_BIT 0 - -#define TIMER_CCER_CC4P (1U << TIMER_CCER_CC4P_BIT) -#define TIMER_CCER_CC4E (1U << TIMER_CCER_CC4E_BIT) -#define TIMER_CCER_CC3NP (1U << TIMER_CCER_CC3NP_BIT) -#define TIMER_CCER_CC3NE (1U << TIMER_CCER_CC3NE_BIT) -#define TIMER_CCER_CC3P (1U << TIMER_CCER_CC3P_BIT) -#define TIMER_CCER_CC3E (1U << TIMER_CCER_CC3E_BIT) -#define TIMER_CCER_CC2NP (1U << TIMER_CCER_CC2NP_BIT) -#define TIMER_CCER_CC2NE (1U << TIMER_CCER_CC2NE_BIT) -#define TIMER_CCER_CC2P (1U << TIMER_CCER_CC2P_BIT) -#define TIMER_CCER_CC2E (1U << TIMER_CCER_CC2E_BIT) -#define TIMER_CCER_CC1NP (1U << TIMER_CCER_CC1NP_BIT) -#define TIMER_CCER_CC1NE (1U << TIMER_CCER_CC1NE_BIT) -#define TIMER_CCER_CC1P (1U << TIMER_CCER_CC1P_BIT) -#define TIMER_CCER_CC1E (1U << TIMER_CCER_CC1E_BIT) - -/* Break and dead-time register (BDTR) */ - -#define TIMER_BDTR_MOE_BIT 15 -#define TIMER_BDTR_AOE_BIT 14 -#define TIMER_BDTR_BKP_BIT 13 -#define TIMER_BDTR_BKE_BIT 12 -#define TIMER_BDTR_OSSR_BIT 11 -#define TIMER_BDTR_OSSI_BIT 10 - -#define TIMER_BDTR_MOE (1U << TIMER_BDTR_MOE_BIT) -#define TIMER_BDTR_AOE (1U << TIMER_BDTR_AOE_BIT) -#define TIMER_BDTR_BKP (1U << TIMER_BDTR_BKP_BIT) -#define TIMER_BDTR_BKE (1U << TIMER_BDTR_BKE_BIT) -#define TIMER_BDTR_OSSR (1U << TIMER_BDTR_OSSR_BIT) -#define TIMER_BDTR_OSSI (1U << TIMER_BDTR_OSSI_BIT) -#define TIMER_BDTR_LOCK (0x3 << 8) -#define TIMER_BDTR_LOCK_OFF (0x0 << 8) -#define TIMER_BDTR_LOCK_LEVEL1 (0x1 << 8) -#define TIMER_BDTR_LOCK_LEVEL2 (0x2 << 8) -#define TIMER_BDTR_LOCK_LEVEL3 (0x3 << 8) -#define TIMER_BDTR_DTG 0xFF - -/* DMA control register (DCR) */ - -#define TIMER_DCR_DBL (0x1F << 8) -#define TIMER_DCR_DBL_1_XFER (0x0 << 8) -#define TIMER_DCR_DBL_2_XFER (0x1 << 8) -#define TIMER_DCR_DBL_3_XFER (0x2 << 8) -#define TIMER_DCR_DBL_4_XFER (0x3 << 8) -#define TIMER_DCR_DBL_5_XFER (0x4 << 8) -#define TIMER_DCR_DBL_6_XFER (0x5 << 8) -#define TIMER_DCR_DBL_7_XFER (0x6 << 8) -#define TIMER_DCR_DBL_8_XFER (0x7 << 8) -#define TIMER_DCR_DBL_9_XFER (0x8 << 8) -#define TIMER_DCR_DBL_10_XFER (0x9 << 8) -#define TIMER_DCR_DBL_11_XFER (0xA << 8) -#define TIMER_DCR_DBL_12_XFER (0xB << 8) -#define TIMER_DCR_DBL_13_XFER (0xC << 8) -#define TIMER_DCR_DBL_14_XFER (0xD << 8) -#define TIMER_DCR_DBL_15_XFER (0xE << 8) -#define TIMER_DCR_DBL_16_XFER (0xF << 8) -#define TIMER_DCR_DBL_17_XFER (0x10 << 8) -#define TIMER_DCR_DBL_18_XFER (0x11 << 8) -#define TIMER_DCR_DBA 0x1F -#define TIMER_DCR_DBA_CR1 0x0 -#define TIMER_DCR_DBA_CR2 0x1 -#define TIMER_DCR_DBA_SMCR 0x2 -#define TIMER_DCR_DBA_DIER 0x3 -#define TIMER_DCR_DBA_SR 0x4 -#define TIMER_DCR_DBA_EGR 0x5 -#define TIMER_DCR_DBA_CCMR1 0x6 -#define TIMER_DCR_DBA_CCMR2 0x7 -#define TIMER_DCR_DBA_CCER 0x8 -#define TIMER_DCR_DBA_CNT 0x9 -#define TIMER_DCR_DBA_PSC 0xA -#define TIMER_DCR_DBA_ARR 0xB -#define TIMER_DCR_DBA_RCR 0xC -#define TIMER_DCR_DBA_CCR1 0xD -#define TIMER_DCR_DBA_CCR2 0xE -#define TIMER_DCR_DBA_CCR3 0xF -#define TIMER_DCR_DBA_CCR4 0x10 -#define TIMER_DCR_DBA_BDTR 0x11 -#define TIMER_DCR_DBA_DCR 0x12 -#define TIMER_DCR_DBA_DMAR 0x13 - -/* - * Convenience routines - */ - -/** - * @brief Used to configure the behavior of a timer channel. - * - * Be careful: not all timers can be configured in every mode. - */ -typedef enum timer_mode { - /** - * The timer stops counting, channel interrupts are detached, and - * no state changes are output. */ - TIMER_DISABLED, - - /** PWM output. */ - TIMER_PWM, - - /* TIMER_PWM_CENTER_ALIGNED, TODO: Center-aligned PWM output mode. */ - - /** - * The timer counts from 0 to its reload value repeatedly; every - * time the counter value reaches one of the channel compare - * values, the corresponding interrupt is fired. */ - TIMER_OUTPUT_COMPARE, - - /* TIMER_INPUT_CAPTURE, TODO: In this mode, the timer can measure the - * pulse lengths of input signals */ - /* TIMER_ONE_PULSE, TODO: In this mode, the timer can generate a single - * pulse on a GPIO pin for a specified amount of - * time. */ -} timer_mode; - -/** Timer channel numbers */ -typedef enum timer_channel { - TIMER_CH1 = 1, /**< Channel 1 */ - TIMER_CH2 = 2, /**< Channel 2 */ - TIMER_CH3 = 3, /**< Channel 3 */ - TIMER_CH4 = 4 /**< Channel 4 */ -} timer_channel; - -/* - * Note: Don't require timer_channel arguments! We want to be able to say - * - * for (int channel = 1; channel <= 4; channel++) { - * ... - * } - * - * without the compiler yelling at us. - */ - -void timer_init(timer_dev *dev); -void timer_disable(timer_dev *dev); -void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode); -void timer_foreach(void (*fn)(timer_dev*)); -int timer_has_cc_channel(timer_dev *dev, uint8 channel); - -/** - * @brief Timer interrupt number. - * - * Not all timers support all of these values. All timers support - * TIMER_UPDATE_INTERRUPT. "General purpose" timers can be a special - * nuisance in this regard, as they individually support different - * subsets of the available interupts. Consult your target's reference - * manual for the details. - */ -typedef enum timer_interrupt_id { - TIMER_UPDATE_INTERRUPT, /**< Update interrupt. */ - TIMER_CC1_INTERRUPT, /**< Capture/compare 1 interrupt. */ - TIMER_CC2_INTERRUPT, /**< Capture/compare 2 interrupt. */ - TIMER_CC3_INTERRUPT, /**< Capture/compare 3 interrupt. */ - TIMER_CC4_INTERRUPT, /**< Capture/compare 4 interrupt. */ - TIMER_COM_INTERRUPT, /**< COM interrupt. */ - TIMER_TRG_INTERRUPT, /**< Trigger interrupt. */ - TIMER_BREAK_INTERRUPT, /**< Break interrupt. */ -} timer_interrupt_id; - -void timer_attach_interrupt(timer_dev *dev, - uint8 interrupt, - voidFuncPtr handler); -void timer_detach_interrupt(timer_dev *dev, uint8 interrupt); - -/** - * Initialize all timer devices on the chip. - */ -static inline void timer_init_all(void) { - timer_foreach(timer_init); -} - -/** - * Disables all timers on the device. - */ -static inline void timer_disable_all(void) { - timer_foreach(timer_disable); -} - -/** - * @brief Stop a timer's counter from changing. - * - * Does not affect the timer's mode or other settings. - * - * @param dev Device whose counter to pause. - */ -static inline void timer_pause(timer_dev *dev) { - *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 0; -} - -/** - * @brief Start a timer's counter. - * - * Does not affect the timer's mode or other settings. - * - * @param dev Device whose counter to resume - */ -static inline void timer_resume(timer_dev *dev) { - *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 1; -} - -/** - * @brief Returns the timer's counter value. - * - * This value is likely to be inaccurate if the counter is running - * with a low prescaler. - * - * @param dev Timer whose counter to return - */ -static inline uint16 timer_get_count(timer_dev *dev) { - return (uint16)(dev->regs).bas->CNT; -} - -/** - * @brief Sets the counter value for the given timer. - * @param dev Timer whose counter to set - * @param value New counter value - */ -static inline void timer_set_count(timer_dev *dev, uint16 value) { - (dev->regs).bas->CNT = value; -} - -/** - * @brief Returns the given timer's prescaler. - * - * Note that if the timer's prescaler is set (e.g. via - * timer_set_prescaler() or accessing a TIMx_PSC register), the value - * returned by this function will reflect the new setting, but the - * timer's counter will only reflect the new prescaler at the next - * update event. - * - * @param dev Timer whose prescaler to return - * @see timer_generate_update() - */ -static inline uint16 timer_get_prescaler(timer_dev *dev) { - return (uint16)(dev->regs).bas->PSC; -} - -/** - * @brief Set a timer's prescale value. - * - * Divides the input clock by (PSC+1). The new value will not take - * effect until the next update event. - * - * @param dev Timer whose prescaler to set - * @param psc New prescaler value - * @see timer_generate_update() - */ -static inline void timer_set_prescaler(timer_dev *dev, uint16 psc) { - (dev->regs).bas->PSC = psc; -} - -/** - * @brief Returns a timer's reload value. - * @param dev Timer whose reload value to return - */ -static inline uint16 timer_get_reload(timer_dev *dev) { - return (uint16)(dev->regs).bas->ARR; -} - -/** - * @brief Set a timer's reload value. - * @param dev Timer whose reload value to set - * @param arr New reload value to use. Takes effect at next update event. - * @see timer_generate_update() - */ -static inline void timer_set_reload(timer_dev *dev, uint16 arr) { - (dev->regs).bas->ARR = arr; -} - -/** - * @brief Get the compare value for the given timer channel. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel whose compare value to get. - */ -static inline uint16 timer_get_compare(timer_dev *dev, uint8 channel) { - __io uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); - return *ccr; -} - -/** - * @brief Set the compare value for the given timer channel. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel whose compare value to set. - * @param value New compare value. - */ -static inline void timer_set_compare(timer_dev *dev, - uint8 channel, - uint16 value) { - __io uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); - *ccr = value; -} - -/** - * @brief Generate an update event for the given timer. - * - * Normally, this will cause the prescaler and auto-reload values in - * the PSC and ARR registers to take immediate effect. However, this - * function will do nothing if the UDIS bit is set in the timer's CR1 - * register (UDIS is cleared by default). - * - * @param dev Timer device to generate an update for. - */ -static inline void timer_generate_update(timer_dev *dev) { - *bb_perip(&(dev->regs).bas->EGR, TIMER_EGR_UG_BIT) = 1; -} - -/** - * @brief Enable a timer's trigger DMA request - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL - */ -static inline void timer_dma_enable_trg_req(timer_dev *dev) { - *bb_perip(&(dev->regs).gen->DIER, TIMER_DIER_TDE_BIT) = 1; -} - -/** - * @brief Disable a timer's trigger DMA request - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL - */ -static inline void timer_dma_disable_trg_req(timer_dev *dev) { - *bb_perip(&(dev->regs).gen->DIER, TIMER_DIER_TDE_BIT) = 0; -} - -/** - * @brief Enable a timer channel's DMA request. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL - * @param channel Channel whose DMA request to enable. - */ -static inline void timer_dma_enable_req(timer_dev *dev, uint8 channel) { - *bb_perip(&(dev->regs).gen->DIER, channel + 8) = 1; -} - -/** - * @brief Disable a timer channel's DMA request. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel whose DMA request to disable. - */ -static inline void timer_dma_disable_req(timer_dev *dev, uint8 channel) { - *bb_perip(&(dev->regs).gen->DIER, channel + 8) = 0; -} - -/** - * @brief Enable a timer interrupt. - * @param dev Timer device. - * @param interrupt Interrupt number to enable; this may be any - * timer_interrupt_id value appropriate for the timer. - * @see timer_interrupt_id - * @see timer_channel - */ -static inline void timer_enable_irq(timer_dev *dev, uint8 interrupt) { - *bb_perip(&(dev->regs).adv->DIER, interrupt) = 1; -} - -/** - * @brief Disable a timer interrupt. - * @param dev Timer device. - * @param interrupt Interrupt number to disable; this may be any - * timer_interrupt_id value appropriate for the timer. - * @see timer_interrupt_id - * @see timer_channel - */ -static inline void timer_disable_irq(timer_dev *dev, uint8 interrupt) { - *bb_perip(&(dev->regs).adv->DIER, interrupt) = 0; -} - -/** - * @brief Enable a timer channel's capture/compare signal. - * - * If the channel is configured as output, the corresponding output - * compare signal will be output on the corresponding output pin. If - * the channel is configured as input, enables capture of the counter - * value into the input capture/compare register. - * - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel to enable, from 1 to 4. - */ -static inline void timer_cc_enable(timer_dev *dev, uint8 channel) { - *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1)) = 1; -} - -/** - * @brief Disable a timer channel's output compare or input capture signal. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel to disable, from 1 to 4. - * @see timer_cc_enable() - */ -static inline void timer_cc_disable(timer_dev *dev, uint8 channel) { - *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1)) = 0; -} - -/** - * @brief Get a channel's capture/compare output polarity - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel whose capture/compare output polarity to get. - * @return Polarity, either 0 or 1. - * @see timer_cc_set_polarity() - */ -static inline uint8 timer_cc_get_pol(timer_dev *dev, uint8 channel) { - return *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1) + 1); -} - -/** - * @brief Set a timer channel's capture/compare output polarity. - * - * If the timer channel is configured as output: polarity == 0 means - * the output channel will be active high; polarity == 1 means active - * low. - * - * If the timer channel is configured as input: polarity == 0 means - * capture is done on the rising edge of ICn; when used as an external - * trigger, ICn is non-inverted. polarity == 1 means capture is done - * on the falling edge of ICn; when used as an external trigger, ICn - * is inverted. - * - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel whose capture/compare output polarity to set. - * @param pol New polarity, 0 or 1. - */ -static inline void timer_cc_set_pol(timer_dev *dev, uint8 channel, uint8 pol) { - *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1) + 1) = pol; -} - -/** - * @brief Get a timer's DMA burst length. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @return Number of transfers per read or write to timer DMA register, - * from 1 to 18. - */ -static inline uint8 timer_dma_get_burst_len(timer_dev *dev) { - uint32 dbl = ((dev->regs).gen->DCR & TIMER_DCR_DBL) >> 8; - return dbl + 1; /* 0 means 1 transfer, etc. */ -} - -/** - * @brief Set a timer's DMA burst length. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param length DMA burst length; i.e., number of DMA transfers per - * read/write to timer DMA register, from 1 to 18. - */ -static inline void timer_dma_set_burst_len(timer_dev *dev, uint8 length) { - uint32 tmp = (dev->regs).gen->DCR; - tmp &= ~TIMER_DCR_DBL; - tmp |= (length - 1) << 8; - (dev->regs).gen->DCR = tmp; -} - -/** - * @brief Timer DMA base address. - * - * Defines the base address for DMA transfers. - */ -typedef enum timer_dma_base_addr { - /** Base is control register 1 */ - TIMER_DMA_BASE_CR1 = TIMER_DCR_DBA_CR1, - /** Base is control register 2 */ - TIMER_DMA_BASE_CR2 = TIMER_DCR_DBA_CR2, - /** Base is slave mode control register */ - TIMER_DMA_BASE_SMCR = TIMER_DCR_DBA_SMCR, - /** Base is DMA interrupt enable register */ - TIMER_DMA_BASE_DIER = TIMER_DCR_DBA_DIER, - /** Base is status register */ - TIMER_DMA_BASE_SR = TIMER_DCR_DBA_SR, - /** Base is event generation register */ - TIMER_DMA_BASE_EGR = TIMER_DCR_DBA_EGR, - /** Base is capture/compare mode register 1 */ - TIMER_DMA_BASE_CCMR1 = TIMER_DCR_DBA_CCMR1, - /** Base is capture/compare mode register 2 */ - TIMER_DMA_BASE_CCMR2 = TIMER_DCR_DBA_CCMR2, - /** Base is capture/compare enable register */ - TIMER_DMA_BASE_CCER = TIMER_DCR_DBA_CCER, - /** Base is counter */ - TIMER_DMA_BASE_CNT = TIMER_DCR_DBA_CNT, - /** Base is prescaler */ - TIMER_DMA_BASE_PSC = TIMER_DCR_DBA_PSC, - /** Base is auto-reload register */ - TIMER_DMA_BASE_ARR = TIMER_DCR_DBA_ARR, - /** Base is repetition counter register */ - TIMER_DMA_BASE_RCR = TIMER_DCR_DBA_RCR, - /** Base is capture/compare register 1 */ - TIMER_DMA_BASE_CCR1 = TIMER_DCR_DBA_CCR1, - /** Base is capture/compare register 2 */ - TIMER_DMA_BASE_CCR2 = TIMER_DCR_DBA_CCR2, - /** Base is capture/compare register 3 */ - TIMER_DMA_BASE_CCR3 = TIMER_DCR_DBA_CCR3, - /** Base is capture/compare register 4 */ - TIMER_DMA_BASE_CCR4 = TIMER_DCR_DBA_CCR4, - /** Base is break and dead-time register */ - TIMER_DMA_BASE_BDTR = TIMER_DCR_DBA_BDTR, - /** Base is DMA control register */ - TIMER_DMA_BASE_DCR = TIMER_DCR_DBA_DCR, - /** Base is DMA address for full transfer */ - TIMER_DMA_BASE_DMAR = TIMER_DCR_DBA_DMAR, -} timer_dma_base_addr; - -/** - * @brief Get the timer's DMA base address. - * - * Some restrictions apply; see the reference manual for your chip. - * - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @return DMA base address - */ -static inline timer_dma_base_addr timer_dma_get_base_addr(timer_dev *dev) { - uint32 dcr = (dev->regs).gen->DCR; - return (timer_dma_base_addr)(dcr & TIMER_DCR_DBA); -} - -/** - * @brief Set the timer's DMA base address. - * - * Some restrictions apply; see the reference manual for your chip. - * - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param dma_base DMA base address. - */ -static inline void timer_dma_set_base_addr(timer_dev *dev, - timer_dma_base_addr dma_base) { - uint32 tmp = (dev->regs).gen->DCR; - tmp &= ~TIMER_DCR_DBA; - tmp |= dma_base; - (dev->regs).gen->DCR = tmp; -} - -/** - * Timer output compare modes. - */ -typedef enum timer_oc_mode { - /** - * Frozen: comparison between output compare register and counter - * has no effect on the outputs. */ - TIMER_OC_MODE_FROZEN = 0 << 4, - /** - * OCxREF signal is forced high when the count matches the channel - * capture/compare register. */ - TIMER_OC_MODE_ACTIVE_ON_MATCH = 1 << 4, - /** - * OCxREF signal is forced low when the counter matches the - * channel capture/compare register. */ - TIMER_OC_MODE_INACTIVE_ON_MATCH = 2 << 4, - /** - * OCxREF toggles when counter matches the channel capture/compare - * register. */ - TIMER_OC_MODE_TOGGLE = 3 << 4, - /** OCxREF is forced low. */ - TIMER_OC_MODE_FORCE_INACTIVE = 4 << 4, - /** OCxREF is forced high. */ - TIMER_OC_MODE_FORCE_ACTIVE = 5 << 4, - /** - * PWM mode 1. In upcounting, channel is active as long as count - * is less than channel capture/compare register, else inactive. - * In downcounting, channel is inactive as long as count exceeds - * capture/compare register, else active. */ - TIMER_OC_MODE_PWM_1 = 6 << 4, - /** - * PWM mode 2. In upcounting, channel is inactive as long as count - * is less than capture/compare register, else active. In - * downcounting, channel is active as long as count exceeds - * capture/compare register, else inactive. */ - TIMER_OC_MODE_PWM_2 = 7 << 4, -} timer_oc_mode; - -/** - * Timer output compare mode flags. - * @see timer_oc_set_mode() - */ -typedef enum timer_oc_mode_flags { - TIMER_OC_CE = 1U << 7, /**< Output compare clear enable. */ - TIMER_OC_PE = 1U << 3, /**< Output compare preload enable. */ - TIMER_OC_FE = 1U << 2, /**< Output compare fast enable. */ -} timer_oc_mode_flags; - -/** - * @brief Configure a channel's output compare mode. - * - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel to configure in output compare mode. - * @param mode Timer mode to set. - * @param flags OR of timer_oc_mode_flags. - * @see timer_oc_mode - * @see timer_oc_mode_flags - */ -static inline void timer_oc_set_mode(timer_dev *dev, - uint8 channel, - timer_oc_mode mode, - uint8 flags) { - /* channel == 1,2 -> CCMR1; channel == 3,4 -> CCMR2 */ - __io uint32 *ccmr = &(dev->regs).gen->CCMR1 + (((channel - 1) >> 1) & 1); - /* channel == 1,3 -> shift = 0, channel == 2,4 -> shift = 8 */ - uint8 shift = 8 * (1 - (channel & 1)); - - uint32 tmp = *ccmr; - tmp &= ~(0xFF << shift); - tmp |= (mode | flags | TIMER_CCMR_CCS_OUTPUT) << shift; - *ccmr = tmp; -} - -/* - * Old, erroneous bit definitions from previous releases, kept for - * backwards compatibility: - */ - -/** Deprecated. Use TIMER_CCMR1_CC4S_OUTPUT instead. */ -#define TIMER_CCMR1_CC4S_OUTPUT TIMER_CCMR2_CC4S_OUTPUT -/** Deprecated. Use TIMER_CCMR1_CC4S_INPUT_TI1 instead. */ -#define TIMER_CCMR1_CC4S_INPUT_TI1 TIMER_CCMR2_CC4S_INPUT_TI1 -/** Deprecated. Use TIMER_CCMR1_CC4S_INPUT_TI2 instead. */ -#define TIMER_CCMR1_CC4S_INPUT_TI2 TIMER_CCMR2_CC4S_INPUT_TI2 -/** Deprecated. Use TIMER_CCMR1_CC4S_INPUT_TRC instead. */ -#define TIMER_CCMR1_CC4S_INPUT_TRC TIMER_CCMR2_CC4S_INPUT_TRC -/** Deprecated. Use TIMER_CCMR2_IC4F instead. */ -#define TIMER_CCMR2_IC2F TIMER_CCMR2_IC4F -/** Deprecated. Use TIMER_CCMR2_IC4PSC instead. */ -#define TIMER_CCMR2_IC2PSC TIMER_CCMR2_IC4PSC -/** Deprecated. Use TIMER_CCMR2_IC3F instead. */ -#define TIMER_CCMR2_IC1F TIMER_CCMR2_IC3F -/** Deprecated. Use TIMER_CCMR2_IC3PSC instead. */ -#define TIMER_CCMR2_IC1PSC TIMER_CCMR2_IC3PSC -/** Deprecated. Use TIMER_CCMR1_CC3S_OUTPUT instead. */ -#define TIMER_CCMR1_CC3S_OUTPUT TIMER_CCMR2_CC3S_OUTPUT -/** Deprecated. Use TIMER_CCMR1_CC3S_INPUT_TI1 instead. */ -#define TIMER_CCMR1_CC3S_INPUT_TI1 TIMER_CCMR2_CC3S_INPUT_TI1 -/** Deprecated. Use TIMER_CCMR1_CC3S_INPUT_TI2 instead. */ -#define TIMER_CCMR1_CC3S_INPUT_TI2 TIMER_CCMR2_CC3S_INPUT_TI2 -/** Deprecated. Use TIMER_CCMR1_CC3S_INPUT_TRC instead. */ -#define TIMER_CCMR1_CC3S_INPUT_TRC TIMER_CCMR2_CC3S_INPUT_TRC - -/** Deprecated. Use TIMER_DCR_DBL_1_XFER instead. */ -#define TIMER_DCR_DBL_1BYTE TIMER_DCR_DBL_1_XFER -/** Deprecated. Use TIMER_DCR_DBL_2_XFER instead. */ -#define TIMER_DCR_DBL_2BYTE TIMER_DCR_DBL_2_XFER -/** Deprecated. Use TIMER_DCR_DBL_3_XFER instead. */ -#define TIMER_DCR_DBL_3BYTE TIMER_DCR_DBL_3_XFER -/** Deprecated. Use TIMER_DCR_DBL_4_XFER instead. */ -#define TIMER_DCR_DBL_4BYTE TIMER_DCR_DBL_4_XFER -/** Deprecated. Use TIMER_DCR_DBL_5_XFER instead. */ -#define TIMER_DCR_DBL_5BYTE TIMER_DCR_DBL_5_XFER -/** Deprecated. Use TIMER_DCR_DBL_6_XFER instead. */ -#define TIMER_DCR_DBL_6BYTE TIMER_DCR_DBL_6_XFER -/** Deprecated. Use TIMER_DCR_DBL_7_XFER instead. */ -#define TIMER_DCR_DBL_7BYTE TIMER_DCR_DBL_7_XFER -/** Deprecated. Use TIMER_DCR_DBL_8_XFER instead. */ -#define TIMER_DCR_DBL_8BYTE TIMER_DCR_DBL_8_XFER -/** Deprecated. Use TIMER_DCR_DBL_9_XFER instead. */ -#define TIMER_DCR_DBL_9BYTE TIMER_DCR_DBL_9_XFER -/** Deprecated. Use TIMER_DCR_DBL_10_XFER instead. */ -#define TIMER_DCR_DBL_10BYTE TIMER_DCR_DBL_10_XFER -/** Deprecated. Use TIMER_DCR_DBL_11_XFER instead. */ -#define TIMER_DCR_DBL_11BYTE TIMER_DCR_DBL_11_XFER -/** Deprecated. Use TIMER_DCR_DBL_12_XFER instead. */ -#define TIMER_DCR_DBL_12BYTE TIMER_DCR_DBL_12_XFER -/** Deprecated. Use TIMER_DCR_DBL_13_XFER instead. */ -#define TIMER_DCR_DBL_13BYTE TIMER_DCR_DBL_13_XFER -/** Deprecated. Use TIMER_DCR_DBL_14_XFER instead. */ -#define TIMER_DCR_DBL_14BYTE TIMER_DCR_DBL_14_XFER -/** Deprecated. Use TIMER_DCR_DBL_15_XFER instead. */ -#define TIMER_DCR_DBL_15BYTE TIMER_DCR_DBL_15_XFER -/** Deprecated. Use TIMER_DCR_DBL_16_XFER instead. */ -#define TIMER_DCR_DBL_16BYTE TIMER_DCR_DBL_16_XFER -/** Deprecated. Use TIMER_DCR_DBL_17_XFER instead. */ -#define TIMER_DCR_DBL_17BYTE TIMER_DCR_DBL_17_XFER -/** Deprecated. Use TIMER_DCR_DBL_18_XFER instead. */ -#define TIMER_DCR_DBL_18BYTE TIMER_DCR_DBL_18_XFER - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/usart.h b/STM32F3/cores/maple/libmaple/include/libmaple/usart.h deleted file mode 100644 index 82b1b7df0..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/usart.h +++ /dev/null @@ -1,464 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/usart.h - * @author Marti Bolivar , - * Perry Hung , - * F3-port by Hanspeter Portner - * @brief USART definitions and prototypes - */ - -#ifndef _LIBMAPLE_USART_H_ -#define _LIBMAPLE_USART_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include -#include -#include -#include -#include - -/* - * Register bit definitions - */ - -/* Status register */ - -/** Line break detection bit */ -#define USART_SR_LBD_BIT 8 -/** Transmit data register empty bit */ -#define USART_SR_TXE_BIT 7 -/** Transmission complete bit */ -#define USART_SR_TC_BIT 6 -/** Read data register not empty bit */ -#define USART_SR_RXNE_BIT 5 -/** IDLE line detected bit */ -#define USART_SR_IDLE_BIT 4 -/** Overrun error bit */ -#define USART_SR_ORE_BIT 3 -/** Noise error bit */ -#define USART_SR_NE_BIT 2 -/** - * @brief Synonym for USART_SR_NE_BIT. - * - * Some series (e.g. STM32F2) use "NF" for "noise flag" instead of the - * original "NE" for "noise error". The meaning of the bit is - * unchanged, but the NF flag can be disabled when the line is - * noise-free. - * - * @see USART_SR_NE_BIT - */ -#define USART_SR_NF_BIT USART_SR_NE_BIT -/** Framing error bit */ -#define USART_SR_FE_BIT 1 -/** Parity error bit */ -#define USART_SR_PE_BIT 0 - -/** Line break detected mask */ -#define USART_SR_LBD BIT(USART_SR_LBD_BIT) -/** Transmit data register empty mask */ -#define USART_SR_TXE BIT(USART_SR_TXE_BIT) -/** Transmission complete mask */ -#define USART_SR_TC BIT(USART_SR_TC_BIT) -/** Read data register not empty mask */ -#define USART_SR_RXNE BIT(USART_SR_RXNE_BIT) -/** IDLE line detected mask */ -#define USART_SR_IDLE BIT(USART_SR_IDLE_BIT) -/** Overrun error mask */ -#define USART_SR_ORE BIT(USART_SR_ORE_BIT) -/** Noise error mask */ -#define USART_SR_NE BIT(USART_SR_NE_BIT) -/** - * @brief Synonym for USART_SR_NE. - * @see USART_SR_NF_BIT - */ -#define USART_SR_NF USART_SR_NE -/** Framing error mask */ -#define USART_SR_FE BIT(USART_SR_FE_BIT) -/** Parity error mask */ -#define USART_SR_PE BIT(USART_SR_PE_BIT) - -/* Data register */ - -/** Data register data value mask */ -#define USART_DR_DR 0xFF - -/* Baud rate register */ - -/** Mantissa of USARTDIV mask */ -#define USART_BRR_DIV_MANTISSA (0xFFF << 4) -/** Fraction of USARTDIV mask */ -#define USART_BRR_DIV_FRACTION 0xF - -/* Control register 1 */ - -/** Word length bit */ -#define USART_CR1_M_BIT 12 -/** Wakeup method bit */ -#define USART_CR1_WAKE_BIT 11 -/** Parity control enable bit */ -#define USART_CR1_PCE_BIT 10 -/** Parity selection bit */ -#define USART_CR1_PS_BIT 9 -/** Parity error interrupt enable bit */ -#define USART_CR1_PEIE_BIT 8 -/** Transmit data regsiter not empty interrupt enable bit */ -#define USART_CR1_TXEIE_BIT 7 -/** Transmission complete interrupt enable bit */ -#define USART_CR1_TCIE_BIT 6 -/** RXNE interrupt enable bit */ -#define USART_CR1_RXNEIE_BIT 5 -/** IDLE interrupt enable bit */ -#define USART_CR1_IDLEIE_BIT 4 -/** Transmitter enable bit */ -#define USART_CR1_TE_BIT 3 -/** Receiver enable bit */ -#define USART_CR1_RE_BIT 2 - -/** Word length mask */ -#define USART_CR1_M BIT(USART_CR1_M_BIT) -/** Word length: 1 start bit, 8 data bits, n stop bit */ -#define USART_CR1_M_8N1 (0 << USART_CR1_M_BIT) -/** Word length: 1 start bit, 9 data bits, n stop bit */ -#define USART_CR1_M_9N1 (1 << USART_CR1_M_BIT) -/** Wakeup method mask */ -#define USART_CR1_WAKE BIT(USART_CR1_WAKE_BIT) -/** Wakeup on idle line */ -#define USART_CR1_WAKE_IDLE (0 << USART_CR1_WAKE_BIT) -/** Wakeup on address mark */ -#define USART_CR1_WAKE_ADDR (1 << USART_CR1_WAKE_BIT) -/** Parity control enable mask */ -#define USART_CR1_PCE BIT(USART_CR1_PCE_BIT) -/** Parity selection mask */ -#define USART_CR1_PS BIT(USART_CR1_PS_BIT) -/** Parity selection: even parity */ -#define USART_CR1_PS_EVEN (0 << USART_CR1_PS_BIT) -/** Parity selection: odd parity */ -#define USART_CR1_PS_ODD (1 << USART_CR1_PS_BIT) -/** Parity error interrupt enable mask */ -#define USART_CR1_PEIE BIT(USART_CR1_PEIE_BIT) -/** Transmit data register empty interrupt enable mask */ -#define USART_CR1_TXEIE BIT(USART_CR1_TXEIE_BIT) -/** Transmission complete interrupt enable mask */ -#define USART_CR1_TCIE BIT(USART_CR1_TCIE_BIT) -/** RXNE interrupt enable mask */ -#define USART_CR1_RXNEIE BIT(USART_CR1_RXNEIE_BIT) -/** IDLE line interrupt enable mask */ -#define USART_CR1_IDLEIE BIT(USART_CR1_IDLEIE_BIT) -/** Transmitter enable mask */ -#define USART_CR1_TE BIT(USART_CR1_TE_BIT) -/** Receiver enable mask */ -#define USART_CR1_RE BIT(USART_CR1_RE_BIT) - -/* Control register 2 */ - -/** LIN mode enable bit */ -#define USART_CR2_LINEN_BIT 14 -/** Clock enable bit */ -#define USART_CR2_CLKEN_BIT 11 -/** Clock polarity bit */ -#define USART_CR2_CPOL_BIT 10 -/** Clock phase bit */ -#define USART_CR2_CPHA_BIT 9 -/** Last bit clock pulse bit */ -#define USART_CR2_LBCL_BIT 8 -/** LIN break detection interrupt enable bit */ -#define USART_CR2_LBDIE_BIT 6 -/** LIN break detection length bit */ -#define USART_CR2_LBDL_BIT 5 - -/** LIN mode enable mask */ -#define USART_CR2_LINEN BIT(USART_CR2_LINEN_BIT) -/** STOP bits mask */ -#define USART_CR2_STOP (0x3 << 12) -/** STOP bits: 1 stop bit */ -#define USART_CR2_STOP_BITS_1 (0x0 << 12) -/** - * @brief STOP bits: 0.5 stop bits - * Not available on UART4, UART5. */ -#define USART_CR2_STOP_BITS_POINT_5 (0x1 << 12) -/** STOP bits: 2 stop bits */ -#define USART_CR2_STOP_BITS_2 (0x2 << 12) -/** - * @brief STOP bits: 1.5 stop bits - * Not available on UART4, UART5. */ -#define USART_CR2_STOP_BITS_1_POINT_5 (0x3 << 12) -/** - * @brief Clock enable. - * Not available on UART4, UART5 */ -#define USART_CR2_CLKEN BIT(USART_CR2_CLKEN_BIT) -/** - * @brief Clock polarity mask. - * Not available on UART4, UART5 */ -#define USART_CR2_CPOL BIT(USART_CR2_CPOL_BIT) -/** Clock polarity: low */ -#define USART_CR2_CPOL_LOW (0x0 << USART_CR2_CLKEN_BIT) -/** Clock polarity: high */ -#define USART_CR2_CPOL_HIGH (0x1 << USART_CR2_CLKEN_BIT) -/** - * @brief Clock phase mask. - * Not available on UART4, UART5 */ -#define USART_CR2_CPHA BIT(USART_CR2_CPHA_BIT) -/** - * @brief Clock phase: first - * First clock transition is the first data capture edge. */ -#define USART_CR2_CPHA_FIRST (0x0 << USART_CR2_CPHA_BIT) -/** - * @brief Clock phase: second - * Second clock transition is the first data capture edge. */ -#define USART_CR2_CPHA_SECOND (0x1 << USART_CR2_CPHA_BIT) -/** - * @brief Last bit clock pulse mask. - * - * When set, the last bit transmitted causes a clock pulse in - * synchronous mode. - * - * Not available on UART4, UART5 */ -#define USART_CR2_LBCL BIT(USART_CR2_LBCL_BIT) -/** LIN break detection interrupt enable mask. */ -#define USART_CR2_LBDIE BIT(USART_CR2_LBDIE_BIT) -/** LIN break detection length. */ -#define USART_CR2_LBDL BIT(USART_CR2_LBDL_BIT) -/** LIN break detection length: 10 bits */ -#define USART_CR2_LBDL_10_BIT (0 << USART_CR2_LBDL_BIT) -/** LIN break detection length: 11 bits */ -#define USART_CR2_LBDL_11_BIT (1 << USART_CR2_LBDL_BIT) - -/* Control register 3 */ - -/** Clear to send interrupt enable bit */ -#define USART_CR3_CTSIE_BIT 10 -/** Clear to send enable bit */ -#define USART_CR3_CTSE_BIT 9 -/** Ready to send enable bit */ -#define USART_CR3_RTSE_BIT 8 -/** DMA enable transmitter bit */ -#define USART_CR3_DMAT_BIT 7 -/** DMA enable receiver bit */ -#define USART_CR3_DMAR_BIT 6 -/** Smartcard mode enable bit */ -#define USART_CR3_SCEN_BIT 5 -/** Smartcard NACK enable bit */ -#define USART_CR3_NACK_BIT 4 -/** Half-duplex selection bit */ -#define USART_CR3_HDSEL_BIT 3 -/** IrDA low power bit */ -#define USART_CR3_IRLP_BIT 2 -/** IrDA mode enable bit */ -#define USART_CR3_IREN_BIT 1 -/** Error interrupt enable bit */ -#define USART_CR3_EIE_BIT 0 - -/** - * @brief Clear to send interrupt enable - * Not available on UART4, UART5. */ -#define USART_CR3_CTSIE BIT(USART_CR3_CTSIE_BIT) -/** - * @brief Clear to send enable - * Not available on UART4, UART5. */ -#define USART_CR3_CTSE BIT(USART_CR3_CTSE_BIT) -/** - * @brief Ready to send enable - * Not available on UART4, UART5. */ -#define USART_CR3_RTSE BIT(USART_CR3_RTSE_BIT) -/** - * @brief DMA enable transmitter - * Not available on UART5. */ -#define USART_CR3_DMAT BIT(USART_CR3_DMAT_BIT) -/** - * @brief DMA enable receiver - * Not available on UART5. */ -#define USART_CR3_DMAR BIT(USART_CR3_DMAR_BIT) -/** - * @brief Smartcard mode enable - * Not available on UART4, UART5. */ -#define USART_CR3_SCEN BIT(USART_CR3_SCEN_BIT) -/** - * @brief Smartcard NACK enable - * Not available on UART4, UART5. */ -#define USART_CR3_NACK BIT(USART_CR3_NACK_BIT) -/** - * @brief Half-duplex selection - * When set, single-wire half duplex mode is selected. - */ -#define USART_CR3_HDSEL BIT(USART_CR3_HDSEL_BIT) -/** IrDA low power mode */ -#define USART_CR3_IRLP BIT(USART_CR3_IRLP_BIT) -/** IrDA mode: normal */ -#define USART_CR3_IRLP_NORMAL (0U << USART_CR3_IRLP_BIT) -/** IrDA mode: low power */ -#define USART_CR3_IRLP_LOW_POWER (1U << USART_CR3_IRLP_BIT) -/** IrDA mode enable */ -#define USART_CR3_IREN BIT(USART_CR3_IREN_BIT) -/** Error interrupt enable */ -#define USART_CR3_EIE BIT(USART_CR3_EIE_BIT) - -/* Guard time and prescaler register */ - -/** - * @brief Guard time value mask - * Used in Smartcard mode. Not available on UART4, UART5. */ -#define USART_GTPR_GT (0xFF << 8) -/** - * @brief Prescaler value mask - * Restrictions on this value apply, depending on the USART mode. Not - * available on UART4, UART5. */ -#define USART_GTPR_PSC 0xFF - -/* - * Devices - */ - -#ifndef USART_RX_BUF_SIZE -#define USART_RX_BUF_SIZE 64 -#endif - -/** USART device type */ -typedef struct usart_dev { - usart_reg_map *regs; /**< Register map */ - ring_buffer *rb; /**< RX ring buffer */ - uint32 max_baud; /**< @brief Deprecated. - * Maximum baud rate. */ - uint8 rx_buf[USART_RX_BUF_SIZE]; /**< @brief Deprecated. - * Actual RX buffer used by rb. - * This field will be removed in - * a future release. */ - rcc_clk_id clk_id; /**< RCC clock information */ - nvic_irq_num irq_num; /**< USART NVIC interrupt */ -} usart_dev; - -void usart_init(usart_dev *dev); - -struct gpio_dev; /* forward declaration */ -/* FIXME [PRE 0.0.13] decide if flags are necessary */ -/** - * @brief Configure GPIOs for use as USART TX/RX. - * @param udev USART device to use - * @param rx_dev RX pin gpio_dev - * @param rx RX pin bit on rx_dev - * @param tx_dev TX pin gpio_dev - * @param tx TX pin bit on tx_dev - * @param flags Currently ignored - */ -extern void usart_config_gpios_async(usart_dev *udev, - struct gpio_dev *rx_dev, uint8 rx, - struct gpio_dev *tx_dev, uint8 tx, - unsigned flags); - -#define USART_USE_PCLK 0 -void usart_set_baud_rate(usart_dev *dev, uint32 clock_speed, uint32 baud); - -void usart_enable(usart_dev *dev); -void usart_disable(usart_dev *dev); -void usart_foreach(void (*fn)(usart_dev *dev)); -/** - * @brief Nonblocking USART transmit - * @param dev Serial port to transmit over - * @param buf Buffer to transmit - * @param len Maximum number of bytes to transmit - * @return Number of bytes transmitted - */ -uint32 usart_tx(usart_dev *dev, const uint8 *buf, uint32 len); -uint32 usart_rx(usart_dev *dev, uint8 *buf, uint32 len); -void usart_putudec(usart_dev *dev, uint32 val); - -/** - * @brief Disable all serial ports. - */ -static inline void usart_disable_all(void) { - usart_foreach(usart_disable); -} - -/** - * @brief Transmit one character on a serial port. - * - * This function blocks until the character has been successfully - * transmitted. - * - * @param dev Serial port to send on. - * @param byte Byte to transmit. - */ -static inline void usart_putc(usart_dev* dev, uint8 byte) { - while (!usart_tx(dev, &byte, 1)) - ; -} - -/** - * @brief Transmit a character string on a serial port. - * - * This function blocks until str is completely transmitted. - * - * @param dev Serial port to send on - * @param str String to send - */ -static inline void usart_putstr(usart_dev *dev, const char* str) { - uint32 i = 0; - while (str[i] != '\0') { - usart_putc(dev, str[i++]); - } -} - -/** - * @brief Read one character from a serial port. - * - * It's not safe to call this function if the serial port has no data - * available. - * - * @param dev Serial port to read from - * @return byte read - * @see usart_data_available() - */ -static inline uint8 usart_getc(usart_dev *dev) { - return rb_remove(dev->rb); -} - -/** - * @brief Return the amount of data available in a serial port's RX buffer. - * @param dev Serial port to check - * @return Number of bytes in dev's RX buffer. - */ -static inline uint32 usart_data_available(usart_dev *dev) { - return rb_full_count(dev->rb); -} - -/** - * @brief Discard the contents of a serial port's RX buffer. - * @param dev Serial port whose buffer to empty. - */ -static inline void usart_reset_rx(usart_dev *dev) { - rb_reset(dev->rb); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/usb.h b/STM32F3/cores/maple/libmaple/include/libmaple/usb.h deleted file mode 100644 index ea24030d4..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/usb.h +++ /dev/null @@ -1,176 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010, 2011, 2012 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* - * NOTE: This API is _unstable_ and will change drastically over time. - */ - -#ifndef _LIBMAPLE_USB_H_ -#define _LIBMAPLE_USB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/* - * Descriptors and other paraphernalia - */ - -/* Descriptor types */ - -#define USB_DESCRIPTOR_TYPE_DEVICE 0x01 -#define USB_DESCRIPTOR_TYPE_CONFIGURATION 0x02 -#define USB_DESCRIPTOR_TYPE_STRING 0x03 -#define USB_DESCRIPTOR_TYPE_INTERFACE 0x04 -#define USB_DESCRIPTOR_TYPE_ENDPOINT 0x05 - -/* Descriptor structs and declaration helpers */ - -#define USB_DESCRIPTOR_STRING_LEN(x) (2 + (x << 1)) - -#define USB_DESCRIPTOR_STRING(len) \ - struct { \ - uint8 bLength; \ - uint8 bDescriptorType; \ - uint16 bString[len]; \ - } __packed - -typedef struct usb_descriptor_device { - uint8 bLength; - uint8 bDescriptorType; - uint16 bcdUSB; - uint8 bDeviceClass; - uint8 bDeviceSubClass; - uint8 bDeviceProtocol; - uint8 bMaxPacketSize0; - uint16 idVendor; - uint16 idProduct; - uint16 bcdDevice; - uint8 iManufacturer; - uint8 iProduct; - uint8 iSerialNumber; - uint8 bNumConfigurations; -} __packed usb_descriptor_device; - -typedef struct usb_descriptor_config_header { - uint8 bLength; - uint8 bDescriptorType; - uint16 wTotalLength; - uint8 bNumInterfaces; - uint8 bConfigurationValue; - uint8 iConfiguration; - uint8 bmAttributes; - uint8 bMaxPower; -} __packed usb_descriptor_config_header; - -typedef struct usb_descriptor_interface { - uint8 bLength; - uint8 bDescriptorType; - uint8 bInterfaceNumber; - uint8 bAlternateSetting; - uint8 bNumEndpoints; - uint8 bInterfaceClass; - uint8 bInterfaceSubClass; - uint8 bInterfaceProtocol; - uint8 iInterface; -} __packed usb_descriptor_interface; - -typedef struct usb_descriptor_endpoint { - uint8 bLength; - uint8 bDescriptorType; - uint8 bEndpointAddress; - uint8 bmAttributes; - uint16 wMaxPacketSize; - uint8 bInterval; -} __packed usb_descriptor_endpoint; - -typedef struct usb_descriptor_string { - uint8 bLength; - uint8 bDescriptorType; - uint8 bString[]; -} usb_descriptor_string; - -/* Common values that go inside descriptors */ - -#define USB_CONFIG_ATTR_BUSPOWERED 0b10000000 -#define USB_CONFIG_ATTR_SELF_POWERED 0b11000000 - -#define USB_EP_TYPE_INTERRUPT 0x03 -#define USB_EP_TYPE_BULK 0x02 - -#define USB_DESCRIPTOR_ENDPOINT_IN 0x80 -#define USB_DESCRIPTOR_ENDPOINT_OUT 0x00 - -/* - * USB module core - */ - -#ifndef USB_ISR_MSK -/* Handle CTRM, WKUPM, SUSPM, ERRM, SOFM, ESOFM, RESETM */ -#define USB_ISR_MSK 0xBF00 -#endif - -typedef enum usb_dev_state { - USB_UNCONNECTED, - USB_ATTACHED, - USB_POWERED, - USB_SUSPENDED, - USB_ADDRESSED, - USB_CONFIGURED -} usb_dev_state; - -/* Encapsulates global state formerly handled by usb_lib/ */ -typedef struct usblib_dev { - uint32 irq_mask; - void (**ep_int_in)(void); - void (**ep_int_out)(void); - usb_dev_state state; - usb_dev_state prevState; - rcc_clk_id clk_id; -} usblib_dev; - -extern usblib_dev *USBLIB; - -void usb_init_usblib(usblib_dev *dev, - void (**ep_int_in)(void), - void (**ep_int_out)(void)); - -static inline uint8 usb_is_connected(usblib_dev *dev) { - return dev->state != USB_UNCONNECTED; -} - -static inline uint8 usb_is_configured(usblib_dev *dev) { - return dev->state == USB_CONFIGURED; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/usb_cdcacm.h b/STM32F3/cores/maple/libmaple/include/libmaple/usb_cdcacm.h deleted file mode 100644 index 5fe832cfb..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/usb_cdcacm.h +++ /dev/null @@ -1,179 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/usb_cdcacm.h - * @brief USB CDC ACM (virtual serial terminal) support - * - * IMPORTANT: this API is unstable, and may change without notice. - */ - -#ifndef _LIBMAPLE_USB_CDCACM_H_ -#define _LIBMAPLE_USB_CDCACM_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * CDC ACM Requests - */ - -#define USB_CDCACM_SET_LINE_CODING 0x20 -#define USB_CDCACM_GET_LINE_CODING 0x21 -#define USB_CDCACM_SET_COMM_FEATURE 0x02 -#define USB_CDCACM_SET_CONTROL_LINE_STATE 0x22 -#define USB_CDCACM_CONTROL_LINE_DTR (0x01) -#define USB_CDCACM_CONTROL_LINE_RTS (0x02) - -/* - * Descriptors, etc. - */ - -#define CDC_FUNCTIONAL_DESCRIPTOR_SIZE(DataSize) (3 + DataSize) -#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \ - struct { \ - uint8 bLength; \ - uint8 bDescriptorType; \ - uint8 SubType; \ - uint8 Data[DataSize]; \ - } __packed - -#define USB_DEVICE_CLASS_CDC 0x02 -#define USB_DEVICE_SUBCLASS_CDC 0x00 -#define USB_INTERFACE_CLASS_CDC 0x02 -#define USB_INTERFACE_SUBCLASS_CDC_ACM 0x02 -#define USB_INTERFACE_CLASS_DIC 0x0A - -/* - * Endpoint configuration - */ - -#define USB_CDCACM_CTRL_ENDP 0 -#define USB_CDCACM_CTRL_RX_ADDR 0x40 -#define USB_CDCACM_CTRL_TX_ADDR 0x80 -#define USB_CDCACM_CTRL_EPSIZE 0x40 - -#define USB_CDCACM_TX_ENDP 1 -#define USB_CDCACM_TX_ADDR 0xC0 -#define USB_CDCACM_TX_EPSIZE 0x40 - -#define USB_CDCACM_MANAGEMENT_ENDP 2 -#define USB_CDCACM_MANAGEMENT_ADDR 0x100 -#define USB_CDCACM_MANAGEMENT_EPSIZE 0x40 - -#define USB_CDCACM_RX_ENDP 3 -#define USB_CDCACM_RX_ADDR 0x110 -#define USB_CDCACM_RX_EPSIZE 0x40 - -#ifndef __cplusplus -#define USB_CDCACM_DECLARE_DEV_DESC(vid, pid) \ - { \ - .bLength = sizeof(usb_descriptor_device), \ - .bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE, \ - .bcdUSB = 0x0200, \ - .bDeviceClass = USB_DEVICE_CLASS_CDC, \ - .bDeviceSubClass = USB_DEVICE_SUBCLASS_CDC, \ - .bDeviceProtocol = 0x00, \ - .bMaxPacketSize0 = 0x40, \ - .idVendor = vid, \ - .idProduct = pid, \ - .bcdDevice = 0x0200, \ - .iManufacturer = 0x01, \ - .iProduct = 0x02, \ - .iSerialNumber = 0x00, \ - .bNumConfigurations = 0x01, \ - } -#endif - -/* - * CDC ACM interface - */ - -void usb_cdcacm_enable(gpio_dev*, uint8); -void usb_cdcacm_disable(gpio_dev*, uint8); - -void usb_cdcacm_putc(char ch); -uint32 usb_cdcacm_tx(const uint8* buf, uint32 len); -uint32 usb_cdcacm_rx(uint8* buf, uint32 len); -uint32 usb_cdcacm_peek(uint8* buf, uint32 len); - -uint32 usb_cdcacm_data_available(void); /* in RX buffer */ -uint16 usb_cdcacm_get_pending(void); -uint8 usb_cdcacm_is_transmitting(void); - -uint8 usb_cdcacm_get_dtr(void); -uint8 usb_cdcacm_get_rts(void); - -typedef struct usb_cdcacm_line_coding { - uint32 dwDTERate; /* Baud rate */ - -#define USB_CDCACM_STOP_BITS_1 0 -#define USB_CDCACM_STOP_BITS_1_5 1 -#define USB_CDCACM_STOP_BITS_2 2 - uint8 bCharFormat; /* Stop bits */ - -#define USB_CDCACM_PARITY_NONE 0 -#define USB_CDCACM_PARITY_ODD 1 -#define USB_CDCACM_PARITY_EVEN 2 -#define USB_CDCACM_PARITY_MARK 3 -#define USB_CDCACM_PARITY_SPACE 4 - uint8 bParityType; /* Parity type */ - - uint8 bDataBits; /* Data bits: 5, 6, 7, 8, or 16 */ -} __packed usb_cdcacm_line_coding; - -/* Retrieve a copy of the current line coding structure. */ -void usb_cdcacm_get_line_coding(usb_cdcacm_line_coding*); - -/* Line coding conveniences. */ -int usb_cdcacm_get_baud(void); /* dwDTERate */ -int usb_cdcacm_get_stop_bits(void); /* bCharFormat */ -int usb_cdcacm_get_parity(void); /* bParityType */ -int usb_cdcacm_get_n_data_bits(void); /* bDataBits */ - -/* - * Hack: hooks for bootloader reset signalling - */ - -#define USB_CDCACM_HOOK_RX 0x1 -#define USB_CDCACM_HOOK_IFACE_SETUP 0x2 - -void usb_cdcacm_set_hooks(unsigned hook_flags, void (*hook)(unsigned, void*)); - -static __always_inline void usb_cdcacm_remove_hooks(unsigned hook_flags) { - usb_cdcacm_set_hooks(hook_flags, 0); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/util.h b/STM32F3/cores/maple/libmaple/include/libmaple/util.h deleted file mode 100644 index 5a7034803..000000000 --- a/STM32F3/cores/maple/libmaple/include/libmaple/util.h +++ /dev/null @@ -1,111 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/util.h - * @brief Miscellaneous utility macros and procedures. - */ - -#ifndef _LIBMAPLE_UTIL_H_ -#define _LIBMAPLE_UTIL_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -/* - * Bit manipulation - */ - -/** 1UL shifted left by 'shift' */ -#define BIT(shift) (1UL << (shift)) -/** 'Mask' shifted left by 'shift' */ -#define BIT_MASK_SHIFT(mask, shift) ((mask) << (shift)) -/** Bits m to n of x */ -#define GET_BITS(x, m, n) ((((uint32)x) << (31 - (n))) >> ((31 - (n)) + (m))) -/** True iff v is a power of two (1, 2, 4, 8, ...) */ -#define IS_POWER_OF_TWO(v) ((v) && !((v) & ((v) - 1))) - -/* - * Failure routines - */ - -void __error(void); -void _fail(const char*, int, const char*); -void throb(void); - -/* - * Asserts and debug levels - */ - -#define DEBUG_NONE 0 -#define DEBUG_FAULT 1 -#define DEBUG_ALL 2 - -/** - * \def DEBUG_LEVEL - * - * Controls the level of assertion checking. - * - * The higher the debug level, the more assertions will be compiled - * in. This increases the amount of debugging information, but slows - * down (and increases the size of) the binary. - * - * The debug levels, from lowest to highest, are DEBUG_NONE, - * DEBUG_FAULT, and DEBUG_ALL. The default level is DEBUG_ALL. - */ - -#ifndef DEBUG_LEVEL -#define DEBUG_LEVEL DEBUG_ALL -#endif - -#if DEBUG_LEVEL >= DEBUG_ALL -#define ASSERT(exp) \ - if (exp) { \ - } else { \ - _fail(__FILE__, __LINE__, #exp); \ - } -#else -#define ASSERT(exp) (void)((0)) -#endif - -#if DEBUG_LEVEL >= DEBUG_FAULT -#define ASSERT_FAULT(exp) \ - if (exp) { \ - } else { \ - _fail(__FILE__, __LINE__, #exp); \ - } -#else -#define ASSERT_FAULT(exp) (void)((0)) -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/iwdg.c b/STM32F3/cores/maple/libmaple/iwdg.c deleted file mode 100644 index 24562353f..000000000 --- a/STM32F3/cores/maple/libmaple/iwdg.c +++ /dev/null @@ -1,62 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/iwdg.c - * @brief Independent watchdog (IWDG) support - */ - -#include - -/** - * @brief Initialise and start the watchdog - * - * The prescaler and reload set the timeout. For example, a prescaler - * of IWDG_PRE_32 divides the 40 kHz clock by 32 and gives roughly 1 - * ms per reload. - * - * @param prescaler Prescaler for the 40 kHz IWDG clock. - * @param reload Independent watchdog counter reload value. - */ -void iwdg_init(iwdg_prescaler prescaler, uint16 reload) { - IWDG_BASE->KR = IWDG_KR_UNLOCK; - IWDG_BASE->PR = prescaler; - IWDG_BASE->RLR = reload; - - /* Start things off */ - IWDG_BASE->KR = IWDG_KR_START; - iwdg_feed(); -} - -/** - * @brief Reset the IWDG counter. - * - * Calling this function will cause the IWDG counter to be reset to - * its reload value. - */ -void iwdg_feed(void) { - IWDG_BASE->KR = IWDG_KR_FEED; -} diff --git a/STM32F3/cores/maple/libmaple/nvic.c b/STM32F3/cores/maple/libmaple/nvic.c deleted file mode 100644 index 149e7804c..000000000 --- a/STM32F3/cores/maple/libmaple/nvic.c +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/nvic.c - * @brief Nested vector interrupt controller support. - */ - -#include -#include -#include - -/** - * @brief Set interrupt priority for an interrupt line - * - * Note: The STM32 only implements 4 bits of priority, ignoring the - * lower 4 bits. This means there are only 16 levels of priority. - * Bits[3:0] read as zero and ignore writes. - * - * @param irqn device to set - * @param priority Priority to set, 0 being highest priority and 15 - * being lowest. - */ -void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority) { - if (irqn < 0) { - /* This interrupt is in the system handler block */ - SCB_BASE->SHP[((uint32)irqn & 0xF) - 4] = (priority & 0xF) << 4; - } else { - NVIC_BASE->IP[irqn] = (priority & 0xF) << 4; - } -} - -/** - * @brief Initialize the NVIC, setting interrupts to a default priority. - */ -void nvic_init(uint32 address, uint32 offset) { - uint32 i; - - nvic_set_vector_table(address, offset); - - /* - * Lower priority level for all peripheral interrupts to lowest - * possible. - */ - for (i = 0; i < STM32_NR_INTERRUPTS; i++) { - nvic_irq_set_priority((nvic_irq_num)i, 0xF); - } - - /* Lower systick interrupt priority to lowest level */ - nvic_irq_set_priority(NVIC_SYSTICK, 0xF); -} - -/** - * @brief Set the vector table base address. - * - * For stand-alone products, the vector table base address is normally - * the start of Flash (0x08000000). - * - * @param address Vector table base address. - * @param offset Offset from address. Some restrictions apply to the - * use of nonzero offsets; see the ARM Cortex M3 - * Technical Reference Manual. - */ -void nvic_set_vector_table(uint32 address, uint32 offset) { - SCB_BASE->VTOR = address | (offset & 0x1FFFFF80); -} - -/** - * @brief Force a system reset. - * - * Resets all major system components, excluding debug. - */ -void nvic_sys_reset() { - uint32 prigroup = SCB_BASE->AIRCR & SCB_AIRCR_PRIGROUP; - SCB_BASE->AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ | prigroup; - asm volatile("dsb"); - while (1) - ; -} diff --git a/STM32F3/cores/maple/libmaple/pwr.c b/STM32F3/cores/maple/libmaple/pwr.c deleted file mode 100644 index 3cf170f37..000000000 --- a/STM32F3/cores/maple/libmaple/pwr.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/pwr.c - * @brief Power control (PWR) support. - */ - -#include -#include - -/** - * Enables the power interface clock, and resets the power device. - */ -void pwr_init(void) { - rcc_clk_enable(RCC_PWR); - rcc_reset_dev(RCC_PWR); -} diff --git a/STM32F3/cores/maple/libmaple/rcc.c b/STM32F3/cores/maple/libmaple/rcc.c deleted file mode 100644 index 8e7d1ea7d..000000000 --- a/STM32F3/cores/maple/libmaple/rcc.c +++ /dev/null @@ -1,169 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/rcc.c - * @brief Portable RCC routines. - */ - -#include - -#include "rcc_private.h" - -/** - * @brief Get a peripheral's clock domain - * @param id Clock ID of the peripheral whose clock domain to return - * @return Clock source for the given clock ID - */ -rcc_clk_domain rcc_dev_clk(rcc_clk_id id) { - return rcc_dev_table[id].clk_domain; -} - -/** - * @brief Switch the clock used as the source of the system clock. - * - * After switching the source, this function blocks until the new - * clock source is in use. - * - * @param sysclk_src New system clock source. - * @see rcc_sysclk_src - */ -void rcc_switch_sysclk(rcc_sysclk_src sysclk_src) { - uint32 cfgr = RCC_BASE->CFGR; - cfgr &= ~RCC_CFGR_SW; - cfgr |= sysclk_src; - - /* Switch SYSCLK source. */ - RCC_BASE->CFGR = cfgr; - - /* Wait for new source to come into use. */ - while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != (sysclk_src << 2)) - ; -} - -/* - * Turning clocks off and on, querying their status. - */ - -/* IMPORTANT NOTE FOR IMPLEMENTORS: - * - * libmaple assumes that enum rcc_clk enumerators are two-byte - * values, stored in a uint16, in the following way: - * - * - The high-order byte is the byte offset (from RCC_BASE) of the register - * to touch when turning on or off the given clock. - * - * - The low-order byte is the bit in that register that turns the - * clock on or off. - * - * Example for STM32F1: Turning on the high-speed external clock (HSE) - * involves setting HSEON, bit 16, of RCC_CR. The high-order byte is - * then offsetof(struct rcc_reg_map, CR) = 0, and the low-order byte - * is 16. - * - * The corresponding value of RCC_CLK_HSE is thus (0 << 8) | 16 = 16. - * - * On all known STM32 series, this encoding has the property that - * adding one to the low byte also gives the bit to check to determine - * if the clock is ready. For example, on STM32F1, RCC_CR_HSERDY is - * bit 17. If that's not the case on your series, rcc_is_clk_ready() - * won't work for you. */ - -/* Returns the RCC register which controls the clock source. */ -static inline __io uint32* rcc_clk_reg(rcc_clk clock) { - return (__io uint32*)((__io uint8*)RCC_BASE + (clock >> 8)); -} - -/* Returns a mask in rcc_clk_reg(clock) to be used for turning the - * clock on and off */ -static inline uint32 rcc_clk_on_mask(rcc_clk clock) { - return 1 << (clock & 0xFF); -} - -/* Returns a mask in rcc_clk_reg(clock) to be used when checking the - * readiness of the clock. */ -static inline uint32 rcc_clk_ready_mask(rcc_clk clock) { - return rcc_clk_on_mask(clock) << 1; -} - -/** - * @brief Turn on a clock source. - * - * After this routine exits, callers should ensure that the clock - * source is ready by waiting until rcc_is_clk_ready(clock) returns - * true. - * - * @param clock Clock to turn on. - * @see rcc_turn_off_clk() - * @see rcc_is_clk_ready() - */ -void rcc_turn_on_clk(rcc_clk clock) { - *rcc_clk_reg(clock) |= rcc_clk_on_mask(clock); -} - -/** - * @brief Turn off a clock source. - * - * In certain configurations, certain clock sources cannot be safely - * turned off. (For example, the main PLL on STM32F1 devices cannot be - * turned off if it has been selected as the SYSCLK source). Consult - * the reference material for your MCU to ensure it is safe to call - * this function. - * - * @param clock Clock to turn off. - * @see rcc_turn_on_clk() - * @see rcc_is_clk_ready() - */ -void rcc_turn_off_clk(rcc_clk clock) { - *rcc_clk_reg(clock) &= ~rcc_clk_on_mask(clock); -} - -/** - * @brief Check if a clock is on. - * @param clock Clock to check. - * @return 1 if the clock is on, 0 if the clock is off. - */ -int rcc_is_clk_on(rcc_clk clock) { - return !!(*rcc_clk_reg(clock) & rcc_clk_on_mask(clock)); -} - -/** - * @brief Check if a clock source is ready. - * - * In general, it is not safe to rely on a clock source unless this - * function returns nonzero. Also note that this function may return - * nonzero for a short period of time after a clock has been turned - * off. Consult the reference material for your MCU for more details. - * - * @param clock Clock whose readiness to check for. - * @return Nonzero if the clock is ready, zero otherwise. - * @see rcc_turn_on_clk() - * @see rcc_turn_off_clk() - */ -int rcc_is_clk_ready(rcc_clk clock) { - return (int)(*rcc_clk_reg(clock) & rcc_clk_ready_mask(clock)); -} diff --git a/STM32F3/cores/maple/libmaple/rcc_private.h b/STM32F3/cores/maple/libmaple/rcc_private.h deleted file mode 100644 index 66eaf00da..000000000 --- a/STM32F3/cores/maple/libmaple/rcc_private.h +++ /dev/null @@ -1,67 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* - * RCC private header. - */ - -#ifndef _LIBMAPLE_PRIVATE_RCC_H_ -#define _LIBMAPLE_PRIVATE_RCC_H_ - -#include - -struct rcc_dev_info { - const rcc_clk_domain clk_domain; - const uint8 line_num; -}; - -extern const struct rcc_dev_info rcc_dev_table[]; - -static inline void rcc_do_clk_enable(__io uint32** enable_regs, - rcc_clk_id id) { - __io uint32 *enable_reg = enable_regs[rcc_dev_clk(id)]; - uint8 line_num = rcc_dev_table[id].line_num; - bb_peri_set_bit(enable_reg, line_num, 1); -} - -static inline void rcc_do_reset_dev(__io uint32** reset_regs, - rcc_clk_id id) { - __io uint32 *reset_reg = reset_regs[rcc_dev_clk(id)]; - uint8 line_num = rcc_dev_table[id].line_num; - bb_peri_set_bit(reset_reg, line_num, 1); - bb_peri_set_bit(reset_reg, line_num, 0); -} - -static inline void rcc_do_set_prescaler(const uint32 *masks, - rcc_prescaler prescaler, - uint32 divider) { - uint32 cfgr = RCC_BASE->CFGR; - cfgr &= ~masks[prescaler]; - cfgr |= divider; - RCC_BASE->CFGR = cfgr; -} - -#endif diff --git a/STM32F3/cores/maple/libmaple/rules.mk b/STM32F3/cores/maple/libmaple/rules.mk deleted file mode 100644 index 0b541edc9..000000000 --- a/STM32F3/cores/maple/libmaple/rules.mk +++ /dev/null @@ -1,53 +0,0 @@ -# Standard things -sp := $(sp).x -dirstack_$(sp) := $(d) -d := $(dir) -BUILDDIRS += $(BUILD_PATH)/$(d) - -LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH)/include -I$(LIBMAPLE_MODULE_SERIES)/include -LIBMAPLE_PRIVATE_INCLUDES := -I$(LIBMAPLE_PATH) - -# Local flags -CFLAGS_$(d) = $(LIBMAPLE_PRIVATE_INCLUDES) $(LIBMAPLE_INCLUDES) -Wall -Werror - -# Local rules and targets -cSRCS_$(d) := adc.c -cSRCS_$(d) += dac.c -cSRCS_$(d) += dma.c -cSRCS_$(d) += exti.c -cSRCS_$(d) += flash.c -cSRCS_$(d) += gpio.c -cSRCS_$(d) += iwdg.c -cSRCS_$(d) += nvic.c -cSRCS_$(d) += pwr.c -cSRCS_$(d) += rcc.c -cSRCS_$(d) += spi.c -cSRCS_$(d) += systick.c -ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),stm32f2 stm32f3)) # SYSCFG peripheral available only on F2, F3 -cSRCS_$(d) += syscfg.c -endif -cSRCS_$(d) += timer.c -cSRCS_$(d) += usart.c -cSRCS_$(d) += usart_private.c -cSRCS_$(d) += util.c -sSRCS_$(d) := exc.S -ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),stm32f1 stm32f3)) # TODO port I2C to F2 -cSRCS_$(d) += i2c.c -cSRCS_$(d) += bkp.c -endif - -cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) -sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%) - -OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) -DEPS_$(d) := $(OBJS_$(d):%.o=%.d) - -$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) -$(OBJS_$(d)): TGT_ASFLAGS := - -TGT_BIN += $(OBJS_$(d)) - -# Standard things --include $(DEPS_$(d)) -d := $(dirstack_$(sp)) -sp := $(basename $(sp)) diff --git a/STM32F3/cores/maple/libmaple/spi.c b/STM32F3/cores/maple/libmaple/spi.c deleted file mode 100644 index ec008d40c..000000000 --- a/STM32F3/cores/maple/libmaple/spi.c +++ /dev/null @@ -1,129 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/spi.c - * @author Marti Bolivar - * @brief Serial Peripheral Interface (SPI) support. - * Currently, there is no Integrated Interchip Sound (I2S) support. - */ - -#include -#include - -/* - * SPI convenience routines - */ - -/** - * @brief Initialize and reset a SPI device. - * @param dev Device to initialize and reset. - */ -void spi_init(spi_dev *dev) { - rcc_clk_enable(dev->clk_id); - rcc_reset_dev(dev->clk_id); -} - -/** - * @brief Configure and enable a SPI device as bus master. - * - * The device's peripheral will be disabled before being reconfigured. - * - * @param dev Device to configure as bus master - * @param baud Bus baud rate - * @param mode SPI mode - * @param flags Logical OR of spi_cfg_flag values. - * @see spi_cfg_flag - */ -void spi_master_enable(spi_dev *dev, - spi_baud_rate baud, - spi_mode mode, - uint32 flags) { - spi_reconfigure(dev, baud | flags | SPI_CR1_MSTR | mode); -} - -/** - * @brief Configure and enable a SPI device as a bus slave. - * - * The device's peripheral will be disabled before being reconfigured. - * - * @param dev Device to configure as a bus slave - * @param mode SPI mode - * @param flags Logical OR of spi_cfg_flag values. - * @see spi_cfg_flag - */ -void spi_slave_enable(spi_dev *dev, spi_mode mode, uint32 flags) { - spi_reconfigure(dev, flags | mode); -} - -/** - * @brief Enable a SPI peripheral - * @param dev Device to enable - */ -void spi_peripheral_enable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR1, SPI_CR1_SPE_BIT, 1); -} - -/** - * @brief Disable a SPI peripheral - * @param dev Device to disable - */ -void spi_peripheral_disable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR1, SPI_CR1_SPE_BIT, 0); -} - -/** - * @brief Enable DMA requests whenever the transmit buffer is empty - * @param dev SPI device on which to enable TX DMA requests - */ -void spi_tx_dma_enable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_TXDMAEN_BIT, 1); -} - -/** - * @brief Disable DMA requests whenever the transmit buffer is empty - * @param dev SPI device on which to disable TX DMA requests - */ -void spi_tx_dma_disable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_TXDMAEN_BIT, 0); -} - -/** - * @brief Enable DMA requests whenever the receive buffer is empty - * @param dev SPI device on which to enable RX DMA requests - */ -void spi_rx_dma_enable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_RXDMAEN_BIT, 1); -} - -/** - * @brief Disable DMA requests whenever the receive buffer is empty - * @param dev SPI device on which to disable RX DMA requests - */ -void spi_rx_dma_disable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_RXDMAEN_BIT, 0); -} diff --git a/STM32F3/cores/maple/libmaple/spi_private.h b/STM32F3/cores/maple/libmaple/spi_private.h deleted file mode 100644 index f0e0bd10f..000000000 --- a/STM32F3/cores/maple/libmaple/spi_private.h +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#ifndef _LIBMAPLE_SPI_PRIVATE_H_ -#define _LIBMAPLE_SPI_PRIVATE_H_ - -#define SPI_DEV(num) \ - { \ - .regs = SPI##num##_BASE, \ - .clk_id = RCC_SPI##num, \ - .irq_num = NVIC_SPI##num, \ - } - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32_private.h b/STM32F3/cores/maple/libmaple/stm32_private.h deleted file mode 100644 index 427417a31..000000000 --- a/STM32F3/cores/maple/libmaple/stm32_private.h +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -#ifndef _LIBMAPLE_STM32_PRIVATE_H_ -#define _LIBMAPLE_STM32_PRIVATE_H_ - -typedef enum stm32_mem_block_purpose { - STM32_BLOCK_CODE, - STM32_BLOCK_SRAM, - STM32_BLOCK_PERIPH, - STM32_BLOCK_FSMC_1_2, - STM32_BLOCK_FSMC_3_4, - STM32_BLOCK_FSMC_REG, - STM32_BLOCK_UNUSED, - STM32_BLOCK_CORTEX_INTERNAL, -} stm32_mem_block_purpose; - -static inline stm32_mem_block_purpose stm32_block_purpose(void *addr) { - return (stm32_mem_block_purpose)((unsigned)addr >> 29); -} - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_adc.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_adc.c deleted file mode 100644 index 982d6ea44..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_adc.c +++ /dev/null @@ -1,412 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/adc.c - * @author Marti Bolivar , - * Perry Hung , - * F3-port by Hanspeter Portner - * @brief STM32F3 ADC support. - */ - -#include -#include -#include - -/* - * Devices - */ - -static adc_private_data adc1_priv; -static adc_dev adc1 = { - .regs = ADC1_BASE, - .clk_id = RCC_ADC12, - .priv = &adc1_priv -}; -/** ADC1 device. */ -const adc_dev *ADC1 = &adc1; - -static adc_private_data adc2_priv; -static adc_dev adc2 = { - .regs = ADC2_BASE, - .clk_id = RCC_ADC12, - .priv = &adc2_priv -}; -/** ADC2 device. */ -const adc_dev *ADC2 = &adc2; - -#if STM32_F3_LINE == STM32_F3_LINE_303 -static adc_private_data adc3_priv; -static adc_dev adc3 = { - .regs = ADC3_BASE, - .clk_id = RCC_ADC34, - .priv = &adc3_priv -}; -/** ADC3 device. */ -const adc_dev *ADC3 = &adc3; - -static adc_private_data adc4_priv; -static adc_dev adc4 = { - .regs = ADC4_BASE, - .clk_id = RCC_ADC34, - .priv = &adc4_priv -}; -/** ADC4 device. */ -const adc_dev *ADC4 = &adc4; -#endif - -/* - * STM32F3 routines - */ - -static inline void adc_check_regular_notongoing(const adc_dev *dev) { - adc_reg_map *regs = dev->regs; - if(regs->CR & ADC_CR_ADSTART) /* check for ongoing regular channel conversion */ - { - regs->CR |= ADC_CR_ADSTP; /* stop regular channel conversion */ - while(regs->CR & ADC_CR_ADSTP) - ; /* wait for conversion to stop */ - } -} - -static inline void adc_check_injected_notongoing(const adc_dev *dev) { - adc_reg_map *regs = dev->regs; - if(regs->CR & ADC_CR_JADSTART) /* check for ongoing injected channel conversion */ - { - regs->CR |= ADC_CR_JADSTP; /* stop injected channel conversion */ - while(regs->CR & ADC_CR_JADSTP) - ; /* wait for conversion to stop */ - } -} - -void adc_set_extsel(const adc_dev *dev, adc_extsel_event event) { - adc_check_regular_notongoing(dev); - - uint32 cfgr = dev->regs->CFGR; - cfgr &= ~ADC_CFGR_EXTSEL; - cfgr |= event; - dev->regs->CFGR = cfgr; -} - -void adc_set_resolution(const adc_dev *dev, adc_resolution res) { - adc_check_regular_notongoing(dev); - adc_check_injected_notongoing(dev); - - uint32 cfgr = dev->regs->CFGR; - cfgr &= ~ADC_CFGR_RES; - cfgr |= res; - dev->regs->CFGR = cfgr; -} - -void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate) { - adc_check_regular_notongoing(dev); - adc_check_injected_notongoing(dev); - - uint32 adc_smpr1_val = 0, adc_smpr2_val = 0; - int i; - - for(i = 0; i < 9; i++) { - /* ADC_SMPR1 determines sample time for channels [1,9] */ - adc_smpr1_val |= smp_rate << (i * 3 + 3); - /* ADC_SMPR2 determines sample time for channels [10,18] */ - adc_smpr2_val |= smp_rate << (i * 3); - } - - dev->regs->SMPR1 = adc_smpr1_val; - dev->regs->SMPR2 = adc_smpr2_val; -} - -void adc_enable_scan(const adc_dev *dev) { - /* FIXME nonexistent in F3 series */ -} - -void adc_disable_scan(const adc_dev *dev) { - /* FIXME nonexistent in F3 series*/ -} - -void adc_enable_continuous(const adc_dev *dev) { - bb_peri_set_bit(&dev->regs->CFGR, ADC_CFGR_CONT_BIT, 1); -} - -void adc_disable_continuous(const adc_dev *dev) { - bb_peri_set_bit(&dev->regs->CFGR, ADC_CFGR_CONT_BIT, 0); -} - -#define BITS_PER_SQ 6 -#define SQs_PER_SQR 5 -void adc_set_conv_seq(const adc_dev *dev, const uint8 *channels, uint8 len) { - ASSERT( (0 < len) && (len <= 16) ); - uint8 i; - uint32 val = 0; - uint8 lshift; - __io uint32 *sqr = &dev->regs->SQR1; - - for (i=0; iregs; - - adc_set_conv_seq(dev, &channel, 1); - - regs->CR |= ADC_CR_ADSTART; /* start conversion */ - while (!(regs->ISR & ADC_ISR_EOC)) - ; /* wait until done */ - - return (uint16)(regs->DR & ADC_DR_RDATA); -} - -void adc_attach_interrupt(const adc_dev *dev, uint32 interrupt_flags, - void (*handler)(adc_callback_data*), void *arg) { - adc_private_data *priv = dev->priv; - priv->handler = handler; - priv->handler_flags = interrupt_flags; - priv->cb_data.arg = arg; - adc_enable_interrupts(dev, interrupt_flags); -} - -void adc_detach_interrupt(const adc_dev *dev) { - adc_private_data *priv; - adc_disable_interrupts(dev, ADC_ALL_INTERRUPTS); - priv = dev->priv; - priv->handler = NULL; - priv->handler_flags = 0; -} - -void adc_enable_interrupts(const adc_dev *dev, uint32 interrupt_flags) { - uint32 ier = dev->regs->IER; - ier |= interrupt_flags; - dev->regs->IER = ier; - _adc_enable_dev_irq(dev); -} - -void adc_disable_interrupts(const adc_dev *dev, uint32 interrupt_flags) { - /* Don't use nvic_irq_disable()! IRQs are shared among ADCs. */ - uint32 ier = dev->regs->IER; - ier &= ~interrupt_flags; - dev->regs->IER = ier; -} - -void adc_calibrate(const adc_dev *dev) { - adc_reg_map *regs = dev->regs; - - if( (regs->CR & ADC_CR_ADVREGEN) != ADC_CR_ADVREGEN_ENABLE) - adc_regulator_enable(dev); /* ensure that voltage regulator is enabled */ - - if(regs->CR & ADC_CR_ADEN) - adc_disable(dev); /* ensure that ADC is disabled */ - - regs->CR &= ~ADC_CR_ADCALDIF; /* calibrate in single-ended mode */ - regs->CR |= ADC_CR_ADCAL; /* start calibration */ - while (regs->CR & ADC_CR_ADCAL) - ; /* wait until done */ - - regs->CR |= ADC_CR_ADCALDIF; /* calibrate in differential mode */ - regs->CR |= ADC_CR_ADCAL; /* start calibration */ - while (regs->CR & ADC_CR_ADCAL) - ; /* wait until done */ -} - -void adc_set_exttrig(const adc_dev *dev, adc_exttrig_mode mode) { - adc_reg_map *regs = dev->regs; - regs->CFGR &= ~ADC_CFGR_EXTEN; - regs->CFGR |= mode; -} - -void adc_set_prescaler(adc_prescaler pre) { - if (pre & 0x10) { /* PLL is used as clock source */ - ADC12_BASE->CCR &= ~ADC_CCR_CKMODE; -#if STM32_F3_LINE == STM32_F3_LINE_303 - ADC34_BASE->CCR &= ~ADC_CCR_CKMODE; -#endif - - uint32 cfgr2 = RCC_BASE->CFGR2; - - cfgr2 &= ~RCC_CFGR2_ADC12PRES; // clear register - cfgr2 |= (uint32)pre << RCC_CFGR2_ADC12PRES_SHIFT; // set register - -#if STM32_F3_LINE == STM32_F3_LINE_303 - cfgr2 &= ~RCC_CFGR2_ADC34PRES; // clear register - cfgr2 |= (uint32)pre << RCC_CFGR2_ADC34PRES_SHIFT; // set register -#endif - - RCC_BASE->CFGR2 = cfgr2; - } else { /* AHB bus is used as clock source */ - /* FIXME does not work with current wirish booting routine */ - uint32 tmp; - - tmp = ADC12_BASE->CCR; - tmp &= ~ADC_CCR_CKMODE; - tmp |= pre << ADC_CCR_CKMODE_SHIFT; - ADC12_BASE->CCR = tmp; - -#if STM32_F3_LINE == STM32_F3_LINE_303 - tmp = ADC34_BASE->CCR; - tmp &= ~ADC_CCR_CKMODE; - tmp |= pre << ADC_CCR_CKMODE_SHIFT; - ADC34_BASE->CCR = tmp; -#endif - } -} - -void adc_foreach(void (*fn)(const adc_dev*)) { - fn(ADC1); - fn(ADC2); -#if STM32_F3_LINE == STM32_F3_LINE_303 - fn(ADC3); - fn(ADC4); -#endif -} - -void adc_config_gpio(const adc_dev *ignored, gpio_dev *gdev, uint8 bit) { - gpio_set_modef(gdev, bit, GPIO_MODE_ANALOG, GPIO_MODEF_PUPD_NONE); -} - -void adc_enable_single_swstart(const adc_dev *dev) { - int check_dev_adc = dev == ADC1; -#if STM32_F3_LINE == STM32_F3_LINE_303 - check_dev_adc = (check_dev_adc || dev == ADC3); -#endif - if (check_dev_adc) - adc_init(dev); /* FIXME hack needed for wirish, as master and slave ADC share the same reset register */ - adc_set_exttrig(dev, ADC_EXTTRIG_MODE_SOFTWARE); - adc_regulator_enable(dev); - adc_calibrate(dev); - adc_enable(dev); -} - -void adc_set_reg_seqlen(const adc_dev *dev, uint8 length) { - adc_check_regular_notongoing(dev); - - uint32 tmp = dev->regs->SQR1; - tmp &= ~ADC_SQR1_L; - tmp |= (length - 1) & ADC_SQR1_L; - dev->regs->SQR1 = tmp; -} - -void adc_enable(const adc_dev *dev) { - adc_reg_map *regs = dev->regs; - - while( (regs->CR & ADC_CR_ADVREGEN) != ADC_CR_ADVREGEN_ENABLE) - adc_regulator_enable(dev); /* ensure that voltage regulator is enabled */ - - regs->CR |= ADC_CR_ADEN; /* enable ADC */ - while (!(regs->ISR & ADC_ISR_ADRDY)) - ; /* wait until ADC is ready */ -} - -void adc_disable(const adc_dev *dev) { - adc_reg_map *regs = dev->regs; - - adc_check_regular_notongoing(dev); - adc_check_injected_notongoing(dev); - - regs->CR |= ADC_CR_ADDIS; /* disable ADC */ - while(regs->CR & ADC_CR_ADEN) - ; /* wait until ADC is effectively disabled */ -} - -void adc_regulator_enable(const adc_dev *dev) { - adc_reg_map *regs = dev->regs; - - regs->CR &= ~ADC_CR_ADVREGEN; - regs->CR |= ADC_CR_ADVREGEN_ENABLE; - - delay_us(10); /* 10us are worst case */ -} - -void adc_regulator_disable(const adc_dev *dev) { - adc_reg_map *regs = dev->regs; - - regs->CR &= ~ADC_CR_ADVREGEN; - regs->CR |= ADC_CR_ADVREGEN_DISABLE; -} - -/* - * Private API - */ - -void _adc_enable_dev_irq(const adc_dev *dev) { - if ( (dev == ADC1) || (dev == ADC2) ) - nvic_irq_enable(NVIC_ADC1_2); -#if STM32_F3_LINE == STM32_F3_LINE_303 - else { - if (dev == ADC3) - nvic_irq_enable(NVIC_ADC3); - else // dev == ADC4 - nvic_irq_enable(NVIC_ADC4); - } -#endif -} - -/* IRQ handler for adc_attach_interrupt() */ -static __always_inline void adc_irq(const adc_dev *dev) { - adc_private_data *priv = dev->priv; - uint32 irq_flags = dev->regs->ISR & priv->handler_flags; - - if (!irq_flags) { - /* The user isn't interested in this IRQ. */ - return; - } else if (priv->handler) { - priv->cb_data.irq_flags = irq_flags; - priv->handler(&priv->cb_data); - } -} - -/* - * IRQ handlers for adc_attach_interrupt() - */ -/* -void __irq_adc1_2(void) { - adc_irq(ADC1); - adc_irq(ADC2); -} - -#if STM32_F3_LINE == STM32_F3_LINE_303 -void __irq_adc3(void) { - adc_irq(ADC3); -} - -void __irq_adc4(void) { - adc_irq(ADC4); -} -#endif -*/ diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_bkp.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_bkp.c deleted file mode 100644 index f6ac4d10e..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_bkp.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/bkp.c - * @author F3-port by Hanspeter Portner - * @brief STM32F3 backup register support. - */ - -#include -#include -#include - -void bkp_init(void) { - /* Don't call pwr_init(), or you'll reset the device. We just - * need the clock. */ - rcc_clk_enable(RCC_PWR); -} - -inline __io uint32* bkp_data_register(uint8 reg) { - if (reg < 1 || reg > BKP_NR_DATA_REGS) - return NULL; - else - return (uint32*)BKP_BASE + (reg-1); // regs are accessed from 1-16 -} diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_comp.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_comp.c deleted file mode 100644 index 527be71d7..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_comp.c +++ /dev/null @@ -1,61 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/comp.c - * @author F3-port by Hanspeter Portner - * @brief STM32F3 Comparator support. - */ - -#include - -/* - * Devices - */ - -static comp_dev comp1 = { .regs = COMP1_BASE }; const comp_dev *COMP1 = &comp1; -static comp_dev comp2 = { .regs = COMP2_BASE }; const comp_dev *COMP2 = &comp2; -static comp_dev comp3 = { .regs = COMP3_BASE }; const comp_dev *COMP3 = &comp3; -static comp_dev comp4 = { .regs = COMP4_BASE }; const comp_dev *COMP4 = &comp4; -static comp_dev comp5 = { .regs = COMP5_BASE }; const comp_dev *COMP5 = &comp5; -static comp_dev comp6 = { .regs = COMP6_BASE }; const comp_dev *COMP6 = &comp6; -static comp_dev comp7 = { .regs = COMP7_BASE }; const comp_dev *COMP7 = &comp7; - -void __irq_comp123(void) { - //TODO -} - -void __irq_com456(void) { - //TODO -} - -void __irq_comp7(void) { - //TODO -} - -/* TODO - * actually implement me ;-) - */ diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_dma.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_dma.c deleted file mode 100644 index 317c28385..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_dma.c +++ /dev/null @@ -1,364 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/dma.c - * @author Marti Bolivar , - * Original implementation by Michael Hope, - * F3-port by Hanspeter Portner - * @brief STM32F3 DMA support. - */ - -#include -#include - -/* Hack to ensure inlining in dma_irq_handler() */ -#define DMA_GET_HANDLER(dev, tube) (dev->handlers[tube - 1].handler) -#include "dma_private.h" - -/* - * Devices - */ - -static dma_dev dma1 = { - .regs = DMA1_BASE, - .clk_id = RCC_DMA1, - .handlers = {{ .handler = NULL, .irq_line = NVIC_DMA_CH1 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH2 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH3 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH4 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH5 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH6 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH7 }}, -}; -/** STM32F3 DMA1 device */ -dma_dev *DMA1 = &dma1; - -static dma_dev dma2 = { - .regs = DMA2_BASE, - .clk_id = RCC_DMA2, - .handlers = {{ .handler = NULL, .irq_line = NVIC_DMA2_CH1 }, - { .handler = NULL, .irq_line = NVIC_DMA2_CH2 }, - { .handler = NULL, .irq_line = NVIC_DMA2_CH3 }, - { .handler = NULL, .irq_line = NVIC_DMA2_CH4 }, - { .handler = NULL, .irq_line = NVIC_DMA2_CH5 }}, -}; -/** STM32F3 DMA2 device */ -dma_dev *DMA2 = &dma2; - -/* - * Auxiliary routines - */ - -/* Can channel serve cfg->tube_req_src? */ -static int cfg_req_ok(dma_channel channel, dma_tube_config *cfg) { - return (cfg->tube_req_src & 0x7) == channel; -} - -/* Can dev serve cfg->tube_req_src? */ -static int cfg_dev_ok(dma_dev *dev, dma_tube_config *cfg) { - return (rcc_clk_id)(cfg->tube_req_src >> 3) == dev->clk_id; -} - -/* Is addr acceptable for use as DMA src/dst? */ -static int cfg_mem_ok(__io void *addr) { - enum dma_atype atype = _dma_addr_type(addr); - return atype == DMA_ATYPE_MEM || atype == DMA_ATYPE_PER; -} - -/* Is the direction implied by src->dst supported? */ -static int cfg_dir_ok(dma_tube_config *cfg) { - /* We can't do peripheral->peripheral transfers. */ - return ((_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM) || - (_dma_addr_type(cfg->tube_dst) == DMA_ATYPE_MEM)); -} - -static int preconfig_check(dma_dev *dev, dma_channel channel, - dma_tube_config *cfg) { - if (!cfg_req_ok(channel, cfg)) { - return -DMA_TUBE_CFG_EREQ; - } - if (cfg->tube_nr_xfers > 65535) { - return -DMA_TUBE_CFG_ENDATA; - } - if (!cfg_dev_ok(dev, cfg)) { - return -DMA_TUBE_CFG_EDEV; - } - if (!cfg_mem_ok(cfg->tube_src)) { - return -DMA_TUBE_CFG_ESRC; - } - if (!cfg_mem_ok(cfg->tube_dst)) { - return -DMA_TUBE_CFG_EDST; - } - if (!cfg_dir_ok(cfg)) { - return -DMA_TUBE_CFG_EDIR; - } - return DMA_TUBE_CFG_SUCCESS; -} - -static inline void set_ccr(dma_tube_reg_map *chregs, - dma_xfer_size msize, int minc, - dma_xfer_size psize, int pinc, - uint32 other_flags) { - chregs->CCR = ((msize << 10) | (psize << 8) | - (minc ? DMA_CCR_MINC : 0) | (pinc ? DMA_CCR_PINC : 0) | - other_flags); -} - -static inline uint32 cfg_ccr_flags(unsigned tube_flags) { - /* DMA_CFG_SRC_INC and DMA_CFG_DST_INC are special */ - return tube_flags & ~(DMA_CFG_SRC_INC | DMA_CFG_DST_INC); -} - -/* Configure chregs according to cfg, where cfg->tube_dst is peripheral. */ -static int config_to_per(dma_tube_reg_map *chregs, dma_tube_config *cfg) { - /* Check that ->tube_src is memory (if it's anything else, we - * shouldn't have been called). */ - ASSERT(_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM); - - set_ccr(chregs, - cfg->tube_src_size, cfg->tube_flags & DMA_CFG_SRC_INC, - cfg->tube_dst_size, cfg->tube_flags & DMA_CFG_DST_INC, - (cfg_ccr_flags(cfg->tube_flags) | DMA_CCR_DIR_FROM_MEM)); - chregs->CNDTR = cfg->tube_nr_xfers; - chregs->CMAR = (uint32)cfg->tube_src; - chregs->CPAR = (uint32)cfg->tube_dst; - return DMA_TUBE_CFG_SUCCESS; -} - -/* Configure chregs according to cfg, where cfg->tube_dst is memory. */ -static int config_to_mem(dma_tube_reg_map *chregs, dma_tube_config *cfg) { - uint32 mem2mem; - - if ((_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM) && - (cfg->tube_flags & DMA_CFG_CIRC)) { - /* Can't do mem-to-mem and circular mode */ - return -DMA_TUBE_CFG_ECFG; - } - - mem2mem = (_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM ? - DMA_CCR_MEM2MEM : 0); - set_ccr(chregs, - cfg->tube_dst_size, cfg->tube_flags & DMA_CFG_DST_INC, - cfg->tube_src_size, cfg->tube_flags & DMA_CFG_SRC_INC, - (cfg_ccr_flags(cfg->tube_flags) | - DMA_CCR_DIR_FROM_PER | - mem2mem)); - chregs->CNDTR = cfg->tube_nr_xfers; - chregs->CMAR = (uint32)cfg->tube_dst; - chregs->CPAR = (uint32)cfg->tube_src; - return DMA_TUBE_CFG_SUCCESS; -} - -/* - * Routines - */ - -int dma_tube_cfg(dma_dev *dev, dma_channel channel, dma_tube_config *cfg) { - dma_tube_reg_map *chregs; - int ret = preconfig_check(dev, channel, cfg); - - if (ret < 0) { - return ret; - } - - dma_disable(dev, channel); /* Must disable before reconfiguring */ - dma_clear_isr_bits(dev, channel); /* For sanity and consistency - * with STM32F2. */ - - chregs = dma_tube_regs(dev, channel); - switch (_dma_addr_type(cfg->tube_dst)) { - case DMA_ATYPE_PER: - ret = config_to_per(chregs, cfg); - break; - case DMA_ATYPE_MEM: - ret = config_to_mem(chregs, cfg); - break; - default: - /* Can't happen */ - ASSERT(0); - return -DMA_TUBE_CFG_ECFG; - } - if (ret < 0) { - return ret; - } - chregs->CNDTR = cfg->tube_nr_xfers; - return DMA_TUBE_CFG_SUCCESS; -} - -void dma_set_priority(dma_dev *dev, - dma_channel channel, - dma_priority priority) { - dma_channel_reg_map *channel_regs; - uint32 ccr; - - ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); - - channel_regs = dma_channel_regs(dev, channel); - ccr = channel_regs->CCR; - ccr &= ~DMA_CCR_PL; - ccr |= (priority << 12); - channel_regs->CCR = ccr; -} - -void dma_set_num_transfers(dma_dev *dev, - dma_channel channel, - uint16 num_transfers) { - dma_channel_reg_map *channel_regs; - - ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); - - channel_regs = dma_channel_regs(dev, channel); - channel_regs->CNDTR = num_transfers; -} - -void dma_attach_interrupt(dma_dev *dev, dma_channel channel, - void (*handler)(void)) { - DMA_GET_HANDLER(dev, channel) = handler; - nvic_irq_enable(dev->handlers[channel - 1].irq_line); -} - -void dma_detach_interrupt(dma_dev *dev, dma_channel channel) { - /* Don't use nvic_irq_disable()! Think about DMA2 channels 4 and 5. */ - dma_channel_regs(dev, channel)->CCR &= ~0xF; - DMA_GET_HANDLER(dev, channel) = NULL; -} - -void dma_enable(dma_dev *dev, dma_channel channel) { - dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel); - bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 1); -} - -void dma_disable(dma_dev *dev, dma_channel channel) { - dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel); - bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 0); -} - -dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) { - /* Grab and clear the ISR bits. */ - uint8 status_bits = dma_get_isr_bits(dev, channel); - dma_clear_isr_bits(dev, channel); - - /* If the channel global interrupt flag is cleared, then - * something's very wrong. */ - ASSERT(status_bits & 0x1); - /* If GIF is set, then some other flag should be set, barring - * something unexpected (e.g. the user making an unforeseen IFCR - * write). */ - ASSERT(status_bits != 0x1); - - /* ISR flags get set even if the corresponding interrupt enable - * bits in the channel's configuration register are cleared, so we - * can't use a switch here. - * - * Don't change the order of these if statements. */ - if (status_bits & 0x8) { - return DMA_TRANSFER_ERROR; - } else if (status_bits & 0x2) { - return DMA_TRANSFER_COMPLETE; - } else if (status_bits & 0x4) { - return DMA_TRANSFER_HALF_COMPLETE; - } - - /* If we get here, one of our assumptions has been violated, but - * the debug level is too low for the above ASSERTs() to have had - * any effect. In order to fail fast, mimic the DMA controller's - * behavior when an error occurs. */ - dma_disable(dev, channel); - return DMA_TRANSFER_ERROR; -} - -void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *addr) { - dma_channel_reg_map *chan_regs; - - ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); - - chan_regs = dma_channel_regs(dev, channel); - chan_regs->CMAR = (uint32)addr; -} - -void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *addr) { - dma_channel_reg_map *chan_regs; - - ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); - - chan_regs = dma_channel_regs(dev, channel); - chan_regs->CPAR = (uint32)addr; -} - -/* - * IRQ handlers - */ - -void __irq_dma1_ch1(void) { - dma_irq_handler(DMA1, DMA_CH1); -} - -void __irq_dma1_ch2(void) { - dma_irq_handler(DMA1, DMA_CH2); -} - -void __irq_dma1_ch3(void) { - dma_irq_handler(DMA1, DMA_CH3); -} - -void __irq_dma1_ch4(void) { - dma_irq_handler(DMA1, DMA_CH4); -} - -void __irq_dma1_ch5(void) { - dma_irq_handler(DMA1, DMA_CH5); -} - -void __irq_dma1_ch6(void) { - dma_irq_handler(DMA1, DMA_CH6); -} - -void __irq_dma1_ch7(void) { - dma_irq_handler(DMA1, DMA_CH7); -} - -void __irq_dma2_ch1(void) { - dma_irq_handler(DMA2, DMA_CH1); -} - -void __irq_dma2_ch2(void) { - dma_irq_handler(DMA2, DMA_CH2); -} - -void __irq_dma2_ch3(void) { - dma_irq_handler(DMA2, DMA_CH3); -} - -void __irq_dma2_ch4(void) { - dma_irq_handler(DMA2, DMA_CH4); -} - -void __irq_dma2_ch5(void) { - dma_irq_handler(DMA2, DMA_CH5); -} diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_exti.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_exti.c deleted file mode 100644 index 44f0057f4..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_exti.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file libmaple/stm32f3/exti.c - * @author F3-port by Hanspeter Portner - * @brief STM32F3 EXTI. - */ - -#include -#include -#include "exti_private.h" - -void exti_select(exti_num num, exti_cfg cfg) { - exti_do_select(&SYSCFG_BASE->EXTICR[num / 4], num, cfg); -} diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_gpio.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_gpio.c deleted file mode 100644 index 45992a411..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_gpio.c +++ /dev/null @@ -1,169 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/gpio.c - * @author F3-port by Hanspeter Portner - * @brief STM32F3 GPIO. - */ - -#include -#include -#include - -/* - * GPIO devices - */ - -gpio_dev gpioa = { - .regs = GPIOA_BASE, - .clk_id = RCC_GPIOA, - .exti_port = EXTI_PA, -}; -/** GPIO port A device. */ -gpio_dev* const GPIOA = &gpioa; - -gpio_dev gpiob = { - .regs = GPIOB_BASE, - .clk_id = RCC_GPIOB, - .exti_port = EXTI_PB, -}; -/** GPIO port B device. */ -gpio_dev* const GPIOB = &gpiob; - -gpio_dev gpioc = { - .regs = GPIOC_BASE, - .clk_id = RCC_GPIOC, - .exti_port = EXTI_PC, -}; -/** GPIO port C device. */ -gpio_dev* const GPIOC = &gpioc; - -gpio_dev gpiod = { - .regs = GPIOD_BASE, - .clk_id = RCC_GPIOD, - .exti_port = EXTI_PD, -}; -/** GPIO port D device. */ -gpio_dev* const GPIOD = &gpiod; - -gpio_dev gpioe = { - .regs = GPIOE_BASE, - .clk_id = RCC_GPIOE, - .exti_port = EXTI_PE, -}; -/** GPIO port E device. */ -gpio_dev* const GPIOE = &gpioe; - -gpio_dev gpiof = { - .regs = GPIOF_BASE, - .clk_id = RCC_GPIOF, - .exti_port = EXTI_PF, -}; -/** GPIO port F device. */ -gpio_dev* const GPIOF = &gpiof; - -/* - * GPIO routines - */ - -/** - * Initialize and reset all available GPIO devices. - */ -void gpio_init_all(void) { - gpio_init(GPIOA); - gpio_init(GPIOB); - gpio_init(GPIOC); - gpio_init(GPIOD); - gpio_init(GPIOE); - gpio_init(GPIOF); -} - -/** - * @brief Set the mode of a GPIO pin. - * @param dev GPIO device. - * @param bit Bit on dev whose mode to set, 0--15. - * @param mode Mode to set the pin to. - * @param flags Flags to modify basic mode configuration - */ -void gpio_set_modef(gpio_dev *dev, - uint8 bit, - gpio_pin_mode mode, - unsigned flags) { - gpio_reg_map *regs = dev->regs; - unsigned shift = bit * 2; - uint32 tmp; - - /* Mode */ - tmp = regs->MODER; - tmp &= ~(0x3 << shift); - tmp |= mode << shift; - regs->MODER = tmp; - - /* Output type */ - bb_peri_set_bit(®s->OTYPER, bit, flags & 0x1); - - /* Speed */ - tmp = regs->OSPEEDR; - tmp &= ~(0x3 << shift); - tmp |= ((flags >> 1) & 0x3) << shift; - regs->OSPEEDR = tmp; - - /* Pull-up/pull-down */ - tmp = regs->PUPDR; - tmp &= ~(0x3 << shift); - tmp |= ((flags >> 3) & 0x3) << shift; - regs->PUPDR = tmp; -} - -/** - * @brief Set a pin's alternate function. - * - * The pin must have its mode set to GPIO_MODE_AF for this to take - * effect. - * - * @param dev Device whose pin to configure. - * @param bit Pin whose alternate function to set. - * @param af Alternate function to use for pin. - * @see gpio_set_modef() - */ -void gpio_set_af(gpio_dev *dev, uint8 bit, gpio_af af) { - __io uint32 *afr; - unsigned shift; - uint32 tmp; - if (bit >= 8) { - afr = &dev->regs->AFRH; - shift = 4 * (bit - 8); - } else{ - afr = &dev->regs->AFRL; - shift = 4 * bit; - } - tmp = *afr; - tmp &= ~(0xF << shift); - tmp |= (af << shift); - *afr = tmp; -} diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_i2c.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_i2c.c deleted file mode 100644 index 241298734..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_i2c.c +++ /dev/null @@ -1,319 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/i2c.c - * @author F3-port by Hanspeter Portner - * @brief STM32F3 I2C support - */ - -#include "i2c_private.h" -#include -#include - -/* - * Devices - */ - -/* on GPIO_AF_4 (PA14,PA15) (PB7,PB6) (PB9,PB8)*/ -static i2c_dev i2c1 = I2C_DEV_OLD(1, &gpiob, 7, 6); -/** STM32F3 I2C device 1 */ -i2c_dev* const I2C1 = &i2c1; - -/* on GPIO_AF_4 (PA10,PA9) (PF0,PF1) (PF0,PF6)*/ -static i2c_dev i2c2 = I2C_DEV_OLD(2, &gpioa, 10, 9); -/** STM32F3 I2C device 2 */ -i2c_dev* const I2C2 = &i2c2; - -/* - * Routines - */ - -void i2c_config_gpios(const i2c_dev *dev) { - gpio_set_modef(sda_port(dev), dev->sda_pin, GPIO_MODE_AF, GPIO_MODEF_TYPE_OD); - gpio_set_modef(scl_port(dev), dev->scl_pin, GPIO_MODE_AF, GPIO_MODEF_TYPE_OD); - - gpio_set_af(sda_port(dev), dev->sda_pin, GPIO_AF_4); - gpio_set_af(scl_port(dev), dev->scl_pin, GPIO_AF_4); -} - -void i2c_master_release_bus(const i2c_dev *dev) { - gpio_write_bit(scl_port(dev), dev->scl_pin, 1); /* TODO check this */ - gpio_write_bit(sda_port(dev), dev->sda_pin, 1); - - i2c_config_gpios(dev); -} - -int32 wait_for_state_change(i2c_dev *dev, - i2c_state state, - uint32 timeout) { - //FIXME not yet used on F3 - return 1; -} - -void i2c_bus_reset(const i2c_dev *dev) { - //FIXME not yet used on F3 -} - -void _i2c_software_reset(i2c_dev *dev) { - dev->regs->CR1 &= ~I2C_CR1_PE; - while(dev->regs->CR1 & I2C_CR1_PE) - ; - dev->regs->CR1 |= I2C_CR1_PE; -} - -void i2c_master_enable(i2c_dev *dev, uint32 flags) { - /* Bring the peripheral down for configuration */ - i2c_peripheral_disable(dev); - - /* Reset the bus when requested so */ - if (flags & I2C_BUS_RESET) - i2c_bus_reset(dev); - - /* Turn on the clock and set GPIO modes */ - i2c_init(dev); - i2c_config_gpios(dev); - - /* Configure analog and digital filters */ - /* TODO ANFOFF, DNF */ - - /* Configure the clock and rise time */ - dev->regs->TIMINGR = I2C_TIMING_10_kHz; - - /* Configure NOSTRETCH behaviour */ - /* TODO NOSTRETCH */ - - /* Enable all interrupts */ /* FIXME not yet used on F3 */ - //nvic_irq_enable(dev->ev_nvic_line); - //nvic_irq_enable(dev->er_nvic_line); - //i2c_enable_irq(dev, 0xFE); /* All interrupts */ - - /* Make it go! */ - i2c_peripheral_enable(dev); - - dev->state = I2C_STATE_IDLE; -} - -static void _i2c_master_xmit(i2c_dev *dev, i2c_msg *msg) { - uint32 cr2; - uint32 isr; - uint16 remaining = msg->length; - msg->xferred = 0; - uint8 *ptr = msg->data; /* pointer to data buffer */ - - while (remaining > 0) { - uint32 reload = remaining > 0xFF ? I2C_CR2_RELOAD : 0U; - uint16 size = remaining >= 0xFF ? 0xFF : remaining & 0xFF; - uint32 nbytes = size << I2C_CR2_NBYTES_SHIFT; - - cr2 = dev->regs->CR2; - cr2 &= ~(I2C_CR2_RELOAD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN); - cr2 |= reload | nbytes; - dev->regs->CR2 = cr2; - - if (msg->xferred == 0) /* first loop iteration? */ - dev->regs->CR2 |= I2C_CR2_START; /* generate START condition */ - - while (ptr < msg->data + msg->xferred + size) { - while ( !( (isr = dev->regs->ISR) & (I2C_ISR_NACKF | I2C_ISR_TXIS) ) ) - ; /* wait until ready for the next byte or NACK*/ - - if (isr & I2C_ISR_TXIS) - dev->regs->TXDR = *ptr++; /* byte to send */ - else { /* NACKF */ - dev->regs->ICR |= I2C_ICR_NACKCF; /* clear NACK flag */ - dev->regs->CR2 |= I2C_CR2_STOP; /* generate STOP condition */ - return; /* STOP condition is automatically generated */ - } - } - - if (reload) - while ( !(dev->regs->ISR & I2C_ISR_TCR) ) - ; /* wait for transmission reload complete */ - - remaining -= size; - msg->xferred += size; - } - - while ( !(dev->regs->ISR & I2C_ISR_TC) ) - ; /* wait for transmission complete */ - - dev->regs->CR2 |= I2C_CR2_STOP; /* generate STOP condition */ - - while ( !(dev->regs->ISR & I2C_ISR_STOPF) ) - ; /* wait for STOP flag */ - - dev->regs->ICR |= I2C_ICR_STOPCF; /* clear STOP flag */ -} - -static void _i2c_master_recv(i2c_dev *dev, i2c_msg *msg) { - uint32 cr2; - uint16 remaining = msg->length; - msg->xferred = 0; - uint8 *ptr = msg->data; /* pointer to data buffer */ - - while (remaining > 0) { - uint32 reload = remaining > 0xFF ? I2C_CR2_RELOAD : 0U; - uint16 size = remaining >= 0xFF ? 0xFF : remaining & 0xFF; - uint32 nbytes = size << I2C_CR2_NBYTES_SHIFT; - - cr2 = dev->regs->CR2; - cr2 &= ~(I2C_CR2_RELOAD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN); - cr2 |= reload | nbytes | I2C_CR2_RD_WRN; - dev->regs->CR2 = cr2; - - if (msg->xferred == 0) /* first loop iteration? */ - dev->regs->CR2 |= I2C_CR2_START; /* generate START condition */ - - while (ptr < msg->data + msg->xferred + size) { - while ( !(dev->regs->ISR & I2C_ISR_RXNE) ) - ; /* wait for next byte */ - - *ptr++ = dev->regs->RXDR & I2C_RXDR_RXDATA; /* read byte */ - } - - if (reload) - while ( !(dev->regs->ISR & I2C_ISR_TCR) ) - ; /* wait for transmission reload complete */ - - remaining -= size; - msg->xferred += size; - } - - while ( !(dev->regs->ISR & I2C_ISR_TC)) - ; /* wait for transmission complete */ - - dev->regs->CR2 |= I2C_CR2_STOP; /* generate STOP condition */ - - while ( !(dev->regs->ISR & I2C_ISR_STOPF) ) - ; /* wait for STOP flag */ - - dev->regs->ICR |= I2C_ICR_STOPCF; /* clear STOP flag */ -} - -int32 i2c_master_xfer(i2c_dev *dev, - i2c_msg *msgs, - uint16 num, - uint32 timeout) { - i2c_msg *msg; - - ASSERT(dev->state == I2C_STATE_IDLE); - - dev->msg = msgs; - dev->msgs_left = num; - dev->timestamp = systick_uptime(); /* FIXME implement handling of timeout */ - dev->state = I2C_STATE_BUSY; - - /* loop over messages */ - for (msg = dev->msg; dev->msgs_left; dev->msgs_left--, msg++) { - /* set slave address and direction*/ - uint32 addr = msg->flags & I2C_MSG_10BIT_ADDR - ? I2C_CR2_ADD10 | (msg->addr << I2C_CR2_SADD_10_BIT_SHIFT) - : msg->addr << I2C_CR2_SADD_7_BIT_SHIFT; - uint32 rd = msg->flags & I2C_MSG_READ ? I2C_CR2_RD_WRN : 0U; - uint32 cr2 = dev->regs->CR2; - cr2 &= ~(I2C_CR2_HEAD10R | I2C_CR2_ADD10 | I2C_CR2_SADD_10_BIT | I2C_CR2_RD_WRN); - cr2 |= rd | addr; - dev->regs->CR2 = cr2; - - if (rd) - _i2c_master_recv(dev, msg); - else - _i2c_master_xmit(dev, msg); - } - - dev->state = I2C_STATE_IDLE; - - return 0; /* FIXME implement error handling*/ -} - -void i2c_start_condition(i2c_dev *dev) { - dev->regs->CR2 |= I2C_CR2_START; /* generate START condition */ -} - -void i2c_stop_condition(i2c_dev *dev) { - dev->regs->CR2 |= I2C_CR2_STOP; /* generate STOP condition */ - - while ( !(dev->regs->ISR & I2C_ISR_STOPF) ) - ; /* wait for STOP flag */ - - dev->regs->ICR |= I2C_ICR_STOPCF; /* clear STOP flag */ -} - -void i2c_enable_irq(i2c_dev *dev, uint32 irqs) { - dev->regs->CR1 |= irqs; -} - -void i2c_disable_irq(i2c_dev *dev, uint32 irqs) { - dev->regs->CR1 &= ~irqs; -} - -/* ACK/NACK */ -void i2c_enable_ack(i2c_dev *dev) { - //FIXME nonexistant on F3 -} - -void i2c_disable_ack(i2c_dev *dev) { - //FIXME nonexistant on F3 -} - -void i2c_write(i2c_dev *dev, uint8 byte) { - //FIXME proper handling of ISR - dev->regs->TXDR = byte; -} - -uint8 i2c_read(i2c_dev *dev) { - //FIXME proper handling of ISR - return dev->regs->RXDR & I2C_RXDR_RXDATA; -} - -void _i2c_irq_handler(i2c_dev *dev) { - //FIXME not yet used on F3 -} - -void _i2c_irq_error_handler(i2c_dev *dev) { - //FIXME not yet used on F3 -} - -/* - * IRQ handlers - */ - -void __irq_i2c1_ev(void) { - _i2c_irq_handler(I2C1); -} - -void __irq_i2c2_ev(void) { - _i2c_irq_handler(I2C2); -} - -void __irq_i2c1_er(void) { - _i2c_irq_error_handler(I2C1); -} - -void __irq_i2c2_er(void) { - _i2c_irq_error_handler(I2C2); -} diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_opamp.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_opamp.c deleted file mode 100644 index c6ec0d5cb..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_opamp.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/opamp.c - * @author F3-port by Hanspeter Portner - * @brief STM32F3 OpAmp support. - */ - -#include - -/* - * Devices - */ - -static opamp_dev opamp1 = { .regs = OPAMP1_BASE }; const opamp_dev *OPAMP1 = &opamp1; -static opamp_dev opamp2 = { .regs = OPAMP2_BASE }; const opamp_dev *OPAMP2 = &opamp2; -static opamp_dev opamp3 = { .regs = OPAMP3_BASE }; const opamp_dev *OPAMP3 = &opamp3; -static opamp_dev opamp4 = { .regs = OPAMP4_BASE }; const opamp_dev *OPAMP4 = &opamp4; - -/* TODO - * actually implement me ;-) - */ diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_rcc.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_rcc.c deleted file mode 100644 index 4099e8001..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_rcc.c +++ /dev/null @@ -1,149 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/rcc.c - * @author F3-port by Hanspeter Portner - * @brief STM32F3 RCC. - */ - -#include -#include -#include - -#include "rcc_private.h" - -#define APB1 RCC_APB1 -#define APB2 RCC_APB2 -#define AHB RCC_AHB - -/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset - * register bit numbers. */ -const struct rcc_dev_info rcc_dev_table[] = { - [RCC_GPIOA] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPAEN_BIT }, - [RCC_GPIOB] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPBEN_BIT }, - [RCC_GPIOC] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPCEN_BIT }, - [RCC_GPIOD] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPDEN_BIT }, - [RCC_GPIOE] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPEEN_BIT }, - [RCC_GPIOF] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPFEN_BIT }, - - [RCC_ADC12] = { .clk_domain = AHB, .line_num = RCC_AHBENR_ADC12EN_BIT}, -#if STM32_F3_LINE == STM32_F3_LINE_303 - [RCC_ADC34] = { .clk_domain = AHB, .line_num = RCC_AHBENR_ADC34EN_BIT }, -#endif - - [RCC_DAC] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_DACEN_BIT }, - - [RCC_DMA1] = { .clk_domain = AHB, .line_num = RCC_AHBENR_DMA1EN_BIT }, - [RCC_DMA2] = { .clk_domain = AHB, .line_num = RCC_AHBENR_DMA2EN_BIT }, - - [RCC_I2C1] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_I2C1EN_BIT }, - [RCC_I2C2] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_I2C2EN_BIT }, - - [RCC_SPI1] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_SPI1EN_BIT }, - [RCC_SPI2] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_SPI2EN_BIT }, - [RCC_SPI3] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_SPI3EN_BIT }, - - [RCC_USART1] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_USART1EN_BIT }, - [RCC_USART2] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_USART2EN_BIT }, - [RCC_USART3] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_USART3EN_BIT }, -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - [RCC_UART4] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_UART4EN_BIT }, - [RCC_UART5] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_UART5EN_BIT }, -#endif - - [RCC_TIMER1] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_TIM1EN_BIT }, - [RCC_TIMER2] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_TIM2EN_BIT }, - [RCC_TIMER3] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_TIM3EN_BIT }, - [RCC_TIMER4] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_TIM4EN_BIT }, - [RCC_TIMER6] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_TIM6EN_BIT }, -#if STM32_F3_LINE == STM32_F3_LINE_303 - [RCC_TIMER7] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_TIM7EN_BIT }, - [RCC_TIMER8] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_TIM8EN_BIT }, -#endif - [RCC_TIMER15] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_TIM15EN_BIT }, - [RCC_TIMER16] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_TIM16EN_BIT }, - [RCC_TIMER17] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_TIM17EN_BIT }, - - [RCC_SYSCFG] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_SYSCFGEN_BIT }, - [RCC_PWR] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_PWREN_BIT }, - [RCC_CRC] = { .clk_domain = AHB, .line_num = RCC_AHBENR_CRCEN_BIT }, - [RCC_FLITF] = { .clk_domain = AHB, .line_num = RCC_AHBENR_FLITFEN_BIT }, - [RCC_SRAM] = { .clk_domain = AHB, .line_num = RCC_AHBENR_SRAMEN_BIT }, - [RCC_USB] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_USBEN_BIT }, -}; - -/* pll_cfg->data must point to a valid struct stm32f3_rcc_pll_data. */ -void rcc_configure_pll(rcc_pll_cfg *pll_cfg) { - stm32f3_rcc_pll_data *data = pll_cfg->data; - rcc_pll_multiplier pll_mul = data->pll_mul; - rcc_prediv_divider pclk_prediv = data->pclk_prediv; //TODO use this!!! - uint32 cfgr; - uint32 cfgr2; - - /* Check that the PLL is disabled. */ - ASSERT_FAULT(!rcc_is_clk_on(RCC_CLK_PLL)); - - cfgr2 = RCC_BASE->CFGR2; - cfgr2 &= ~(RCC_CFGR2_PREDIV); - cfgr2 |= pclk_prediv; - RCC_BASE->CFGR2 = cfgr2; - - cfgr = RCC_BASE->CFGR; - cfgr &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL); - cfgr |= pll_cfg->pllsrc | pll_mul; - RCC_BASE->CFGR = cfgr; -} - -void rcc_clk_enable(rcc_clk_id id) { - static __io uint32* enable_regs[] = { - [APB1] = &RCC_BASE->APB1ENR, - [APB2] = &RCC_BASE->APB2ENR, - [AHB] = &RCC_BASE->AHBENR, - }; - rcc_do_clk_enable(enable_regs, id); -} - -void rcc_reset_dev(rcc_clk_id id) { - static __io uint32* reset_regs[] = { - [APB1] = &RCC_BASE->APB1RSTR, - [APB2] = &RCC_BASE->APB2RSTR, - [AHB] = &RCC_BASE->AHBRSTR, - }; - rcc_do_reset_dev(reset_regs, id); -} - -void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { - static const uint32 masks[] = { - [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE, - [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1, - [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2, - [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE, - }; - rcc_do_set_prescaler(masks, prescaler, divider); -} diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_spi.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_spi.c deleted file mode 100644 index 3fafa5217..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_spi.c +++ /dev/null @@ -1,143 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/spi.c - * @author Marti Bolivar , - * F3-port by Hanspeter Portner - * @brief STM32F3 SPI/I2S. - */ - -#include -#include -#include "spi_private.h" - -/* - * Devices - */ - -static spi_dev spi1 = SPI_DEV(1); -static spi_dev spi2 = SPI_DEV(2); -static spi_dev spi3 = SPI_DEV(3); - -spi_dev *SPI1 = &spi1; -spi_dev *SPI2 = &spi2; -spi_dev *SPI3 = &spi3; - -/* - * Routines - */ - -void spi_config_gpios(spi_dev *dev, - uint8 as_master, - gpio_dev *nss_dev, - uint8 nss_bit, - gpio_dev *comm_dev, - uint8 sck_bit, - uint8 miso_bit, - uint8 mosi_bit) { - gpio_set_modef(nss_dev, nss_bit, GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - gpio_set_modef(comm_dev, sck_bit, GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - gpio_set_modef(comm_dev, miso_bit, GPIO_MODE_AF, GPIO_MODEF_PUPD_NONE); - gpio_set_modef(comm_dev, mosi_bit, GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - - if ( (dev == SPI1) || (dev == SPI2) ) - { - gpio_set_af(nss_dev, nss_bit, GPIO_AF_5); - gpio_set_af(comm_dev, sck_bit, GPIO_AF_5); - gpio_set_af(comm_dev, miso_bit, GPIO_AF_5); - gpio_set_af(comm_dev, mosi_bit, GPIO_AF_5); - } - else if (dev == SPI3) - { - gpio_set_af(nss_dev, nss_bit, GPIO_AF_6); - gpio_set_af(comm_dev, sck_bit, GPIO_AF_6); - gpio_set_af(comm_dev, miso_bit, GPIO_AF_6); - gpio_set_af(comm_dev, mosi_bit, GPIO_AF_6); - } -} - -void spi_foreach(void (*fn)(spi_dev*)) { - fn(SPI1); - fn(SPI2); - fn(SPI3); -} - -void spi_data_size(struct spi_dev *dev, spi_ds ds) { - uint8 byte_frame = ds <= SPI_DATA_SIZE_8_BIT; - uint32 cr2 = dev->regs->CR2; - cr2 &= ~(SPI_CR2_DS | SPI_CR2_FRXTH); - cr2 |= ds; - if (byte_frame) - cr2 |= SPI_CR2_FRXTH; - dev->regs->CR2 = cr2; -} - -/* - * SPI auxiliary routines - */ -void spi_reconfigure(spi_dev *dev, uint32 cr1_config) { - spi_irq_disable(dev, SPI_INTERRUPTS_ALL); - spi_peripheral_disable(dev); - - uint8 byte_frame = (dev->regs->CR2 & SPI_CR2_DS) <= SPI_DATA_SIZE_8_BIT; - uint32 cr2 = dev->regs->CR2; - cr2 &= ~SPI_CR2_FRXTH; - if (byte_frame) - cr2 |= SPI_CR2_FRXTH; - dev->regs->CR2 = cr2; - - dev->regs->CR1 = cr1_config; - spi_peripheral_enable(dev); -} - -uint16 spi_rx_reg(spi_dev *dev) { - uint8 byte_frame = (dev->regs->CR2 & SPI_CR2_DS) <= SPI_DATA_SIZE_8_BIT; - if (byte_frame) { - __io uint8 *dr8 = (__io uint8 *)&dev->regs->DR; /* we need to access as byte */ - return (uint16)*dr8; - } else { - __io uint16 *dr16 = (__io uint16 *)&dev->regs->DR; /* we need to access as half-word */ - return (uint16)*dr16; - } -} - -uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) { - uint32 txed = 0; - uint8 byte_frame = (dev->regs->CR2 & SPI_CR2_DS) <= SPI_DATA_SIZE_8_BIT; - while (spi_is_tx_empty(dev) && (txed < len)) { - if (byte_frame) { - __io uint8 *dr8 = (__io uint8 *)&dev->regs->DR; /* we need to access as byte */ - *dr8 = ((const uint8 *)buf)[txed++]; - } else { - __io uint16 *dr16 = (__io uint16 *)&dev->regs->DR; /* we need to access as half-word */ - *dr16 = ((const uint16 *)buf)[txed++]; - } - } - return txed; -} diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_syscfg.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_syscfg.c deleted file mode 100644 index 9421b2dcb..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_syscfg.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/syscfg.c - * @author F3-port by Hanspeter Portner - * @brief SYSCFG routines. - */ - -#include -#include -#include - -void syscfg_set_mem_mode(syscfg_mem_mode mode) { - uint32 memrmp = SYSCFG_BASE->CFGR1; - memrmp &= ~SYSCFG_CFGR1_MEM_MODE; - memrmp |= (uint32)mode; - SYSCFG_BASE->CFGR1 = memrmp; -} diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_timer.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_timer.c deleted file mode 100644 index 08b906323..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_timer.c +++ /dev/null @@ -1,147 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/timer.c - * @author Marti Bolivar , - * F3-port by Hanspeter Portner - * @brief STM32F3 timer. - */ - -#include -#include -#include -#include "timer_private.h" - -/** - * @brief Get the GPIO alternate function corresponding to a timer. - * - * For example, if dev is TIMER1, this function returns - * GPIO_AF_TIM_1_2. This is useful for e.g. using gpio_set_af() to set - * a pin's alternate function to a timer. - * - * @param dev Timer device, must not be TIMER6 or TIMER7. - * @return gpio_af corresponding to dev - * @see gpio_set_af - * @see gpio_af - */ - /* FIXME this has to be inline with the PIN_MAP, but some timers are accessible on different alternate function lanes based on the used pin... */ -gpio_af timer_get_af(timer_dev *dev) { - rcc_clk_id clk_id = dev->clk_id; - /* Timers 6 and 7 don't have any capture/compare, so they can't do - * PWM (and in fact have no AF values). */ - ASSERT(clk_id != RCC_TIMER6 && clk_id != RCC_TIMER7); - switch(dev->clk_id) { - case RCC_TIMER1: - return GPIO_AF_6; - case RCC_TIMER2: // fall-through - case RCC_TIMER3: // fall-through - case RCC_TIMER4: - return GPIO_AF_2; - case RCC_TIMER8: - return GPIO_AF_4; - case RCC_TIMER15: - return GPIO_AF_3; - case RCC_TIMER16: // fall-through - case RCC_TIMER17: - return GPIO_AF_1; - default: - ASSERT(0); // Can't happen - return (gpio_af)-1; - } -} - -/* - * IRQ handlers - * - * Defer to the timer_private dispatch API. - * - * FIXME: The names of these handlers are inaccurate since XL-density - * devices came out. Update these to match the STM32F3 names, maybe - * using some weak symbol magic to preserve backwards compatibility if - * possible. Once that's done, we can just move the IRQ handlers into - * the top-level libmaple/timer.c, and there will be no need for this - * file. - */ - -void __irq_tim1_brk_tim15(void) { - dispatch_adv_brk(TIMER1); - dispatch_tim_9_12(TIMER15); -} - -void __irq_tim1_up_tim16(void) { - dispatch_adv_up(TIMER1); - dispatch_tim_10_11_13_14(TIMER16); -} - -void __irq_tim1_trg_com_tim17(void) { - dispatch_adv_trg_com(TIMER1); - dispatch_tim_10_11_13_14(TIMER17); -} - -void __irq_tim1_cc(void) { - dispatch_adv_cc(TIMER1); -} - -void __irq_tim2(void) { - dispatch_general(TIMER2); -} - -void __irq_tim3(void) { - dispatch_general(TIMER3); -} - -void __irq_tim4(void) { - dispatch_general(TIMER4); -} - -void __irq_tim6_dacunder(void) { - dispatch_basic(TIMER6); - /* FIXME handle DAC12 underrun */ -} - -#if STM32_F3_LINE == STM32_F3_LINE_303 -void __irq_tim7(void) { - dispatch_basic(TIMER7); -} - -void __irq_tim8_brk(void) { - dispatch_adv_brk(TIMER8); -} - -void __irq_tim8_up(void) { - dispatch_adv_up(TIMER8); -} - -void __irq_tim8_trg_com(void) { - dispatch_adv_trg_com(TIMER8); -} - -void __irq_tim8_cc(void) { - dispatch_adv_cc(TIMER8); -} -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_usart.c b/STM32F3/cores/maple/libmaple/stm32f3/f3_usart.c deleted file mode 100644 index 4d466b338..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_usart.c +++ /dev/null @@ -1,210 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/usart.c - * @author F3-port by Hanspeter Portner - * @brief STM32F3 USART. - */ - -#include -#include -#include -#include "usart_private.h" - -/* - * Devices - */ - -static ring_buffer usart1_rb; -static usart_dev usart1 = { - .regs = USART1_BASE, - .rb = &usart1_rb, - .max_baud = 4500000UL, - .clk_id = RCC_USART1, - .irq_num = NVIC_USART1, -}; -/** USART1 device */ -usart_dev *USART1 = &usart1; - -static ring_buffer usart2_rb; -static usart_dev usart2 = { - .regs = USART2_BASE, - .rb = &usart2_rb, - .max_baud = 2250000UL, - .clk_id = RCC_USART2, - .irq_num = NVIC_USART2, -}; -/** USART2 device */ -usart_dev *USART2 = &usart2; - -static ring_buffer usart3_rb; -static usart_dev usart3 = { - .regs = USART3_BASE, - .rb = &usart3_rb, - .max_baud = 2250000UL, - .clk_id = RCC_USART3, - .irq_num = NVIC_USART3, -}; -/** USART3 device */ -usart_dev *USART3 = &usart3; - -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) -static ring_buffer uart4_rb; -static usart_dev uart4 = { - .regs = UART4_BASE, - .rb = &uart4_rb, - .max_baud = 2250000UL, - .clk_id = RCC_UART4, - .irq_num = NVIC_UART4, -}; -/** UART4 device */ -usart_dev *UART4 = &uart4; - -static ring_buffer uart5_rb; -static usart_dev uart5 = { - .regs = UART5_BASE, - .rb = &uart5_rb, - .max_baud = 2250000UL, - .clk_id = RCC_UART5, - .irq_num = NVIC_UART5, -}; -/** UART5 device */ -usart_dev *UART5 = &uart5; -#endif - -/* - * Routines - */ - -void usart_config_gpios_async(usart_dev *udev, - gpio_dev *rx_dev, uint8 rx, - gpio_dev *tx_dev, uint8 tx, - unsigned flags) { - gpio_af af = usart_get_af(udev); - gpio_set_modef(rx_dev, rx, GPIO_MODE_AF, GPIO_MODEF_PUPD_NONE); - //gpio_set_modef(tx_dev, tx, GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - gpio_set_modef(tx_dev, tx, GPIO_MODE_AF, GPIO_MODEF_TYPE_OD); - gpio_set_af(rx_dev, rx, af); - gpio_set_af(tx_dev, tx, af); -} - -void usart_set_baud_rate(usart_dev *dev, uint32 clock_speed, uint32 baud) { - /* Figure out the clock speed, if the user doesn't give one. */ - if (clock_speed == 0) { - clock_speed = _usart_clock_freq(dev); - } - ASSERT(clock_speed); - - uint32 divider = clock_speed / baud; - uint32 tmpreg = clock_speed % baud; - /* round divider : if fractional part i greater than 0.5 increment divider */ - if (tmpreg >= baud / 2) - divider++; - dev->regs->BRR = (uint16)divider; -} - -uint32 usart_tx(usart_dev *dev, const uint8 *buf, uint32 len) { - usart_reg_map *regs = dev->regs; - uint32 txed = 0; - while ((regs->SR & USART_SR_TXE) && (txed < len)) { - regs->TDR = buf[txed++] & USART_TDR_TDR; - } - return txed; -} - -/** - * @brief Call a function on each USART. - * @param fn Function to call. - */ -void usart_foreach(void (*fn)(usart_dev*)) { - fn(USART1); - fn(USART2); - fn(USART3); -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - fn(UART4); - fn(UART5); -#endif -} - -/** - * @brief Get GPIO alternate function mode for a USART. - * @param dev USART whose gpio_af to get. - * @return gpio_af corresponding to dev. - */ -gpio_af usart_get_af(usart_dev *dev) { - switch (dev->clk_id) { - case RCC_USART1: - case RCC_USART2: - case RCC_USART3: - return GPIO_AF_7; -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - case RCC_UART4: - case RCC_UART5: - return GPIO_AF_5; -#endif - default: - ASSERT(0); /* Can't happen */ - return (gpio_af)-1; - } -} - -/* - * Interrupt handlers. - */ - -static __always_inline void usart_irq(ring_buffer *rb, usart_reg_map *regs) { -#ifdef USART_SAFE_INSERT - /* If the buffer is full and the user defines USART_SAFE_INSERT, - * ignore new bytes. */ - rb_safe_insert(rb, regs->RDR & USART_RDR_RDR); -#else - /* By default, push bytes around in the ring buffer. */ - rb_push_insert(rb, regs->RDR & USART_RDR_RDR); -#endif -} - -void __irq_usart1(void) { - usart_irq(&usart1_rb, USART1_BASE); -} - -void __irq_usart2(void) { - usart_irq(&usart2_rb, USART2_BASE); -} - -void __irq_usart3(void) { - usart_irq(&usart3_rb, USART3_BASE); -} - -#ifdef STM32_HIGH_DENSITY -void __irq_uart4(void) { - usart_irq(&uart4_rb, UART4_BASE); -} - -void __irq_uart5(void) { - usart_irq(&uart5_rb, UART5_BASE); -} -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/adc.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/adc.h deleted file mode 100644 index 76422f63f..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/adc.h +++ /dev/null @@ -1,696 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/adc.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 ADC support. - */ - -#ifndef _LIBMAPLE_STM32F3_ADC_H_ -#define _LIBMAPLE_STM32F3_ADC_H_ - -#include -#include -#include /* For the prescalers */ - -/* - * Register map - */ - -/* - * ADC individual register map type. - */ -typedef struct adc_reg_map { - __io uint32 ISR; /**< */ - __io uint32 IER; /**< */ - __io uint32 CR; /**< */ - __io uint32 CFGR; /**< */ - uint32 reserved1; - __io uint32 SMPR1; /**< */ - __io uint32 SMPR2; /**< */ - uint32 reserved2; - __io uint32 TR1; /**< */ - __io uint32 TR2; /**< */ - __io uint32 TR3; /**< */ - uint32 reserved3; - __io uint32 SQR1; /**< */ - __io uint32 SQR2; /**< */ - __io uint32 SQR3; /**< */ - __io uint32 SQR4; /**< */ - __io uint32 DR; /**< */ - uint32 reserved4 [2]; - __io uint32 JSQR; /**< */ - uint32 reserved5 [4]; - __io uint32 OFR1; /**< */ - __io uint32 OFR2; /**< */ - __io uint32 OFR3; /**< */ - __io uint32 OFR4; /**< */ - uint32 reserved6 [4]; - __io uint32 JDR1; /**< */ - __io uint32 JDR2; /**< */ - __io uint32 JDR3; /**< */ - __io uint32 JDR4; /**< */ - uint32 reserved7 [4]; - __io uint32 AWD2CR; /**< */ - __io uint32 AWD3CR; /**< */ - uint32 reserved8 [2]; - __io uint32 DIFSEL; /**< */ - __io uint32 CALFACT; /**< */ -} adc_reg_map; - -/* - * ADC master and slave common register map type. - */ -typedef struct adc_common_reg_map { - __io uint32 CSR; /**< */ - uint32 reserved; - __io uint32 CCR; /**< */ - __io uint32 CDR; /**< */ -} adc_common_reg_map; - -/** ADC device type. */ -typedef struct adc_dev { - adc_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ - adc_private_data *priv; /**< ADC private data */ -} adc_dev; - -/* - * Devices - */ - -extern const struct adc_dev *ADC1; /* master */ -extern const struct adc_dev *ADC2; /* slave */ -#if STM32_F3_LINE == STM32_F3_LINE_303 -extern const struct adc_dev *ADC3; /* master */ -extern const struct adc_dev *ADC4; /* slave */ -#endif - -/* - * Register map base pointers - */ - -/** STM32F3 ADC1 individual register map base pointer. */ -#define ADC1_BASE ((struct adc_reg_map*)0x50000000) -/** STM32F3 ADC2 individual register map base pointer. */ -#define ADC2_BASE ((struct adc_reg_map*)0x50000100) -/** STM32F3 ADC1/ADC2 common register map base pointer. */ -#define ADC12_BASE ((struct adc_common_reg_map*)0x50000300) -#if STM32_F3_LINE == STM32_F3_LINE_303 -/** STM32F3 ADC3 individual register map base pointer. */ -#define ADC3_BASE ((struct adc_reg_map*)0x50000400) -/** STM32F3 ADC4 individual register map base pointer. */ -#define ADC4_BASE ((struct adc_reg_map*)0x50000500) -/** STM32F3 ADC3/ADC4 common register map base pointer. */ -#define ADC34_BASE ((struct adc_common_reg_map*)0x50000700) -#endif - -/* - * Register bit definitions - */ - -/* Interrupt and status register */ -#define ADC_ISR_JQOVF_BIT 10 -#define ADC_ISR_AWD3_BIT 9 -#define ADC_ISR_AWD2_BIT 8 -#define ADC_ISR_AWD1_BIT 7 -#define ADC_ISR_JEOS_BIT 6 -#define ADC_ISR_JEOC_BIT 5 -#define ADC_ISR_OVR_BIT 4 -#define ADC_ISR_EOS_BIT 3 -#define ADC_ISR_EOC_BIT 2 -#define ADC_ISR_EOSMP_BIT 1 -#define ADC_ISR_ADRDY_BIT 0 - -#define ADC_ISR_JQOVF (1U << ADC_ISR_JQOVF_BIT) -#define ADC_ISR_AWD3 (1U << ADC_ISR_AWD3_BIT) -#define ADC_ISR_AWD2 (1U << ADC_ISR_AWD2_BIT) -#define ADC_ISR_AWD1 (1U << ADC_ISR_AWD1_BIT) -#define ADC_ISR_JEOS (1U << ADC_ISR_JEOS_BIT) -#define ADC_ISR_JEOC (1U << ADC_ISR_JEOC_BIT) -#define ADC_ISR_OVR (1U << ADC_ISR_OVR_BIT) -#define ADC_ISR_EOS (1U << ADC_ISR_EOS_BIT) -#define ADC_ISR_EOC (1U << ADC_ISR_EOC_BIT) -#define ADC_ISR_EOSMP (1U << ADC_ISR_EOSMP_BIT) -#define ADC_ISR_ADRDY (1U << ADC_ISR_ADRDY_BIT) - -/* FIXME make an enum out of this */ -#define ADC_WATCHDOG_1_INTERRUPT ADC_ISR_AWD1 -#define ADC_WATCHDOG_2_INTERRUPT ADC_ISR_AWD2 -#define ADC_WATCHDOG_3_INTERRUPT ADC_ISR_AWD3 -#define ADC_CONV_INTERRUPT ADC_ISR_EOC -#define ADC_INJ_CONV_INTERRUPT ADC_ISR_JEOC -#define ADC_OVERRUN_INTERRUPT ADC_ISR_OVR -#define ADC_ALL_INTERRUPTS (ADC_CONV_INTERRUPT | ADC_WATCHDOG_1_INTERRUPT | ADC_WATCHDOG_2_INTERRUPT | ADC_WATCHDOG_3_INTERRUPT | ADC_INJ_CONV_INTERRUPT | ADC_OVERRUN_INTERRUPT) - -/* Interrupt enable register */ -#define ADC_IER_JQOVF_BIT 10 -#define ADC_IER_AWD3_BIT 9 -#define ADC_IER_AWD2_BIT 8 -#define ADC_IER_AWD1_BIT 7 -#define ADC_IER_JEOS_BIT 6 -#define ADC_IER_JEOC_BIT 5 -#define ADC_IER_OVR_BIT 4 -#define ADC_IER_EOS_BIT 3 -#define ADC_IER_EOC_BIT 2 -#define ADC_IER_EOSMP_BIT 1 -#define ADC_IER_ADRDY_BIT 0 - -#define ADC_IER_JQOVF (1U << ADC_IER_JQOVF_BIT) -#define ADC_IER_AWD3 (1U << ADC_IER_AWD3_BIT) -#define ADC_IER_AWD2 (1U << ADC_IER_AWD2_BIT) -#define ADC_IER_AWD1 (1U << ADC_IER_AWD1_BIT) -#define ADC_IER_JEOS (1U << ADC_IER_JEOS_BIT) -#define ADC_IER_JEOC (1U << ADC_IER_JEOC_BIT) -#define ADC_IER_OVR (1U << ADC_IER_OVR_BIT) -#define ADC_IER_EOS (1U << ADC_IER_EOS_BIT) -#define ADC_IER_EOC (1U << ADC_IER_EOC_BIT) -#define ADC_IER_EOSMP (1U << ADC_IER_EOSMP_BIT) -#define ADC_IER_ADRDY (1U << ADC_IER_ADRDY_BIT) - -/* Control register */ -#define ADC_CR_ADCAL_BIT 31 -#define ADC_CR_ADCALDIF_BIT 30 -#define ADC_CR_ADVREGEN_SHIFT 28 -#define ADC_CR_JADSTP_BIT 5 -#define ADC_CR_ADSTP_BIT 4 -#define ADC_CR_JADSTART_BIT 3 -#define ADC_CR_ADSTART_BIT 2 -#define ADC_CR_ADDIS_BIT 1 -#define ADC_CR_ADEN_BIT 0 - -#define ADC_CR_ADCAL (1U << ADC_CR_ADCAL_BIT) -#define ADC_CR_ADCALDIF (1U << ADC_CR_ADCALDIF_BIT) -#define ADC_CR_ADVREGEN (0x3 << ADC_CR_ADVREGEN_SHIFT) -#define ADC_CR_ADVREGEN_ENABLE (0x1 << ADC_CR_ADVREGEN_SHIFT) -#define ADC_CR_ADVREGEN_DISABLE (0x2 << ADC_CR_ADVREGEN_SHIFT) -#define ADC_CR_JADSTP (1U << ADC_CR_JADSTP_BIT) -#define ADC_CR_ADSTP (1U << ADC_CR_ADSTP_BIT) -#define ADC_CR_JADSTART (1U << ADC_CR_JADSTART_BIT) -#define ADC_CR_ADSTART (1U << ADC_CR_ADSTART_BIT) -#define ADC_CR_ADDIS (1U << ADC_CR_ADDIS_BIT) -#define ADC_CR_ADEN (1U << ADC_CR_ADEN_BIT) - -/* Configuration register */ -#define ADC_CFGR_AWD1CH_SHIFT 26 -#define ADC_CFGR_JAUTO_BIT 25 -#define ADC_CFGR_JAWD1EN_BIT 24 -#define ADC_CFGR_AWD1EN_BIT 23 -#define ADC_CFGR_AWD1SGL_BIT 22 -#define ADC_CFGR_JQM_BIT 21 -#define ADC_CFGR_JDISCEN_BIT 20 -#define ADC_CFGR_JDISCNUM_SHIFT 17 -#define ADC_CFGR_DISCEN_BIT 16 -#define ADC_CFGR_AUTDLY_BIT 14 -#define ADC_CFGR_CONT_BIT 13 -#define ADC_CFGR_OVRMOD_BIT 12 -#define ADC_CFGR_EXTEN_SHIFT 10 -#define ADC_CFGR_EXTSEL_SHIFT 6 -#define ADC_CFGR_ALIGN_BIT 5 -#define ADC_CFGR_RES_SHIFT 3 -#define ADC_CFGR_DMACFG_BIT 1 -#define ADC_CFGR_DMAEN_BIT 0 - -#define ADC_CFGR_AWD1CH (0x1F << ADC_CFGR_AWD1CH_SHIFT) -#define ADC_CFGR_JAUTO (1U << ADC_CFGR_JAUTO_BIT) -#define ADC_CFGR_JAWD1EN (1U << ADC_CFGR_JAWD1EN_BIT) -#define ADC_CFGR_AWD1EN (1U << ADC_CFGR_AWD1EN_BIT) -#define ADC_CFGR_AWD1SGL (1U << ADC_CFGR_AWD1SGL_BIT) -#define ADC_CFGR_JQM (1U << ADC_CFGR_JQM_BIT) -#define ADC_CFGR_JDISCEN (1U << ADC_CFGR_JDISCEN_BIT) -#define ADC_CFGR_JDISCNUM (0x7 << ADC_CFGR_JDISCNUM_SHIFT) -#define ADC_CFGR_DISCEN (1U << ADC_CFGR_DISCEN_BIT) -#define ADC_CFGR_AUTODLY (1U << ADC_CFGR_AUTODLY_BIT) -#define ADC_CFGR_CONT (1U << ADC_CFGR_CONT_BIT) -#define ADC_CFGR_OVRMOD (1U << ADC_CFGR_OVRMOD_BIT) -#define ADC_CFGR_EXTEN (0x3 << ADC_CFGR_EXTEN_SHIFT) -#define ADC_CFGR_EXTSEL (0xF << ADC_CFGR_EXTSEL_SHIFT) -#define ADC_CFGR_ALIGN (1U << ADC_CFGR_ALIGN_BIT) -#define ADC_CFGR_RES (0x3 << ADC_CFGR_RES_SHIFT) -#define ADC_CFGR_DMACFG (1U << ADC_CFGR_DMACFG_BIT) -#define ADC_CFGR_DMAEN (1U << ADC_CFGR_DMAEN_BIT) - -/* Sample time register 1 */ -#define ADC_SMPR1_SMP9 (0x7 << 27) -#define ADC_SMPR1_SMP8 (0x7 << 24) -#define ADC_SMPR1_SMP7 (0x7 << 21) -#define ADC_SMPR1_SMP6 (0x7 << 18) -#define ADC_SMPR1_SMP5 (0x7 << 15) -#define ADC_SMPR1_SMP4 (0x7 << 12) -#define ADC_SMPR1_SMP3 (0x7 << 9) -#define ADC_SMPR1_SMP2 (0x7 << 6) -#define ADC_SMPR1_SMP1 (0x7 << 3) - -/* Sample time register 2 */ -#define ADC_SMPR2_SMP18 (0x7 << 24) -#define ADC_SMPR2_SMP17 (0x7 << 21) -#define ADC_SMPR2_SMP16 (0x7 << 18) -#define ADC_SMPR2_SMP15 (0x7 << 15) -#define ADC_SMPR2_SMP14 (0x7 << 12) -#define ADC_SMPR2_SMP13 (0x7 << 9) -#define ADC_SMPR2_SMP12 (0x7 << 6) -#define ADC_SMPR2_SMP11 (0x7 << 3) -#define ADC_SMPR2_SMP10 0x7 - -/* Analog watchdog 1 threshold register */ -#define ADC_TR1_HT1 (0xFFF << 16) /* 12bit watchdog */ -#define ADC_TR1_LT1 0xFFF - -/* Analog watchdog 2 threshold register */ -#define ADC_TR2_HT2 (0xFF << 16) /* 8bit watchdog */ -#define ADC_TR2_LT2 0xFF - -/* Analog watchdog 3 threshold register */ -#define ADC_TR3_HT3 (0xFF << 16) /* 8bit watchdog */ -#define ADC_TR3_LT3 0xFF - -/* Regular sequence register 1 */ -#define ADC_SQR1_SQ4 (0x1F << 24) -#define ADC_SQR1_SQ3 (0x1F << 18) -#define ADC_SQR1_SQ2 (0x1F << 12) -#define ADC_SQR1_SQ1 (0x1F << 6) -#define ADC_SQR1_L 0xF - -/* Regular sequence register 2 */ -#define ADC_SQR2_SQ9 (0x1F << 24) -#define ADC_SQR2_SQ8 (0x1F << 18) -#define ADC_SQR2_SQ7 (0x1F << 12) -#define ADC_SQR2_SQ6 (0x1F << 6) -#define ADC_SQR2_SQ5 0x1F - -/* Regular sequence register 3 */ -#define ADC_SQR3_SQ14 (0x1F << 24) -#define ADC_SQR3_SQ13 (0x1F << 18) -#define ADC_SQR3_SQ12 (0x1F << 12) -#define ADC_SQR3_SQ11 (0x1F << 6) -#define ADC_SQR3_SQ10 0x1F - -/* Regular sequence register 4 */ -#define ADC_SQR4_SQ16 (0x1F << 6) -#define ADC_SQR4_SQ15 0x1F - -/* Regular data register */ -#define ADC_DR_RDATA 0xFFFF - -/* Injected sequence register */ -#define ADC_JSQR_JEXTEN_SHIFT 6 -#define ADC_JSQR_JEXTSEL_SHIFT 2 - -#define ADC_JSQR_SQ4 (0x1F << 26) -#define ADC_JSQR_SQ3 (0x1F << 20) -#define ADC_JSQR_SQ2 (0x1F << 14) -#define ADC_JSQR_SQ1 (0x1F << 8) -#define ADC_JSQR_JEXTEN (0x3 << ADC_JSQR_JEXTEN_SHIFT) -#define ADC_JSQR_JEXTSEL (0xF << ADC_JSQR_JEXTSEL_SHIFT) -#define ADC_JSQR_JL 0x3 - -/* Offset register 1 */ -#define ADC_OFR1_OFFSET1EN_BIT 31 - -#define ADC_OFR1_OFFSET1ENT (1U << ADC_OFR1_OFFSET1EN_BIT) -#define ADC_OFR1_OFFSET1_CH (0x1F << 26) -#define ADC_OFR1_OFFSET1 0xFFF - -/* Offset register 2 */ -#define ADC_OFR2_OFFSET2EN_BIT 31 - -#define ADC_OFR2_OFFSET2EN (1U << ADC_OFR2_OFFSET2EN_BIT) -#define ADC_OFR2_OFFSET2_CH (0x1F << 26) -#define ADC_OFR2_OFFSET2 0xFFF - -/* Offset register 3 */ -#define ADC_OFR3_OFFSET3EN_BIT 31 - -#define ADC_OFR3_OFFSET3EN (1U << ADC_OFR3_OFFSET3EN_BIT) -#define ADC_OFR3_OFFSET3_CH (0x1F << 26) -#define ADC_OFR3_OFFSET3 0xFFF - -/* Offset register 4 */ -#define ADC_OFR4_OFFSET4EN_BIT 31 - -#define ADC_OFR4_OFFSET4EN (1U << ADC_OFR4_OFFSET4EN_BIT) -#define ADC_OFR4_OFFSET4_CH (0x1F << 26) -#define ADC_OFR4_OFFSET4 0xFFF - -/* Injected data register 1 */ -#define ADC_JDR1_JDATA1 0xFFFF - -/* Injected data register 2 */ -#define ADC_JDR2_JDATA2 0xFFFF - -/* Injected data register 3 */ -#define ADC_JDR3_JDATA3 0xFFFF - -/* Injected data register 4 */ -#define ADC_JDR4_JDATA4 0xFFFF - -/* Analog watchdog 2 configuration register */ -#define ADC_AWD2CR_AWD2CH (0x1FFFF << 1) - -/* Analog watchdog 3 configuration register */ -#define ADC_AWD3CR_AWD3CH (0x1FFFF << 1) - -/* Differential mode selection register */ -#define ADC_DIFSEL_DIFSEL (0x1FFFF << 1) - -/* Calibration factors */ -#define ADC_CALFACT_CALFACT_D (0x7F << 16) -#define ADC_CALFACT_CALFACT_S 0x7F - -/* Common status register */ -#define ADC_CSR_JQOVF_SLV_BIT 26 -#define ADC_CSR_AWD3_SLV_BIT 25 -#define ADC_CSR_AWD2_SLV_BIT 24 -#define ADC_CSR_AWD1_SLV_BIT 23 -#define ADC_CSR_JEOS_SLV_BIT 22 -#define ADC_CSR_JEOC_SLV_BIT 21 -#define ADC_CSR_OVR_SLV_BIT 20 -#define ADC_CSR_EOS_SLV_BIT 19 -#define ADC_CSR_EOC_SLV_BIT 18 -#define ADC_CSR_EOSMP_SLV_BIT 17 -#define ADC_CSR_ADRDY_SLV_BIT 16 - -#define ADC_CSR_JQOVF_MST_BIT 10 -#define ADC_CSR_AWD3_MST_BIT 9 -#define ADC_CSR_AWD2_MST_BIT 8 -#define ADC_CSR_AWD1_MST_BIT 7 -#define ADC_CSR_JEOS_MST_BIT 6 -#define ADC_CSR_JEOC_MST_BIT 5 -#define ADC_CSR_OVR_MST_BIT 4 -#define ADC_CSR_EOS_MST_BIT 3 -#define ADC_CSR_EOC_MST_BIT 2 -#define ADC_CSR_EOSMP_MST_BIT 1 -#define ADC_CSR_ADRDY_MST_BIT 0 - -#define ADC_CSR_JQOVF_SLV (1U << ADC_CSR_JQOVF_SLV_BIT) -#define ADC_CSR_AWD3_SLV (1U << ADC_CSR_AWD3_SLV_BIT) -#define ADC_CSR_AWD2_SLV (1U << ADC_CSR_AWD2_SLV_BIT) -#define ADC_CSR_AWD1_SLV (1U << ADC_CSR_AWD1_SLV_BIT) -#define ADC_CSR_JEOS_SLV (1U << ADC_CSR_JEOS_SLV_BIT) -#define ADC_CSR_JEOC_SLV (1U << ADC_CSR_JEOC_SLV_BIT) -#define ADC_CSR_OVR_SLV (1U << ADC_CSR_OVR_SLV_BIT) -#define ADC_CSR_EOS_SLV (1U << ADC_CSR_EOS_SLV_BIT) -#define ADC_CSR_EOC_SLV (1U << ADC_CSR_EOC_SLV_BIT) -#define ADC_CSR_EOSMP_SLV (1U << ADC_CSR_EOS_MP_SLV_BIT) -#define ADC_CSR_ADRDY_SLV (1U << ADC_CSR_ADRDY_SLV_BIT) - -#define ADC_CSR_JQOVF_MST (1U << ADC_CSR_JQOVF_MST_BIT) -#define ADC_CSR_AWD3_MST (1U << ADC_CSR_AWD3_MST_BIT) -#define ADC_CSR_AWD2_MST (1U << ADC_CSR_AWD2_MST_BIT) -#define ADC_CSR_AWD1_MST (1U << ADC_CSR_AWD1_MST_BIT) -#define ADC_CSR_JEOS_MST (1U << ADC_CSR_JEOS_MST_BIT) -#define ADC_CSR_JEOC_MST (1U << ADC_CSR_JEOC_MST_BIT) -#define ADC_CSR_OVR_MST (1U << ADC_CSR_OVR_MST_BIT) -#define ADC_CSR_EOS_MST (1U << ADC_CSR_EOS_MST_BIT) -#define ADC_CSR_EOC_MST (1U << ADC_CSR_EOC_MST_BIT) -#define ADC_CSR_EOSMP_MST (1U << ADC_CSR_EOS_MP_MST_BIT) -#define ADC_CSR_ADRDY_MST (1U << ADC_CSR_ADRDY_MST_BIT) - -/* Common control register */ -#define ADC_CCR_VBATEN_BIT 24 -#define ADC_CCR_TSEN_BIT 23 -#define ADC_CCR_VREFEN_BIT 22 -#define ADC_CCR_CKMODE_SHIFT 16 -#define ADC_CCR_MDMA_SHIFT 14 -#define ADC_CCR_DMACFG_BIT 13 -#define ADC_CCR_DELAY_SHIFT 8 -#define ADC_CCR_DUAL_SHIFT 0 - -#define ADC_CCR_VBATEN (1U << ADC_CCR_VBATEN_BIT) -#define ADC_CCR_TSEN (1U << ADC_CCR_TSEN_BIT) -#define ADC_CCR_VREFEN (1U << ADC_CCR_VREFEN_BIT) -#define ADC_CCR_CKMODE (0x3 << ADC_CCR_CKMODE_SHIFT) -#define ADC_CCR_MDMA (0x3 << ADC_CCR_MDMA_SHIFT) -#define ADC_CCR_DMACFG (1U << ADC_CCR_DMACFG_BIT) -#define ADC_CCR_DELAY (0xF << ADC_CCR_DELAY_SHIFT) -#define ADC_CCR_DUAL 0X1F - -/* Common regular data register for dual mode */ -#define ADC_CDR_RDATA_SLV (0xFFFF << 16) -#define ADC_CDR_RDATA_MST 0xFFFF - -/* - * Other types - */ - -/** - * @brief STM32F3 external event selectors for regular group - * conversion. - * - * For ease of use, each event selector is given along with the ADCs - * it's available on, along with any other availability restrictions. - * - * @see adc_set_extsel() - */ -typedef enum adc_extsel_event { - /* ADC1 (master) and ADC2 (slave) regular channels */ - ADC12_EXT_EV_TIM1_CC1 = 0x0 << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM1_CC2 = 0x1 << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM1_CC3 = 0x2 << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM2_CC2 = 0x3 << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM3_TRGO = 0x4 << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM4_CC4 = 0x5 << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_EXTI_11 = 0x6 << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM8_TRGO = 0x7 << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM8_TRGO2 = 0x8 << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM1_TRGO = 0x9 << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM1_TRGO2 = 0xA << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM2_TRGO = 0xB << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM4_TRGO = 0xC << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM6_TRGO = 0xD << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM15_TRGO = 0xE << ADC_CFGR_EXTSEL_SHIFT, - ADC12_EXT_EV_TIM3_CC4 = 0xF << ADC_CFGR_EXTSEL_SHIFT, - - /* ADC1 (master) and ADC2 (slave) injected channels */ - ADC12_JEXT_EV_TIM1_TRGO = 0x0 << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM1_CC4 = 0x1 << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM2_TRGO = 0x2 << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM2_CC1 = 0x3 << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM3_CC4 = 0x4 << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM4_TRGO = 0x5 << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_EXTI_15 = 0x6 << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM8_CC4 = 0x7 << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM1_TRGO2 = 0x8 << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM8_TRGO = 0x9 << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM8_TRGO2 = 0xA << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM3_CC3 = 0xB << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM3_TRGO = 0xC << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM3_CC1 = 0xD << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM6_TRGO = 0xE << ADC_JSQR_JEXTSEL_SHIFT, - ADC12_JEXT_EV_TIM15_TRGO = 0xF << ADC_JSQR_JEXTSEL_SHIFT, - - /* ADC3 (master) and ADC4 (slave) injected channels */ - ADC34_EXT_EV_TIM3_CC1 = 0x0 << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM3_CC3 = 0x1 << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM1_cc3 = 0x2 << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM8_CC1 = 0x3 << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM8_TRGO = 0x4 << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_EXTI_2 = 0x5 << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM4_CC1 = 0x6 << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM2_TRGO = 0x7 << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM8_TRGO2 = 0x8 << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM1_TRGO = 0x9 << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM1_TRGO2 = 0xA << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM3_TRGO = 0xB << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM4_TRGO = 0xC << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM7_TRGO = 0xD << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM15_TRGO = 0xE << ADC_CFGR_EXTSEL_SHIFT, - ADC34_EXT_EV_TIM2_CC1 = 0xF << ADC_CFGR_EXTSEL_SHIFT, - - /* ADC3 (master) and ADC4 (slave) injected channels */ - ADC34_JEXT_EV_TIM1_TRGO = 0x0 << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM1_CC4 = 0x1 << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM4_CC3 = 0x2 << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM8_CC2 = 0x3 << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM8_CC4 = 0x4 << ADC_JSQR_JEXTSEL_SHIFT, - /* ADC34_JEXT_EV_TIM4_CC3 = 0x5 << ADC_JSQR_JEXTSEL_SHIFT, */ /* FIXME duplicate or typo in manual? */ - ADC34_JEXT_EV_TIM4_CC4 = 0x6 << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM4_TRGO = 0x7 << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM1_TRGO2 = 0x8 << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM8_TRGO = 0x9 << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM8_TRGO2 = 0xA << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM1_CC3 = 0xB << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM3_TRGO = 0xC << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM2_TRGO = 0xD << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM7_TRGO = 0xE << ADC_JSQR_JEXTSEL_SHIFT, - ADC34_JEXT_EV_TIM15_TRGO = 0xF << ADC_JSQR_JEXTSEL_SHIFT, -} adc_extsel_event; - -/** - * @brief STM32F3 ADC trigger mode. - * - * These control the trigger mode of the ADC, which can be set to: - * Software trigger, hardware trigger on rising, falling or both edges. - */ -typedef enum adc_exttrig_mode { - ADC_EXTTRIG_MODE_SOFTWARE = 0x0 << ADC_CFGR_EXTEN_SHIFT, /**< .. */ - ADC_EXTTRIG_MODE_HARDWARE_RISING = 0x1 << ADC_CFGR_EXTEN_SHIFT, /**< .. */ - ADC_EXTTRIG_MODE_HARDWARE_FALLING = 0x2 << ADC_CFGR_EXTEN_SHIFT, /**< .. */ - ADC_EXTTRIG_MODE_HARDWARE_BOTH = 0x3 << ADC_CFGR_EXTEN_SHIFT, /**< .. */ -} adc_exttrig_mode; - -/** - * @brief STM32F3 ADC resolution. - * - * These control the ADC resolution, which can be set to: - * 6, 8, 10 or 12 bit. - */ -typedef enum adc_resolution { - ADC_RESOLUTION_12_BIT = 0x0 << ADC_CFGR_RES_SHIFT, /**< .. */ - ADC_RESOLUTION_10_BIT = 0x1 << ADC_CFGR_RES_SHIFT, /**< .. */ - ADC_RESOLUTION_8_BIT = 0x2 << ADC_CFGR_RES_SHIFT, /**< .. */ - ADC_RESOLUTION_6_BIT = 0x3 << ADC_CFGR_RES_SHIFT, /**< .. */ -} adc_resolution; - -/** - * @brief STM32F3 sample times, in ADC clock cycles. - * - * These control the amount of time spent sampling the input voltage. - */ -typedef enum adc_smp_rate { - ADC_SMPR_1_5 = 0x0, /**< 1.5 ADC cycles */ - ADC_SMPR_2_5 = 0x1, /**< 2.5 ADC cycles */ - ADC_SMPR_4_5 = 0x2, /**< 4.5 ADC cycles */ - ADC_SMPR_7_5 = 0x3, /**< 7.5 ADC cycles */ - ADC_SMPR_19_5 = 0x4, /**< 19.5 ADC cycles */ - ADC_SMPR_61_5 = 0x5, /**< 61.5 ADC cycles */ - ADC_SMPR_181_5 = 0x6, /**< 181.5 ADC cycles */ - ADC_SMPR_601_5 = 0x7, /**< 601.5 ADC cycles */ -} adc_smp_rate; - -/* - * FIXME SHIFT - */ - -/** - * @brief STM32F3 ADC clock mode. - */ -typedef enum adc_clock_mode { - ADC_CLOCK_MODE_ASYNCHRONOUS = 0x0, /**< . */ - ADC_CLOCK_MODE_SYNCHRONOUS_DIV_1 = 0x1, /**< . */ - ADC_CLOCK_MODE_SYNCHRONOUS_DIV_2 = 0x2, /**< . */ - ADC_CLOCK_MODE_SYNCHRONOUS_DIV_4 = 0x3, /**< . */ -} adc_clock_mode; - -/** - * @brief STM32F3 ADC DMA mode. - */ -typedef enum adc_dma_mode { - ADC_MDMA_MODE_DISABLE = (0x0 << ADC_CCR_MDMA_SHIFT), /**< . */ - ADC_MDMA_MODE_ENABLE_12_10_BIT = (0x2 << ADC_CCR_MDMA_SHIFT), /**< . */ - ADC_MDMA_MODE_ENABLE_8_6_BIT = (0x3 << ADC_CCR_MDMA_SHIFT), /**< . */ -} adc_dma_mode; - -/** - * @brief STM32F3 ADC mode. - */ -typedef enum adc_mode { - ADC_MODE_INDEPENDENT = 0x0, /**< . */ - ADC_MODE_DUAL_REGULAR_INJECTED = 0x1, /**< . */ - ADC_MODE_DUAL_REGULAR_ALTERNATE_TRIGGER = 0x2, /**< . */ - ADC_MODE_DUAL_INJECTED_ONLY = 0x5, /**< . */ - ADC_MODE_DUAL_REGULAR_ONLY = 0x6, /**< . */ - ADC_MODE_DUAL_INTERLEAVED_ONLY = 0x7, /**< . */ - ADC_MODE_DUAL_ALTERNATE_TRIGGER_ONLY = 0x9, /**< . */ -} adc_mode; - -/** - * @brief STM32F3 ADC prescalers, as divisors of PCLK2. - */ -typedef enum adc_prescaler { - /** ADC clock disabled, AHB clock enabled */ - ADC_PRE_AHBCLK_DIV_1 = ADC_CLOCK_MODE_SYNCHRONOUS_DIV_1, - ADC_PRE_AHBCLK_DIV_2 = ADC_CLOCK_MODE_SYNCHRONOUS_DIV_2, - ADC_PRE_AHBCLK_DIV_4 = ADC_CLOCK_MODE_SYNCHRONOUS_DIV_4, - - /** ADC clock enabled, AHB clock disabled */ - ADC_PRE_PCLK_DIV_1 = RCC_ADCPRE_PCLK_DIV_1, /** PCLK divided by 1 */ - ADC_PRE_PCLK_DIV_2 = RCC_ADCPRE_PCLK_DIV_2, /** PCLK divided by 2 */ - ADC_PRE_PCLK_DIV_4 = RCC_ADCPRE_PCLK_DIV_4, /** PCLK divided by 4 */ - ADC_PRE_PCLK_DIV_6 = RCC_ADCPRE_PCLK_DIV_6, /** PCLK divided by 6 */ - ADC_PRE_PCLK_DIV_8 = RCC_ADCPRE_PCLK_DIV_8, /** PCLK divided by 8 */ - ADC_PRE_PCLK_DIV_10 = RCC_ADCPRE_PCLK_DIV_10, /** PCLK divided by 10 */ - ADC_PRE_PCLK_DIV_12 = RCC_ADCPRE_PCLK_DIV_12, /** PCLK divided by 12 */ - ADC_PRE_PCLK_DIV_16 = RCC_ADCPRE_PCLK_DIV_16, /** PCLK divided by 16 */ - ADC_PRE_PCLK_DIV_32 = RCC_ADCPRE_PCLK_DIV_32, /** PCLK divided by 32 */ - ADC_PRE_PCLK_DIV_64 = RCC_ADCPRE_PCLK_DIV_64, /** PCLK divided by 64 */ - ADC_PRE_PCLK_DIV_128 = RCC_ADCPRE_PCLK_DIV_128, /** PCLK divided by 128 */ - ADC_PRE_PCLK_DIV_256 = RCC_ADCPRE_PCLK_DIV_256, /** PCLK divided by 256 */ -} adc_prescaler; - -/* - * Routines - */ - -/** - * @brief Calibrate an ADC peripheral - * - * Availability: STM32F1, STM32F3. - * - * @param dev adc device - */ -void adc_calibrate(const adc_dev *dev); - -/** - * @brief Set external trigger conversion mode event for regular channels - * - * Availability: STM32F1, STM32F3. - * - * @param dev ADC device - * @param mode external trigger disabled, on rising edge, on falling edge or on both - */ -void adc_set_exttrig(const adc_dev *dev, adc_exttrig_mode mode); - -/** - * @brief Set ADC resolution of an ADC peripheral - * - * Availability: STM32F3. - * - * @param dev adc device - * @param resolution ADC resolution (6, 8, 10 or 12 bit) - */ -void adc_set_resolution(const adc_dev *dev, adc_resolution res); - -/** - * @brief Enable the voltage regulatr of an ADC peripheral - * - * Availability: STM32F3. - * - * @param dev adc device - */ -void adc_regulator_enable(const adc_dev *dev); - -/** - * @brief Disable the voltage regulatr of an ADC peripheral - * - * Availability: STM32F3. - * - * @param dev adc device - */ -void adc_regulator_disable(const adc_dev *dev); - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/bkp.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/bkp.h deleted file mode 100644 index 3a49a4160..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/bkp.h +++ /dev/null @@ -1,62 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/bkp.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 backup register support. - */ - -#ifndef _LIBMAPLE_STM32F3_BKP_H_ -#define _LIBMAPLE_STM32F3_BKP_H_ - -#define BKP_NR_DATA_REGS 16 - -/** Backup peripheral register map type. */ -typedef struct bkp_reg_map { - __io uint32 DR0; ///< Data register 0 - __io uint32 DR1; ///< Data register 1 - __io uint32 DR2; ///< Data register 2 - __io uint32 DR3; ///< Data register 3 - __io uint32 DR4; ///< Data register 4 - __io uint32 DR5; ///< Data register 5 - __io uint32 DR6; ///< Data register 6 - __io uint32 DR7; ///< Data register 7 - __io uint32 DR8; ///< Data register 8 - __io uint32 DR9; ///< Data register 9 - __io uint32 DR10; ///< Data register 10 - __io uint32 DR11; ///< Data register 11 - __io uint32 DR12; ///< Data register 12 - __io uint32 DR13; ///< Data register 13 - __io uint32 DR14; ///< Data register 14 - __io uint32 DR15; ///< Data register 15 -} bkp_reg_map; - -/** Backup peripheral register map base pointer. */ -#define BKP_BASE ((struct bkp_reg_map*)0x40002850) //is part of RTC memory map - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/comp.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/comp.h deleted file mode 100644 index ca40a96c5..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/comp.h +++ /dev/null @@ -1,119 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/comp.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 Comparator support. - */ - -#ifndef _LIBMAPLE_STM32F3_COMP_H_ -#define _LIBMAPLE_STM32F3_COMP_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -/* - * Register map - */ - -/* - * COMP individual register map type. - */ -typedef struct comp_reg_map { - __io uint32 CSR; /**< */ -} comp_reg_map; - -/** COMP device type. */ -typedef struct comp_dev { - comp_reg_map *regs; /**< Register map */ -} comp_dev; - -/* - * Devices - */ - -extern const struct comp_dev *COMP1; /* comparator 1 */ -extern const struct comp_dev *COMP2; /* comparator 2 */ -extern const struct comp_dev *COMP3; /* comparator 3 */ -extern const struct comp_dev *COMP4; /* comparator 4 */ -extern const struct comp_dev *COMP5; /* comparator 5 */ -extern const struct comp_dev *COMP6; /* comparator 6 */ -extern const struct comp_dev *COMP7; /* comparator 7 */ - -/* - * Register map base pointers - */ - -#define COMP1_BASE ((struct comp_reg_map*)0x4001001C) -#define COMP2_BASE ((struct comp_reg_map*)0x40010020) -#define COMP3_BASE ((struct comp_reg_map*)0x40010024) -#define COMP4_BASE ((struct comp_reg_map*)0x40010028) -#define COMP5_BASE ((struct comp_reg_map*)0x4001002C) -#define COMP6_BASE ((struct comp_reg_map*)0x40010030) -#define COMP7_BASE ((struct comp_reg_map*)0x40010034) - -/* - * Register bit definitions - */ - -/* Control and status register */ -#define COMP_CSR_LOCK_BIT 31 -#define COMP_CSR_OUT_BIT 30 -#define COMP_CSR_BLANKING_SHIFT 18 -#define COMP_CSR_HIST_SHIFT 16 -#define COMP_CSR_POL_BIT 15 -#define COMP_CSR_OUTSEL_SHIFT 10 -#define COMP_CSR_WINMODE_BIT 9 -#define COMP_CSR_INPSEL_BIT 7 -#define COMP_CSR_INMSEL_SHIFT 4 -#define COMP_CSR_MODE_SHIFT 2 -#define COMP_CSR_EN_BIT 0 - -#define COMP_CSR_LOCK (1U << COMP_CSR_LOCK_BIT) -#define COMP_CSR_OUT (1U << COMP_CSR_OUT_BIT) -#define COMP_CSR_BLANKING (0x7 << COMP_CSR_BLANKING_SHIFT) -#define COMP_CSR_HIST (0x3 << COMP_CSR_HIST_SHIFT) -#define COMP_CSR_POL (1U << COMP_CSR_POL_BIT) -#define COMP_CSR_OUTSEL (0xF << COMP_CSR_OUTSEL_SHIFT) -#define COMP_CSR_WINMODE (0xF << COMP_CSR_WINMODE_SHIFT) -#define COMP_CSR_INPSEL (1U << COMP_CSR_INPSEL_BIT) -#define COMP_CSR_INMSEL (0x7 << COMP_CSR_INMSEL_SHIFT) -#define COMP_CSR_MODE (0x3 << COMP_CSR_MODE_SHIFT) -#define COMP_CSR_EN (1U << COMP_CSR_EN_BIT) - -/* TODO - * actually implement me ;-) - */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/crc.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/crc.h deleted file mode 100644 index 72e7995a2..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/crc.h +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/crc.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 Cylic Redundancy Check (CRC) support. - */ - -#ifndef _LIBMAPLE_STM32F3_CRC_H_ -#define _LIBMAPLE_STM32F3_CRC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - * Register maps - */ - -/** CRC register map type */ -typedef struct crc_reg_map { - __io uint32 DR; /**< Data register */ - __io uint32 IDR; /**< Independent data register */ - __io uint32 CR; /**< Control register */ - uint32 reserved; - __io uint32 INIT; /**< Initial data register */ - __io uint32 POL; /**< Polynomial register */ -} crc_reg_map; - -/* - * Register map base pointers - */ - -/** CRC register map base pointer */ -#define CRC_BASE ((struct crc_reg_map*)0x40013800) //TODO - -/* - * Register bit definitions - */ - -/* Data register */ -#define CRC_DR_DATA 0xFFFFFFFF - -/* Independent data register */ -#define CRC_IDR_DATA 0xFF - -/* Control register */ -#define CRC_CR_REV_OUT_BIT 7 -#define CRC_CR_REV_IN_SHIFT 5 -#define CRC_CR_POLYSIZE_SHIFT 3 -#define CRC_CR_RESET_BIT 0 - -#define CRC_CR_REV_OUT (1U << CRC_CR_REV_OUT_BIT) -#define CRC_CR_REV_IN (0x3 << CRC_CR_REV_IN_SHIFT) -#define CRC_CR_POLYSIZE (0x3 << CRC_CR_POLYSIZE_SHIFT) -#define CRC_CR_RESET (1U << CRC_CR_RESET_BIT) - -/* Initial data register */ -#define CRC_INIT_DATA 0xFFFFFFFF - -/* Polynomial register */ -#define CRC_POL_DATA 0xFFFFFFFF - -/* TODO add some routines */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/dac.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/dac.h deleted file mode 100644 index 7c5e8f5a0..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/dac.h +++ /dev/null @@ -1,74 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/dac.h - * @brief STM32F3 DAC support - */ - -#ifndef _LIBMAPLE_STM32F3_DAC_H_ -#define _LIBMAPLE_STM32F3_DAC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -/** STM32F3 DAC register map type. */ -typedef struct dac_reg_map { - __io uint32 CR; /**< Control register */ - __io uint32 SWTRIGR; /**< Software trigger register */ - __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data - holding register */ - __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data - holding register */ - __io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data - holding register */ - __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data - holding register */ - __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data - holding register */ - __io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data - holding register */ - __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data - holding register */ - __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data - holding register */ - __io uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding - register */ - __io uint32 DOR1; /**< Channel 1 data output register */ - __io uint32 DOR2; /**< Channel 2 data output register */ -} dac_reg_map; - -//#define DAC1_BASE ((struct dac_reg_map*)0x40007400) -//#define DAC2_BASE ((struct dac_reg_map*)0x40009800) //TODO STM32F37/38xx - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/dma.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/dma.h deleted file mode 100644 index 9bb3b1b33..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/dma.h +++ /dev/null @@ -1,557 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * Copyright (c) 2012 LeafLabs, LLC - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/dma.h - * @author Marti Bolivar , - * Original implementation by Michael Hope, - * F3-port by Hanspeter Portner - * @brief STM32F3 DMA series header. - */ - -#ifndef _LIBMAPLE_STM32F3_DMA_H_ -#define _LIBMAPLE_STM32F3_DMA_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include - -/* - * Register maps and base pointers - */ - -/** - * @brief STM32F3 DMA register map type. - * - * Note that DMA controller 2 (register map base pointer DMA2_BASE) - * only supports channels 1--5. - */ -typedef struct dma_reg_map { - __io uint32 ISR; /**< Interrupt status register */ - __io uint32 IFCR; /**< Interrupt flag clear register */ - __io uint32 CCR1; /**< Channel 1 configuration register */ - __io uint32 CNDTR1; /**< Channel 1 number of data register */ - __io uint32 CPAR1; /**< Channel 1 peripheral address register */ - __io uint32 CMAR1; /**< Channel 1 memory address register */ - const uint32 RESERVED1; /**< Reserved. */ - __io uint32 CCR2; /**< Channel 2 configuration register */ - __io uint32 CNDTR2; /**< Channel 2 number of data register */ - __io uint32 CPAR2; /**< Channel 2 peripheral address register */ - __io uint32 CMAR2; /**< Channel 2 memory address register */ - const uint32 RESERVED2; /**< Reserved. */ - __io uint32 CCR3; /**< Channel 3 configuration register */ - __io uint32 CNDTR3; /**< Channel 3 number of data register */ - __io uint32 CPAR3; /**< Channel 3 peripheral address register */ - __io uint32 CMAR3; /**< Channel 3 memory address register */ - const uint32 RESERVED3; /**< Reserved. */ - __io uint32 CCR4; /**< Channel 4 configuration register */ - __io uint32 CNDTR4; /**< Channel 4 number of data register */ - __io uint32 CPAR4; /**< Channel 4 peripheral address register */ - __io uint32 CMAR4; /**< Channel 4 memory address register */ - const uint32 RESERVED4; /**< Reserved. */ - __io uint32 CCR5; /**< Channel 5 configuration register */ - __io uint32 CNDTR5; /**< Channel 5 number of data register */ - __io uint32 CPAR5; /**< Channel 5 peripheral address register */ - __io uint32 CMAR5; /**< Channel 5 memory address register */ - const uint32 RESERVED5; /**< Reserved. */ - __io uint32 CCR6; /**< Channel 6 configuration register */ - __io uint32 CNDTR6; /**< Channel 6 number of data register */ - __io uint32 CPAR6; /**< Channel 6 peripheral address register */ - __io uint32 CMAR6; /**< Channel 6 memory address register */ - const uint32 RESERVED6; /**< Reserved. */ - __io uint32 CCR7; /**< Channel 7 configuration register */ - __io uint32 CNDTR7; /**< Channel 7 number of data register */ - __io uint32 CPAR7; /**< Channel 7 peripheral address register */ - __io uint32 CMAR7; /**< Channel 7 memory address register */ - const uint32 RESERVED7; /**< Reserved. */ -} dma_reg_map; - -/** DMA controller 1 register map base pointer */ -#define DMA1_BASE ((struct dma_reg_map*)0x40020000) -/** DMA controller 2 register map base pointer */ -#define DMA2_BASE ((struct dma_reg_map*)0x40020400) - -/** - * @brief STM32F3 DMA channel (i.e. tube) register map type. - * Provides access to an individual channel's registers. - * @see dma_tube_regs() - */ -typedef struct dma_tube_reg_map { - __io uint32 CCR; /**< Channel configuration register */ - __io uint32 CNDTR; /**< Channel number of data register */ - __io uint32 CPAR; /**< Channel peripheral address register */ - __io uint32 CMAR; /**< Channel memory address register */ -} dma_tube_reg_map; - -/** DMA1 channel 1 register map base pointer */ -#define DMA1CH1_BASE ((struct dma_tube_reg_map*)0x40020008) -/** DMA1 channel 2 register map base pointer */ -#define DMA1CH2_BASE ((struct dma_tube_reg_map*)0x4002001C) -/** DMA1 channel 3 register map base pointer */ -#define DMA1CH3_BASE ((struct dma_tube_reg_map*)0x40020030) -/** DMA1 channel 4 register map base pointer */ -#define DMA1CH4_BASE ((struct dma_tube_reg_map*)0x40020044) -/** DMA1 channel 5 register map base pointer */ -#define DMA1CH5_BASE ((struct dma_tube_reg_map*)0x40020058) -/** DMA1 channel 6 register map base pointer */ -#define DMA1CH6_BASE ((struct dma_tube_reg_map*)0x4002006C) -/** DMA1 channel 7 register map base pointer */ -#define DMA1CH7_BASE ((struct dma_tube_reg_map*)0x40020080) - -/** DMA2 channel 1 register map base pointer */ -#define DMA2CH1_BASE ((struct dma_tube_reg_map*)0x40020408) -/** DMA2 channel 2 register map base pointer */ -#define DMA2CH2_BASE ((struct dma_tube_reg_map*)0x4002041C) -/** DMA2 channel 3 register map base pointer */ -#define DMA2CH3_BASE ((struct dma_tube_reg_map*)0x40020430) -/** DMA2 channel 4 register map base pointer */ -#define DMA2CH4_BASE ((struct dma_tube_reg_map*)0x40020444) -/** DMA2 channel 5 register map base pointer */ -#define DMA2CH5_BASE ((struct dma_tube_reg_map*)0x40020458) - -/* - * Register bit definitions - */ - -/* Interrupt status register */ - -#define DMA_ISR_TEIF_BIT 3 -#define DMA_ISR_HTIF_BIT 2 -#define DMA_ISR_TCIF_BIT 1 -#define DMA_ISR_GIF_BIT 0 - -#define DMA_ISR_TEIF (1 << DMA_ISR_TEIF_BIT) -#define DMA_ISR_HTIF (1 << DMA_ISR_HTIF_BIT) -#define DMA_ISR_TCIF (1 << DMA_ISR_TCIF_BIT) -#define DMA_ISR_GIF (1 << DMA_ISR_GIF_BIT) - -#define DMA_ISR_TEIF7_BIT 27 -#define DMA_ISR_HTIF7_BIT 26 -#define DMA_ISR_TCIF7_BIT 25 -#define DMA_ISR_GIF7_BIT 24 -#define DMA_ISR_TEIF6_BIT 23 -#define DMA_ISR_HTIF6_BIT 22 -#define DMA_ISR_TCIF6_BIT 21 -#define DMA_ISR_GIF6_BIT 20 -#define DMA_ISR_TEIF5_BIT 19 -#define DMA_ISR_HTIF5_BIT 18 -#define DMA_ISR_TCIF5_BIT 17 -#define DMA_ISR_GIF5_BIT 16 -#define DMA_ISR_TEIF4_BIT 15 -#define DMA_ISR_HTIF4_BIT 14 -#define DMA_ISR_TCIF4_BIT 13 -#define DMA_ISR_GIF4_BIT 12 -#define DMA_ISR_TEIF3_BIT 11 -#define DMA_ISR_HTIF3_BIT 10 -#define DMA_ISR_TCIF3_BIT 9 -#define DMA_ISR_GIF3_BIT 8 -#define DMA_ISR_TEIF2_BIT 7 -#define DMA_ISR_HTIF2_BIT 6 -#define DMA_ISR_TCIF2_BIT 5 -#define DMA_ISR_GIF2_BIT 4 -#define DMA_ISR_TEIF1_BIT 3 -#define DMA_ISR_HTIF1_BIT 2 -#define DMA_ISR_TCIF1_BIT 1 -#define DMA_ISR_GIF1_BIT 0 - -#define DMA_ISR_TEIF7 (1U << DMA_ISR_TEIF7_BIT) -#define DMA_ISR_HTIF7 (1U << DMA_ISR_HTIF7_BIT) -#define DMA_ISR_TCIF7 (1U << DMA_ISR_TCIF7_BIT) -#define DMA_ISR_GIF7 (1U << DMA_ISR_GIF7_BIT) -#define DMA_ISR_TEIF6 (1U << DMA_ISR_TEIF6_BIT) -#define DMA_ISR_HTIF6 (1U << DMA_ISR_HTIF6_BIT) -#define DMA_ISR_TCIF6 (1U << DMA_ISR_TCIF6_BIT) -#define DMA_ISR_GIF6 (1U << DMA_ISR_GIF6_BIT) -#define DMA_ISR_TEIF5 (1U << DMA_ISR_TEIF5_BIT) -#define DMA_ISR_HTIF5 (1U << DMA_ISR_HTIF5_BIT) -#define DMA_ISR_TCIF5 (1U << DMA_ISR_TCIF5_BIT) -#define DMA_ISR_GIF5 (1U << DMA_ISR_GIF5_BIT) -#define DMA_ISR_TEIF4 (1U << DMA_ISR_TEIF4_BIT) -#define DMA_ISR_HTIF4 (1U << DMA_ISR_HTIF4_BIT) -#define DMA_ISR_TCIF4 (1U << DMA_ISR_TCIF4_BIT) -#define DMA_ISR_GIF4 (1U << DMA_ISR_GIF4_BIT) -#define DMA_ISR_TEIF3 (1U << DMA_ISR_TEIF3_BIT) -#define DMA_ISR_HTIF3 (1U << DMA_ISR_HTIF3_BIT) -#define DMA_ISR_TCIF3 (1U << DMA_ISR_TCIF3_BIT) -#define DMA_ISR_GIF3 (1U << DMA_ISR_GIF3_BIT) -#define DMA_ISR_TEIF2 (1U << DMA_ISR_TEIF2_BIT) -#define DMA_ISR_HTIF2 (1U << DMA_ISR_HTIF2_BIT) -#define DMA_ISR_TCIF2 (1U << DMA_ISR_TCIF2_BIT) -#define DMA_ISR_GIF2 (1U << DMA_ISR_GIF2_BIT) -#define DMA_ISR_TEIF1 (1U << DMA_ISR_TEIF1_BIT) -#define DMA_ISR_HTIF1 (1U << DMA_ISR_HTIF1_BIT) -#define DMA_ISR_TCIF1 (1U << DMA_ISR_TCIF1_BIT) -#define DMA_ISR_GIF1 (1U << DMA_ISR_GIF1_BIT) - -/* Interrupt flag clear register */ - -#define DMA_IFCR_CTEIF7_BIT 27 -#define DMA_IFCR_CHTIF7_BIT 26 -#define DMA_IFCR_CTCIF7_BIT 25 -#define DMA_IFCR_CGIF7_BIT 24 -#define DMA_IFCR_CTEIF6_BIT 23 -#define DMA_IFCR_CHTIF6_BIT 22 -#define DMA_IFCR_CTCIF6_BIT 21 -#define DMA_IFCR_CGIF6_BIT 20 -#define DMA_IFCR_CTEIF5_BIT 19 -#define DMA_IFCR_CHTIF5_BIT 18 -#define DMA_IFCR_CTCIF5_BIT 17 -#define DMA_IFCR_CGIF5_BIT 16 -#define DMA_IFCR_CTEIF4_BIT 15 -#define DMA_IFCR_CHTIF4_BIT 14 -#define DMA_IFCR_CTCIF4_BIT 13 -#define DMA_IFCR_CGIF4_BIT 12 -#define DMA_IFCR_CTEIF3_BIT 11 -#define DMA_IFCR_CHTIF3_BIT 10 -#define DMA_IFCR_CTCIF3_BIT 9 -#define DMA_IFCR_CGIF3_BIT 8 -#define DMA_IFCR_CTEIF2_BIT 7 -#define DMA_IFCR_CHTIF2_BIT 6 -#define DMA_IFCR_CTCIF2_BIT 5 -#define DMA_IFCR_CGIF2_BIT 4 -#define DMA_IFCR_CTEIF1_BIT 3 -#define DMA_IFCR_CHTIF1_BIT 2 -#define DMA_IFCR_CTCIF1_BIT 1 -#define DMA_IFCR_CGIF1_BIT 0 - -#define DMA_IFCR_CTEIF7 (1U << DMA_IFCR_CTEIF7_BIT) -#define DMA_IFCR_CHTIF7 (1U << DMA_IFCR_CHTIF7_BIT) -#define DMA_IFCR_CTCIF7 (1U << DMA_IFCR_CTCIF7_BIT) -#define DMA_IFCR_CGIF7 (1U << DMA_IFCR_CGIF7_BIT) -#define DMA_IFCR_CTEIF6 (1U << DMA_IFCR_CTEIF6_BIT) -#define DMA_IFCR_CHTIF6 (1U << DMA_IFCR_CHTIF6_BIT) -#define DMA_IFCR_CTCIF6 (1U << DMA_IFCR_CTCIF6_BIT) -#define DMA_IFCR_CGIF6 (1U << DMA_IFCR_CGIF6_BIT) -#define DMA_IFCR_CTEIF5 (1U << DMA_IFCR_CTEIF5_BIT) -#define DMA_IFCR_CHTIF5 (1U << DMA_IFCR_CHTIF5_BIT) -#define DMA_IFCR_CTCIF5 (1U << DMA_IFCR_CTCIF5_BIT) -#define DMA_IFCR_CGIF5 (1U << DMA_IFCR_CGIF5_BIT) -#define DMA_IFCR_CTEIF4 (1U << DMA_IFCR_CTEIF4_BIT) -#define DMA_IFCR_CHTIF4 (1U << DMA_IFCR_CHTIF4_BIT) -#define DMA_IFCR_CTCIF4 (1U << DMA_IFCR_CTCIF4_BIT) -#define DMA_IFCR_CGIF4 (1U << DMA_IFCR_CGIF4_BIT) -#define DMA_IFCR_CTEIF3 (1U << DMA_IFCR_CTEIF3_BIT) -#define DMA_IFCR_CHTIF3 (1U << DMA_IFCR_CHTIF3_BIT) -#define DMA_IFCR_CTCIF3 (1U << DMA_IFCR_CTCIF3_BIT) -#define DMA_IFCR_CGIF3 (1U << DMA_IFCR_CGIF3_BIT) -#define DMA_IFCR_CTEIF2 (1U << DMA_IFCR_CTEIF2_BIT) -#define DMA_IFCR_CHTIF2 (1U << DMA_IFCR_CHTIF2_BIT) -#define DMA_IFCR_CTCIF2 (1U << DMA_IFCR_CTCIF2_BIT) -#define DMA_IFCR_CGIF2 (1U << DMA_IFCR_CGIF2_BIT) -#define DMA_IFCR_CTEIF1 (1U << DMA_IFCR_CTEIF1_BIT) -#define DMA_IFCR_CHTIF1 (1U << DMA_IFCR_CHTIF1_BIT) -#define DMA_IFCR_CTCIF1 (1U << DMA_IFCR_CTCIF1_BIT) -#define DMA_IFCR_CGIF1 (1U << DMA_IFCR_CGIF1_BIT) - -/* Channel configuration register */ - -#define DMA_CCR_MEM2MEM_BIT 14 -#define DMA_CCR_MINC_BIT 7 -#define DMA_CCR_PINC_BIT 6 -#define DMA_CCR_CIRC_BIT 5 -#define DMA_CCR_DIR_BIT 4 -#define DMA_CCR_TEIE_BIT 3 -#define DMA_CCR_HTIE_BIT 2 -#define DMA_CCR_TCIE_BIT 1 -#define DMA_CCR_EN_BIT 0 - -#define DMA_CCR_MEM2MEM (1U << DMA_CCR_MEM2MEM_BIT) -#define DMA_CCR_PL (0x3 << 12) -#define DMA_CCR_PL_LOW (0x0 << 12) -#define DMA_CCR_PL_MEDIUM (0x1 << 12) -#define DMA_CCR_PL_HIGH (0x2 << 12) -#define DMA_CCR_PL_VERY_HIGH (0x3 << 12) -#define DMA_CCR_MSIZE (0x3 << 10) -#define DMA_CCR_MSIZE_8BITS (0x0 << 10) -#define DMA_CCR_MSIZE_16BITS (0x1 << 10) -#define DMA_CCR_MSIZE_32BITS (0x2 << 10) -#define DMA_CCR_PSIZE (0x3 << 8) -#define DMA_CCR_PSIZE_8BITS (0x0 << 8) -#define DMA_CCR_PSIZE_16BITS (0x1 << 8) -#define DMA_CCR_PSIZE_32BITS (0x2 << 8) -#define DMA_CCR_MINC (1U << DMA_CCR_MINC_BIT) -#define DMA_CCR_PINC (1U << DMA_CCR_PINC_BIT) -#define DMA_CCR_CIRC (1U << DMA_CCR_CIRC_BIT) -#define DMA_CCR_DIR (1U << DMA_CCR_DIR_BIT) -#define DMA_CCR_DIR_FROM_PER (0U << DMA_CCR_DIR_BIT) -#define DMA_CCR_DIR_FROM_MEM (1U << DMA_CCR_DIR_BIT) -#define DMA_CCR_TEIE (1U << DMA_CCR_TEIE_BIT) -#define DMA_CCR_HTIE (1U << DMA_CCR_HTIE_BIT) -#define DMA_CCR_TCIE (1U << DMA_CCR_TCIE_BIT) -#define DMA_CCR_EN (1U << DMA_CCR_EN_BIT) - -/* - * Devices - */ - -extern dma_dev *DMA1; -extern dma_dev *DMA2; - -/* - * Other types needed by, or useful for, . - */ - -/** - * @brief STM32F3 dma_tube. - * On STM32F3, DMA tubes are just channels. - */ -#define dma_tube dma_channel - -/** - * @brief On STM32F3, dma_channel_reg_map is an alias for dma_tube_reg_map. - * This is for backwards compatibility. */ -#define dma_channel_reg_map dma_tube_reg_map - -/** - * @brief STM32F3 configuration flags for dma_tube_config - * @see struct dma_tube_config - */ -typedef enum dma_cfg_flags { - /** - * Source address increment mode - * - * If this flag is set, the source address is incremented (by the - * source size) after each DMA transfer. - */ - DMA_CFG_SRC_INC = 1U << 31, - - /** - * Destination address increment mode - * - * If this flag is set, the destination address is incremented (by - * the destination size) after each DMA transfer. - */ - DMA_CFG_DST_INC = 1U << 30, - - /** - * Circular mode - * - * This mode is not available for memory-to-memory transfers. - */ - DMA_CFG_CIRC = DMA_CCR_CIRC, - - /** Transfer complete interrupt enable */ - DMA_CFG_CMPLT_IE = DMA_CCR_TCIE, - /** Transfer half-complete interrupt enable */ - DMA_CFG_HALF_CMPLT_IE = DMA_CCR_HTIE, - /** Transfer error interrupt enable */ - DMA_CFG_ERR_IE = DMA_CCR_TEIE, -} dma_cfg_flags; - -/** - * @brief STM32F3 DMA request sources. - * - * IMPORTANT: - * - * 1. On STM32F3, each dma_request_src can only be used by a - * particular tube on a particular DMA controller. For example, - * DMA_REQ_SRC_ADC1 belongs to DMA1, tube 1. DMA2 cannot serve - * requests from ADC1, nor can DMA1 tube 2, etc. If you try to use a - * request source with the wrong DMA controller or tube on STM32F3, - * dma_tube_cfg() will fail. - * - * 2. In general, a DMA tube can only serve a single request source at - * a time, and on STM32F3, Terrible Super-Bad Things will happen if - * two request sources are active for a single tube. - * - * To make all this easier to sort out, these dma_request_src - * enumerators are grouped by DMA controller and tube. - * - * @see struct dma_tube_config - * @see dma_tube_cfg() - */ -typedef enum dma_request_src { - /* Each request source encodes the DMA controller and channel it - * belongs to, for error checking in dma_tube_cfg(). */ - - /* DMA1 request sources */ - - /**@{*/ - /** (DMA1, tube 1) */ - DMA_REQ_SRC_ADC1 = (RCC_DMA1 << 3) | 1, - DMA_REQ_SRC_TIM2_CH3 = (RCC_DMA1 << 3) | 1, - DMA_REQ_SRC_TIM4_CH1 = (RCC_DMA1 << 3) | 1, - DMA_REQ_SRC_TIM17_CH1 = (RCC_DMA1 << 3) | 1, - DMA_REQ_SRC_TIM17_UP = (RCC_DMA1 << 3) | 1, - /**@}*/ - - /**@{*/ - /** (DMA1, tube 2)*/ - DMA_REQ_SRC_SPI1_RX = (RCC_DMA1 << 3) | 2, - DMA_REQ_SRC_USART3_TX = (RCC_DMA1 << 3) | 2, - DMA_REQ_SRC_TIM1_CH1 = (RCC_DMA1 << 3) | 2, - DMA_REQ_SRC_TIM2_UP = (RCC_DMA1 << 3) | 2, - DMA_REQ_SRC_TIM3_CH3 = (RCC_DMA1 << 3) | 2, - /**@}*/ - - /**@{*/ - /** (DMA1, tube 3)*/ - DMA_REQ_SRC_SPI1_TX = (RCC_DMA1 << 3) | 3, - DMA_REQ_SRC_USART3_RX = (RCC_DMA1 << 3) | 3, - DMA_REQ_SRC_TIM1_CH2 = (RCC_DMA1 << 3) | 3, - DMA_REQ_SRC_TIM3_CH4 = (RCC_DMA1 << 3) | 3, - DMA_REQ_SRC_TIM3_UP = (RCC_DMA1 << 3) | 3, - /*DMA_REQ_SRC_TIM6_UP = (RCC_DMA1 << 3) | 3,*/ /* remap in SYSCFGR */ - /*DMA_REQ_SRC_DAC_CH1 = (RCC_DMA1 << 3) | 3,*/ /* remap in SYSCFGR */ - DMA_REQ_SRC_TIM16_CH1 = (RCC_DMA1 << 3) | 3, - DMA_REQ_SRC_TIM16_UP = (RCC_DMA1 << 3) | 3, - /**@}*/ - - /**@{*/ - /** (DMA1, tube 4)*/ - DMA_REQ_SRC_SPI2_RX = (RCC_DMA1 << 3) | 4, - DMA_REQ_SRC_USART1_TX = (RCC_DMA1 << 3) | 4, - DMA_REQ_SRC_I2C2_TX = (RCC_DMA1 << 3) | 4, - DMA_REQ_SRC_TIM1_CH4 = (RCC_DMA1 << 3) | 4, - DMA_REQ_SRC_TIM1_TRIG = (RCC_DMA1 << 3) | 4, - DMA_REQ_SRC_TIM1_COM = (RCC_DMA1 << 3) | 4, - DMA_REQ_SRC_TIM4_CH2 = (RCC_DMA1 << 3) | 4, - /*DMA_REQ_SRC_TIM7_UP = (RCC_DMA1 << 3) | 4,*/ /* remap in SYSCFGR */ - /*DMA_REQ_SRC_DAC_CH2 = (RCC_DMA1 << 3) | 4,*/ /* remap in SYSCFGR */ - /**@}*/ - - /**@{*/ - /** (DMA1, tube 5)*/ - DMA_REQ_SRC_SPI2_TX = (RCC_DMA1 << 3) | 5, - DMA_REQ_SRC_USART1_RX = (RCC_DMA1 << 3) | 5, - DMA_REQ_SRC_I2C2_RX = (RCC_DMA1 << 3) | 5, - DMA_REQ_SRC_TIM1_UP = (RCC_DMA1 << 3) | 5, - DMA_REQ_SRC_TIM2_CH1 = (RCC_DMA1 << 3) | 5, - DMA_REQ_SRC_TIM4_CH3 = (RCC_DMA1 << 3) | 5, - DMA_REQ_SRC_TIM15_CH1 = (RCC_DMA1 << 3) | 5, - DMA_REQ_SRC_TIM15_UP = (RCC_DMA1 << 3) | 5, - DMA_REQ_SRC_TIM15_TRIG = (RCC_DMA1 << 3) | 5, - DMA_REQ_SRC_TIM15_COM = (RCC_DMA1 << 3) | 5, - /**@}*/ - - /**@{*/ - /** (DMA1, tube 6)*/ - DMA_REQ_SRC_USART2_RX = (RCC_DMA1 << 3) | 6, - DMA_REQ_SRC_I2C1_TX = (RCC_DMA1 << 3) | 6, - DMA_REQ_SRC_TIM1_CH3 = (RCC_DMA1 << 3) | 6, - DMA_REQ_SRC_TIM3_CH1 = (RCC_DMA1 << 3) | 6, - DMA_REQ_SRC_TIM3_TRIG = (RCC_DMA1 << 3) | 6, - /*DMA_REQ_SRC_TIM16_CH1 = (RCC_DMA1 << 3) | 6,*/ /* remap in SYSCFGR */ - /*DMA_REQ_SRC_TIM16_UP = (RCC_DMA1 << 3) | 6,*/ /* remap in SYSCFGR */ - /**@}*/ - - /**@{*/ - /* Tube 7 */ - DMA_REQ_SRC_USART2_TX = (RCC_DMA1 << 3) | 7, - DMA_REQ_SRC_I2C1_RX = (RCC_DMA1 << 3) | 7, - DMA_REQ_SRC_TIM2_CH2 = (RCC_DMA1 << 3) | 7, - DMA_REQ_SRC_TIM2_CH4 = (RCC_DMA1 << 3) | 7, - DMA_REQ_SRC_TIM4_UP = (RCC_DMA1 << 3) | 7, - /**@}*/ - - /* DMA2 request sources */ - - /**@{*/ - /** (DMA2, tube 1)*/ - DMA_REQ_SRC_ADC2 = (RCC_DMA2 << 3) | 1, - DMA_REQ_SRC_SPI3_RX = (RCC_DMA2 << 3) | 1, - DMA_REQ_SRC_TIM8_CH3 = (RCC_DMA2 << 3) | 1, - DMA_REQ_SRC_TIM8_UP = (RCC_DMA2 << 3) | 1, - /**@}*/ - - /**@{*/ - /** (DMA2, tube 2)*/ - DMA_REQ_SRC_ADC4 = (RCC_DMA2 << 3) | 2, - DMA_REQ_SRC_SPI3_TX = (RCC_DMA2 << 3) | 2, - DMA_REQ_SRC_TIM8_CH4 = (RCC_DMA2 << 3) | 2, - DMA_REQ_SRC_TIM8_TRIG = (RCC_DMA2 << 3) | 2, - DMA_REQ_SRC_TIM8_COM = (RCC_DMA2 << 3) | 2, - /**@}*/ - - /**@{*/ - /** (DMA2, tube 3)*/ - /* DMA_REQ_SRC_ADC2 = (RCC_DMA2 << 3) | 3,*/ /* remap in SYSCFGR */ - DMA_REQ_SRC_UART4_RX = (RCC_DMA2 << 3) | 3, - DMA_REQ_SRC_TIM6_UP = (RCC_DMA2 << 3) | 3, - DMA_REQ_SRC_DAC1_CH1 = (RCC_DMA2 << 3) | 3, - DMA_REQ_SRC_TIM8_CH1 = (RCC_DMA2 << 3) | 3, - /**@}*/ - - /**@{*/ - /** (DMA2, tube 4)*/ - /*DMA_REQ_SRC_ADC4 = (RCC_DMA2 << 3) | 4,*/ /* remap in SYSCFGR */ - DMA_REQ_SRC_TIM7_UP = (RCC_DMA2 << 3) | 4, - DMA_REQ_SRC_DAC1_CH2 = (RCC_DMA2 << 3) | 4, - /**@}*/ - - /**@{*/ - /** (DMA2, tube 5)*/ - DMA_REQ_SRC_ADC3 = (RCC_DMA2 << 3) | 5, - DMA_REQ_SRC_UART4_TX = (RCC_DMA2 << 3) | 5, - DMA_REQ_SRC_TIM8_CH2 = (RCC_DMA2 << 3) | 5, - /**@}*/ -} dma_request_src; - -/* - * Convenience routines. - */ - -/** - * @brief On STM32F3, dma_is_channel_enabled() is an alias for - * dma_is_enabled(). - * This is for backwards compatibility. - */ -#define dma_is_channel_enabled dma_is_enabled - -#define DMA_CHANNEL_NREGS 5 /* accounts for reserved word */ -static inline dma_tube_reg_map* dma_tube_regs(dma_dev *dev, dma_tube tube) { - __io uint32 *ccr1 = &dev->regs->CCR1; - return (dma_channel_reg_map*)(ccr1 + DMA_CHANNEL_NREGS * (tube - 1)); -} - -/** - * @brief On STM32F3, dma_channel_regs() is an alias for dma_tube_regs(). - * This is for backwards compatibility. */ -#define dma_channel_regs(dev, ch) dma_tube_regs(dev, ch) - -static inline uint8 dma_is_enabled(dma_dev *dev, dma_tube tube) { - return (uint8)(dma_tube_regs(dev, tube)->CCR & DMA_CCR_EN); -} - -static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_tube tube) { - uint8 shift = (tube - 1) * 4; - return (dev->regs->ISR >> shift) & 0xF; -} - -static inline void dma_clear_isr_bits(dma_dev *dev, dma_tube tube) { - dev->regs->IFCR = (1U << (4 * (tube - 1))); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/exti.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/exti.h deleted file mode 100644 index 05ed1e6e9..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/exti.h +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/exti.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 external interrupts - */ - -#ifndef _LIBMAPLE_STM32F3_EXTI_H_ -#define _LIBMAPLE_STM32F3_EXTI_H_ - -#ifdef __cpluspus -extern "C" { -#endif - -//FIXME F3 has up to 36 EXTIs, expose and handle internal EXTIs 16-35 -struct exti_reg_map; -#define EXTI_BASE ((struct exti_reg_map*)0x40010400) - -#ifdef __cpluspus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/flash.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/flash.h deleted file mode 100644 index 85baf9b3c..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/flash.h +++ /dev/null @@ -1,164 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/flash.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 Flash header. - * - * Provides register map, base pointer, and register bit definitions - * for the Flash controller on the STM32F3 line, along with - * series-specific configuration values. - */ - -#ifndef _LIBMAPLE_STM32F3_FLASH_H_ -#define _LIBMAPLE_STM32F3_FLASH_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -/* - * Register map - */ - -/** @brief STM32F3 Flash register map type */ -typedef struct flash_reg_map { - __io uint32 ACR; /**< Access control register */ - __io uint32 KEYR; /**< Key register */ - __io uint32 OPTKEYR; /**< OPTKEY register */ - __io uint32 SR; /**< Status register */ - __io uint32 CR; /**< Control register */ - __io uint32 AR; /**< Address register */ - __io uint32 OBR; /**< Option byte register */ - __io uint32 WRPR; /**< Write protection register */ -} flash_reg_map; - -#define FLASH_BASE ((struct flash_reg_map*)0x40022000) - -/* - * Register bit definitions - */ - -/* Access control register */ - -#define FLASH_ACR_PRFTBS_BIT 5 -#define FLASH_ACR_PRFTBE_BIT 4 -#define FLASH_ACR_HLFCYA_BIT 3 - -#define FLASH_ACR_PRFTBS (1U << FLASH_ACR_PRFTBS_BIT) -#define FLASH_ACR_PRFTBE (1U << FLASH_ACR_PRFTBE_BIT) -#define FLASH_ACR_HLFCYA (1U << FLASH_ACR_HLFCYA_BIT) -#define FLASH_ACR_LATENCY 0x7 - -/* Status register */ - -#define FLASH_SR_EOP_BIT 5 -#define FLASH_SR_WRPRTERR_BIT 4 -#define FLASH_SR_PGERR_BIT 2 -#define FLASH_SR_BSY_BIT 0 - -#define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT) -#define FLASH_SR_WRPRTERR (1U << FLASH_SR_WRPRTERR_BIT) -#define FLASH_SR_PGERR (1U << FLASH_SR_PGERR_BIT) -#define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT) - -/* Control register */ - -#define FLASH_CR_OBL_LAUNCH_BIT 13 -#define FLASH_CR_EOPIE_BIT 12 -#define FLASH_CR_ERRIE_BIT 10 -#define FLASH_CR_OPTWRE_BIT 9 -#define FLASH_CR_LOCK_BIT 7 -#define FLASH_CR_STRT_BIT 6 -#define FLASH_CR_OPTER_BIT 5 -#define FLASH_CR_OPTPG_BIT 4 -#define FLASH_CR_MER_BIT 2 -#define FLASH_CR_PER_BIT 1 -#define FLASH_CR_PG_BIT 0 - -#define FLASH_CR_OBL_LAUNCH (1U << FLASH_CR_OBL_LAUNCH_BIT) -#define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT) -#define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT) -#define FLASH_CR_OPTWRE (1U << FLASH_CR_OPTWRE_BIT) -#define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT) -#define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT) -#define FLASH_CR_OPTER (1U << FLASH_CR_OPTER_BIT) -#define FLASH_CR_OPTPG (1U << FLASH_CR_OPTPG_BIT) -#define FLASH_CR_MER (1U << FLASH_CR_MER_BIT) -#define FLASH_CR_PER (1U << FLASH_CR_PER_BIT) -#define FLASH_CR_PG (1U << FLASH_CR_PG_BIT) - -/* Option byte register */ - -#define FLASH_OBR_DATA1_SHIFT 24 -#define FLASH_OBR_DATA0_SHIFT 16 -#define FLASH_OBR_BYTE_SHIFT 8 -#define FLASH_OBR_SRAM_PE_BIT 14 -#define FLASH_OBR_VDDA_MONITOR_BIT 13 -#define FLASH_OBR_nBOOT1_BIT 12 -#define FLASH_OBR_nRST_STDBY_BIT 10 -#define FLASH_OBR_nRST_STOP_BIT 9 -#define FLASH_OBR_WDG_SW_BIT 8 -#define FLASH_OBR_RDPRT_SHIFT 1 -#define FLASH_OBR_OPTERR_BIT 0 - -#define FLASH_OBR_DATA1 (0xFF << FLASH_OBR_DATA1_SHIFT) -#define FLASH_OBR_DATA0 (0xFF << FLASH_OBR_DATA0_SHIFT) -#define FLASH_OBR_BYTE (0xFF << FLASH_OBR_BYTE_SHIFT) -#define FLASH_OBR_SRAM_PE_STDBY (1U << FLASH_OBR_SRAM_PE_STDBY_BIT) -#define FLASH_OBR_VDDA_MONITOR_STDBY (1U << FLASH_OBR_VDDA_MONITOR_STDBY_BIT) -#define FLASH_OBR_nBOOT1_STDBY (1U << FLASH_OBR_nBOOT1_STDBY_BIT) -#define FLASH_OBR_nRST_STDBY (1U << FLASH_OBR_nRST_STDBY_BIT) -#define FLASH_OBR_nRST_STOP (1U << FLASH_OBR_nRST_STOP_BIT) -#define FLASH_OBR_WDG_SW (1U << FLASH_OBR_WDG_SW_BIT) -#define FLASH_OBR_RDPRT (0x3 << FLASH_OBR_RDPRT_SHIFT) -#define FLASH_OBR_OPTERR (1U << FLASH_OBR_OPTERR_BIT) - -/* - * Series-specific configuration values. - */ - -#define FLASH_SAFE_WAIT_STATES FLASH_WAIT_STATE_2 - -/* Flash memory features available via ACR */ -enum { - FLASH_PREFETCH = 0x10, - FLASH_HALF_CYCLE = 0x8, - FLASH_ICACHE = 0x0, /* Not available on STM32F3 */ - FLASH_DCACHE = 0x0, /* Not available on STM32F3 */ -}; - -/* TODO add routines for option byte handling, e.g. nBoot1 */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/gpio.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/gpio.h deleted file mode 100644 index 50e8c091e..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/gpio.h +++ /dev/null @@ -1,255 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/gpio.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 GPIO support. - */ - -#ifndef _LIBMAPLE_STM32F3_GPIO_H_ -#define _LIBMAPLE_STM32F3_GPIO_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -/* - * GPIO register maps and devices - */ - -/** GPIO register map type */ -typedef struct gpio_reg_map { - __io uint32 MODER; /**< Mode register */ - __io uint32 OTYPER; /**< Output type register */ - __io uint32 OSPEEDR; /**< Output speed register */ - __io uint32 PUPDR; /**< Pull-up/pull-down register */ - __io uint32 IDR; /**< Input data register */ - __io uint32 ODR; /**< Output data register */ - __io uint32 BSRR; /**< Bit set/reset register */ - __io uint32 LCKR; /**< Configuration lock register */ - __io uint32 AFRL; /**< Alternate function low register */ - __io uint32 AFRH; /**< Alternate function high register */ - __io uint32 BRR; /**< Port bit reset register */ -} gpio_reg_map; - -/** GPIO port A register map base pointer */ -#define GPIOA_BASE ((struct gpio_reg_map*)0x48000000) -/** GPIO port B register map base pointer */ -#define GPIOB_BASE ((struct gpio_reg_map*)0x48000400) -/** GPIO port C register map base pointer */ -#define GPIOC_BASE ((struct gpio_reg_map*)0x48000800) -/** GPIO port D register map base pointer */ -#define GPIOD_BASE ((struct gpio_reg_map*)0x48000C00) -/** GPIO port E register map base pointer */ -#define GPIOE_BASE ((struct gpio_reg_map*)0x48001000) -/** GPIO port F register map base pointer */ -#define GPIOF_BASE ((struct gpio_reg_map*)0x48001400) - -struct gpio_dev; -extern struct gpio_dev* const GPIOA; -extern struct gpio_dev gpioa; -extern struct gpio_dev* const GPIOB; -extern struct gpio_dev gpiob; -extern struct gpio_dev* const GPIOC; -extern struct gpio_dev gpioc; -extern struct gpio_dev* const GPIOD; -extern struct gpio_dev gpiod; -extern struct gpio_dev* const GPIOE; -extern struct gpio_dev gpioe; -extern struct gpio_dev* const GPIOF; -extern struct gpio_dev gpiof; - -/* - * Register bit definitions - * - * Currently, we only provide masks to be used for shifting for some - * registers, rather than repeating the same values 16 times. - */ - -/* Mode register */ - -#define GPIO_MODER_INPUT 0x0 -#define GPIO_MODER_OUTPUT 0x1 -#define GPIO_MODER_AF 0x2 -#define GPIO_MODER_ANALOG 0x3 - -/* Output type register */ - -#define GPIO_OTYPER_PP 0x0 -#define GPIO_OTYPER_OD 0x1 - -/* Output speed register */ - -#define GPIO_OSPEEDR_LOW 0x0 -#define GPIO_OSPEEDR_MED 0x1 -#define GPIO_OSPEEDR_FAST 0x2 -#define GPIO_OSPEEDR_HIGH 0x3 - -/* Pull-up/pull-down register */ - -#define GPIO_PUPDR_NOPUPD 0x0 -#define GPIO_PUPDR_PU 0x1 -#define GPIO_PUPDR_PD 0x2 - -/* Alternate function register low */ - -#define GPIO_AFRL_AF0 (0xFU << 0) -#define GPIO_AFRL_AF1 (0xFU << 4) -#define GPIO_AFRL_AF2 (0xFU << 8) -#define GPIO_AFRL_AF3 (0xFU << 12) -#define GPIO_AFRL_AF4 (0xFU << 16) -#define GPIO_AFRL_AF5 (0xFU << 20) -#define GPIO_AFRL_AF6 (0xFU << 24) -#define GPIO_AFRL_AF7 (0xFU << 28) - -/* Alternate function register high */ - -#define GPIO_AFRH_AF8 (0xFU << 0) -#define GPIO_AFRH_AF9 (0xFU << 4) -#define GPIO_AFRH_AF10 (0xFU << 8) -#define GPIO_AFRH_AF11 (0xFU << 12) -#define GPIO_AFRH_AF12 (0xFU << 16) -#define GPIO_AFRH_AF13 (0xFU << 20) -#define GPIO_AFRH_AF14 (0xFU << 24) -#define GPIO_AFRH_AF15 (0xFU << 28) - -/* - * GPIO routines - */ - -/** - * @brief GPIO pin modes - */ -typedef enum gpio_pin_mode { - GPIO_MODE_INPUT = GPIO_MODER_INPUT, /**< Input mode */ - GPIO_MODE_OUTPUT = GPIO_MODER_OUTPUT, /**< Output mode */ - GPIO_MODE_AF = GPIO_MODER_AF, /**< Alternate function mode */ - GPIO_MODE_ANALOG = GPIO_MODER_ANALOG, /**< Analog mode */ -} gpio_pin_mode; - -/** - * @brief Additional flags to be used when setting a pin's mode. - * - * Beyond the basic modes (input, general purpose output, alternate - * function, and analog), there are three parameters that can affect a - * pin's mode: - * - * 1. Output type: push/pull or open-drain. This only has an effect - * for output modes. Choices are: GPIO_MODEF_TYPE_PP (the default) - * and GPIO_MODEF_TYPE_OD. - * - * 2. Output speed: specifies the frequency at which a pin changes - * state. This only has an effect for output modes. Choices are: - * GPIO_MODEF_SPEED_LOW (default), GPIO_MODEF_SPEED_MED, - * GPIO_MODEF_SPEED_FAST, and GPIO_MODEF_SPEED_HIGH. - * - * 3. Push/pull setting: All GPIO pins have weak pull-up and pull-down - * resistors that can be enabled when the pin's mode is - * set. Choices are: GPIO_MODEF_PUPD_NONE (default), - * GPIO_MODEF_PUPD_PU, and GPIO_MODEF_PUPD_PD. - */ -typedef enum gpio_mode_flags { - /* Output type in bit 0 */ - GPIO_MODEF_TYPE_PP = GPIO_OTYPER_PP, /**< Output push/pull (default). - Applies only when the mode - specifies output. */ - GPIO_MODEF_TYPE_OD = GPIO_OTYPER_OD, /**< Output open drain. - Applies only when the mode - specifies output. */ - - /* Speed in bits 2:1 */ - GPIO_MODEF_SPEED_LOW = GPIO_OSPEEDR_LOW << 1, /**< Low speed (default): - 2 MHz. */ - GPIO_MODEF_SPEED_MED = GPIO_OSPEEDR_MED << 1, /**< Medium speed: 25 MHz. */ - GPIO_MODEF_SPEED_FAST = GPIO_OSPEEDR_FAST << 1, /**< Fast speed: 50 MHz. */ - GPIO_MODEF_SPEED_HIGH = GPIO_OSPEEDR_HIGH << 1, /**< High speed: FIXME one of those does not exist on the F3 - 100 MHz on 30 pF, - 80 MHz on 15 pF. */ - - /* Pull-up/pull-down in bits 4:3 */ - GPIO_MODEF_PUPD_NONE = GPIO_PUPDR_NOPUPD << 3, /**< No pull-up/pull-down - (default). */ - GPIO_MODEF_PUPD_PU = GPIO_PUPDR_PU << 3, /**< Pull-up */ - GPIO_MODEF_PUPD_PD = GPIO_PUPDR_PD << 3, /**< Pull-down */ -} gpio_mode_flags; - -void gpio_set_modef(struct gpio_dev *dev, - uint8 bit, - gpio_pin_mode mode, - unsigned flags); - -/** - * @brief Set the mode of a GPIO pin. - * - * Calling this function is equivalent to calling gpio_set_modef(dev, - * pin, mode, GPIO_MODE_SPEED_HIGH). Note that this overrides the - * default speed. - * - * @param dev GPIO device. - * @param bit Bit on the device whose mode to set, 0--15. - * @param mode Mode to set the pin to. - */ -static inline void gpio_set_mode(struct gpio_dev *dev, - uint8 bit, - gpio_pin_mode mode) { - gpio_set_modef(dev, bit, mode, GPIO_MODEF_SPEED_HIGH); -} - -/** - * @brief GPIO alternate functions. - * Use these to select an alternate function for a pin. - * @see gpio_set_af() - */ -typedef enum gpio_af { - GPIO_AF_0 = 0x0, /**< alternate function 0. */ - GPIO_AF_1 = 0x1, /**< alternate function 1. */ - GPIO_AF_2 = 0x2, /**< alternate function 2. */ - GPIO_AF_3 = 0x3, /**< alternate function 3. */ - GPIO_AF_4 = 0x4, /**< alternate function 4. */ - GPIO_AF_5 = 0x5, /**< alternate function 5. */ - GPIO_AF_6 = 0x6, /**< alternate function 6. */ - GPIO_AF_7 = 0x7, /**< alternate function 7. */ - GPIO_AF_8 = 0x8, /**< alternate function 8. */ - GPIO_AF_9 = 0x9, /**< alternate function 9. */ - GPIO_AF_10 = 0xA, /**< alternate function 10. */ - GPIO_AF_11 = 0xB, /**< alternate function 11. */ - GPIO_AF_12 = 0xC, /**< alternate function 12. */ - GPIO_AF_13 = 0xD, /**< alternate function 13. */ - GPIO_AF_14 = 0xE, /**< alternate function 14. */ - GPIO_AF_15 = 0xF, /**< alternate function 14. */ -} gpio_af; - -void gpio_set_af(struct gpio_dev *dev, uint8 bit, gpio_af af); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/i2c.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/i2c.h deleted file mode 100644 index c7be377fc..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/i2c.h +++ /dev/null @@ -1,315 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/i2c.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 I2C - */ - -#ifndef _LIBMAPLE_STM32F3_I2C_H_ -#define _LIBMAPLE_STM32F3_I2C_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include -#include - -/* - * Register maps - */ - -/** I2C register map type */ -typedef struct i2c_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 OAR1; /**< Own address register 1 */ - __io uint32 OAR2; /**< Own address register 2 */ - __io uint32 TIMINGR; /**< Timing register */ - __io uint32 TIMEOUTR; /**< Timeout register */ - __io uint32 ISR; /**< Interrupt and status register */ - __io uint32 ICR; /**< Interrupt clear register */ - __io uint32 PECR; /**< PEC register */ - __io uint32 RXDR; /**< Receive data register */ - __io uint32 TXDR; /**< Transmit data register */ -} i2c_reg_map; - -extern i2c_dev* const I2C1; -extern i2c_dev* const I2C2; - -/* - * Register map base pointers - */ - -/** STM32F3 I2C1 register map base pointer */ -#define I2C1_BASE ((struct i2c_reg_map*)0x40005400) -/** STM32F3 I2C2 register map base pointer */ -#define I2C2_BASE ((struct i2c_reg_map*)0x40005800) - -/* - * Register bit definitions - */ - -/* Control register 1 */ -#define I2C_CR1_PECEN_BIT 23 -#define I2C_CR1_ALERTEN_BIT 22 -#define I2C_CR1_SMBDEN_BIT 21 -#define I2C_CR1_SMBHEN_BIT 20 -#define I2C_CR1_GCEN_BIT 19 -#define I2C_CR1_WUPEN_BIT 18 -#define I2C_CR1_NOSTRETCH_BIT 17 -#define I2C_CR1_SBC_BIT 16 -#define I2C_CR1_RXDMAEN_BIT 15 -#define I2C_CR1_TXDMAEN_BIT 14 -#define I2C_CR1_ANFOFF_BIT 12 -#define I2C_CR1_DNF_SHIFT 8 -#define I2C_CR1_ERRIE_BIT 7 -#define I2C_CR1_TCIE_BIT 6 -#define I2C_CR1_STOPIE_BIT 5 -#define I2C_CR1_NACKIE_BIT 4 -#define I2C_CR1_ADDRIE_BIT 3 -#define I2C_CR1_RXIE_BIT 2 -#define I2C_CR1_TXIE_BIT 1 -#define I2C_CR1_PE_BIT 0 - -#define I2C_CR1_PECEN (1U << I2C_CR1_PECEN_BIT) -#define I2C_CR1_ALERTEN (1U << I2C_CR1_ALERTEN_BIT) -#define I2C_CR1_SMBDEN (1U << I2C_CR1_SMBDEN_BIT) -#define I2C_CR1_SMBHEN (1U << I2C_CR1_SMBHEN_BIT) -#define I2C_CR1_GCEN (1U << I2C_CR1_GCEN_BIT) -#define I2C_CR1_WUPEN (1U << I2C_CR1_WUPEN_BIT) -#define I2C_CR1_NOSTRETCH (1U << I2C_CR1_NOSTRETCH_BIT) -#define I2C_CR1_SBC (1U << I2C_CR1_SBC_BIT) -#define I2C_CR1_RXDMAEN (1U << I2C_CR1_RXDMAEN_BIT) -#define I2C_CR1_TXDMAEN (1U << I2C_CR1_TXDMAEN_BIT) -#define I2C_CR1_ANFOFF (1U << I2C_CR1_ANFOFF_BIT) -#define I2C_CR1_DNF (0xF << I2C_CR1_DNF_SHIFT) -#define I2C_CR1_ERRIE (1U << I2C_CR1_ERRIE_BIT) -#define I2C_CR1_TCIE (1U << I2C_CR1_TCIE_BIT) -#define I2C_CR1_STOPIE (1U << I2C_CR1_STOPIE_BIT) -#define I2C_CR1_NACKIE (1U << I2C_CR1_NACKIE_BIT) -#define I2C_CR1_ADDRIE (1U << I2C_CR1_ADDRIE_BIT) -#define I2C_CR1_RXIE (1U << I2C_CR1_RXIE_BIT) -#define I2C_CR1_TXIE (1U << I2C_CR1_TXIE_BIT) -#define I2C_CR1_PE (1U << I2C_CR1_PE_BIT) - -/* Control register 2 */ -#define I2C_CR2_PECBYTE_BIT 26 -#define I2C_CR2_AUTOEND_BIT 25 -#define I2C_CR2_RELOAD_BIT 24 -#define I2C_CR2_NBYTES_SHIFT 16 -#define I2C_CR2_NACK_BIT 15 -#define I2C_CR2_STOP_BIT 14 -#define I2C_CR2_START_BIT 13 -#define I2C_CR2_HEAD10R_BIT 12 -#define I2C_CR2_ADD10_BIT 11 -#define I2C_CR2_RD_WRN_BIT 10 -#define I2C_CR2_SADD_7_BIT_SHIFT 1 -#define I2C_CR2_SADD_10_BIT_SHIFT 0 - -#define I2C_CR2_PECBYTE (1U << I2C_CR2_PECBYTE_BIT) -#define I2C_CR2_AUTOEND (1U << I2C_CR2_AUTOEND_BIT) -#define I2C_CR2_RELOAD (1U << I2C_CR2_RELOAD_BIT) -#define I2C_CR2_NBYTES (0xFF << I2C_CR2_NBYTES_SHIFT) -#define I2C_CR2_NACK (1U << I2C_CR2_NACK_BIT) -#define I2C_CR2_STOP (1U << I2C_CR2_STOP_BIT) -#define I2C_CR2_START (1U << I2C_CR2_START_BIT) -#define I2C_CR2_HEAD10R (1U << I2C_CR2_HEAD10R_BIT) -#define I2C_CR2_ADD10 (1U << I2C_CR2_ADD10_BIT) -#define I2C_CR2_RD_WRN (1U << I2C_CR2_RD_WRN_BIT) -#define I2C_CR2_SADD_7_BIT (0x7F << I2C_CR2_SADD_7_BIT_SHIFT) -#define I2C_CR2_SADD_10_BIT (0x3FF << I2C_CR2_SADD_10_BIT_SHIFT) - -/* Own address register 1 */ -#define I2C_OAR1_OA1EN_BIT 15 -#define I2C_OAR1_OA1MODE_BIT 10 -#define I2C_OAR1_OA1_7_BIT_SHIFT 1 -#define I2C_OAR1_OA1_10_BIT_SHIFT 0 - -#define I2C_OAR1_OA1EN (1U << I2C_OAR1_OA1EN_BIT) -#define I2C_OAR1_OA1MODE (1U << I2C_OAR1_OA1MODE_BIT) -#define I2C_OAR1_OA1_7_BIT (0x7F << I2C_OAR1_OA1_7_BIT_SHIFT) -#define I2C_OAR1_OA1_10_BIT (0x3FF << I2C_OAR1_OA1_10_BIT_SHIFT) - -/* Own address register 2 */ -#define I2C_OAR2_OA2EN_BIT 15 -#define I2C_OAR2_OA2MSK_SHIFT 8 -#define I2C_OAR2_OA2_7_BIT_SHIFT 1 - -#define I2C_OAR2_OA2EN (1U << I2C_OAR2_OA2EN_BIT) -#define I2C_OAR2_OA2MSK (0x7 << I2C_OAR2_OA2MSK_SHIFT) -#define I2C_OAR2_OA2_7_BIT (0x7F << I2C_OAR2_OA2_7_BIT_SHIFT) - -/* Timing register */ -#define I2C_TIMINGR_PRESC_SHIFT 28 -#define I2C_TIMINGR_SCLDEL_SHIFT 20 -#define I2C_TIMINGR_SDADEL_SHIFT 16 -#define I2C_TIMINGR_SCLH_SHIFT 8 -#define I2C_TIMINGR_SCLL_SHIFT 0 - -#define I2C_TIMINGR_PRESC (0xF << I2C_TIMINGR_PRESC_SHIFT) -#define I2C_TIMINGR_SCLDEL (0xF << I2C_TIMINGR_SCLDEL_SHIFT) -#define I2C_TIMINGR_SCADEL (0xF << I2C_TIMINGR_SCADEL_SHIFT) -#define I2C_TIMINGR_SCLH (0xFF << I2C_TIMINGR_SCLH_SHIFT) -#define I2C_TIMINGR_SCLL (0xFF << I2C_TIMINGR_SCLL_SHIFT) - -/* Timeout register */ -#define I2C_TIMEOUTR_TEXTEN_BIT 31 -#define I2C_TIMEOUTR_TIMEOUTB_SHIFT 16 -#define I2C_TIMEOUTR_TIMOUTEN_BIT 15 -#define I2C_TIMEOUTR_TIDLE_BIT 12 -#define I2C_TIMEOUTR_TIMEOUTA_SHIFT 0 - -#define I2C_TIMEOUTR_TEXTEN (1U << I2C_TIMEOUTR_TEXTEN_BIT) -#define I2C_TIMEOUTR_TIMEOUTB (0xFFF << I2C_TIMEOUTR_TIMEOUTB_SHIFT) -#define I2C_TIMEOUTR_TIMOUTEN (1U << I2C_TIMEOUTR_TIMOUTEN_BIT) -#define I2C_TIMEOUTR_TIDLE (1U << I2C_TIMEOUTR_TIDLE_BIT) -#define I2C_TIMEOUTR_TIMEOUTA (0xFFF << I2C_TIMEOUTR_TIMEOUTA_SHIFT) - -/* Interrupt and status register */ -#define I2C_ISR_ADDCODE_SHIFT 17 -#define I2C_ISR_DIR_BIT 16 -#define I2C_ISR_BUSY_BIT 15 -#define I2C_ISR_ALERT_BIT 13 -#define I2C_ISR_TIMEOUT_BIT 12 -#define I2C_ISR_PECERR_BIT 11 -#define I2C_ISR_OVR_BIT 10 -#define I2C_ISR_ARLO_BIT 9 -#define I2C_ISR_BERR_BIT 8 -#define I2C_ISR_TCR_BIT 7 -#define I2C_ISR_TC_BIT 6 -#define I2C_ISR_STOPF_BIT 5 -#define I2C_ISR_NACKF_BIT 4 -#define I2C_ISR_ADDR_BIT 3 -#define I2C_ISR_RXNE_BIT 2 -#define I2C_ISR_TXIS_BIT 1 -#define I2C_ISR_TXE_BIT 0 - -#define I2C_ISR_ADDCODE (0x7F << I2C_ISR_ADDCODE_SHIFT) -#define I2C_ISR_ALERTCF (1U << I2C_ISR_ALERTCF_BIT) -#define I2C_ISR_DIR (1U << I2C_ISR_DIR_BIT) -#define I2C_ISR_BUSY (1U << I2C_ISR_BUSY_BIT) -#define I2C_ISR_ALERT (1U << I2C_ISR_ALERT_BIT) -#define I2C_ISR_TIMEOUT (1U << I2C_ISR_TIMEOUT_BIT) -#define I2C_ISR_PECERR (1U << I2C_ISR_PECERR_BIT) -#define I2C_ISR_OVR (1U << I2C_ISR_OVR_BIT) -#define I2C_ISR_ARLO (1U << I2C_ISR_ARLO_BIT) -#define I2C_ISR_BERR (1U << I2C_ISR_BERR_BIT) -#define I2C_ISR_TCR (1U << I2C_ISR_TCR_BIT) -#define I2C_ISR_TC (1U << I2C_ISR_TC_BIT) -#define I2C_ISR_STOPF (1U << I2C_ISR_STOPF_BIT) -#define I2C_ISR_NACKF (1U << I2C_ISR_NACKF_BIT) -#define I2C_ISR_ADDR (1U << I2C_ISR_ADDR_BIT) -#define I2C_ISR_RXNE (1U << I2C_ISR_RXNE_BIT) -#define I2C_ISR_TXIS (1U << I2C_ISR_TXIS_BIT) -#define I2C_ISR_TXE (1U << I2C_ISR_TXE_BIT) - -/* Interrupt clear register */ -#define I2C_ICR_ALERTCF_BIT 13 -#define I2C_ICR_TIMOUTCF_BIT 12 -#define I2C_ICR_PECCF_BIT 11 -#define I2C_ICR_OVRCF_BIT 10 -#define I2C_ICR_ARLOCF_BIT 9 -#define I2C_ICR_BERRCF_BIT 8 -#define I2C_ICR_STOPCF_BIT 5 -#define I2C_ICR_NACKCF_BIT 4 -#define I2C_ICR_ADDRCF_BIT 3 - -#define I2C_ICR_ALERTCF (1U << I2C_ICR_ALERTCF_BIT) -#define I2C_ICR_TIMOUTCF (1U << I2C_ICR_TIMOUTCF_BIT) -#define I2C_ICR_PECCF (1U << I2C_ICR_PECERRCF_BIT) -#define I2C_ICR_OVRCF (1U << I2C_ICR_OVRCF_BIT) -#define I2C_ICR_ARLOCF (1U << I2C_ICR_ARLOCF_BIT) -#define I2C_ICR_BERRCF (1U << I2C_ICR_BERRCF_BIT) -#define I2C_ICR_STOPCF (1U << I2C_ICR_STOPCF_BIT) -#define I2C_ICR_NACKCF (1U << I2C_ICR_NACKCF_BIT) -#define I2C_ICR_ADDRCF (1U << I2C_ICR_ADDRCF_BIT) - -/* PEC register */ -#define I2C_PEC_PEC 0xFF - -/* Receive data register */ -#define I2C_RXDR_RXDATA 0xFF - -/* Transmit data register */ -#define I2C_TXDR_TXDATA 0xFF - -/* - * Timing configurations - */ - -/* Timing configuration for I2C clock running at 8MHz */ - -/* NOTE: - * I2C is clocked by HSI (8MHz) by default - * if clock source is changed with RCC_CFGR_I2C1SW/I2C2SW, - * these values have to be adapted - */ -typedef enum i2c_timing { - I2C_TIMING_10_kHz = (0x01 << I2C_TIMINGR_PRESC_SHIFT) - + (0x04 << I2C_TIMINGR_SCLDEL_SHIFT) - + (0x02 << I2C_TIMINGR_SDADEL_SHIFT) - + (0xC3 << I2C_TIMINGR_SCLH_SHIFT) - + (0xC7 << I2C_TIMINGR_SCLL_SHIFT), - - I2C_TIMING_100_kHz = (0x01 << I2C_TIMINGR_PRESC_SHIFT) - + (0x04 << I2C_TIMINGR_SCLDEL_SHIFT) - + (0x02 << I2C_TIMINGR_SDADEL_SHIFT) - + (0x0F << I2C_TIMINGR_SCLH_SHIFT) - + (0x13 << I2C_TIMINGR_SCLL_SHIFT), - - I2C_TIMING_400_kHz = (0x00 << I2C_TIMINGR_PRESC_SHIFT) - + (0x03 << I2C_TIMINGR_SCLDEL_SHIFT) - + (0x01 << I2C_TIMINGR_SDADEL_SHIFT) - + (0x03 << I2C_TIMINGR_SCLH_SHIFT) - + (0x09 << I2C_TIMINGR_SCLL_SHIFT), - - I2C_TIMING_500_kHz = (0x00 << I2C_TIMINGR_PRESC_SHIFT) - + (0x01 << I2C_TIMINGR_SCLDEL_SHIFT) - + (0x01 << I2C_TIMINGR_SDADEL_SHIFT) - + (0x03 << I2C_TIMINGR_SCLH_SHIFT) - + (0x06 << I2C_TIMINGR_SCLL_SHIFT), -} i2c_timing; - -/* - * For internal use - */ - -static inline uint32 _i2c_bus_clk(i2c_dev *dev) { /* FIXME remove, is a remainder of F1 code */ - /* Both I2C peripherals are on APB1 */ - return STM32_PCLK1 / (1000 * 1000); -} - -extern uint8 i2c_read(i2c_dev *dev); - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBMAPLE_STM32F3_I2C_H_ */ diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/nvic.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/nvic.h deleted file mode 100644 index 7643c3251..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/nvic.h +++ /dev/null @@ -1,153 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/nvic.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 Nested Vectored Interrupt Controller (NVIC) support. - */ - -#ifndef _LIBMAPLE_STM32F3_NVIC_H_ -#define _LIBMAPLE_STM32F3_NVIC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include - -/** - * @brief STM32F1 interrupt vector table interrupt numbers. - * @see - */ -typedef enum nvic_irq_num { - NVIC_NMI = -14, /**< Non-maskable interrupt */ - NVIC_HARDFAULT = -13, /**< Hard fault (all class of fault) */ - NVIC_MEM_MANAGE = -12, /**< Memory management */ - NVIC_BUS_FAULT = -11, /**< Bus fault: prefetch fault, memory - access fault. */ - NVIC_USAGE_FAULT = -10, /**< Usage fault: Undefined instruction or - illegal state. */ - NVIC_SVC = -5, /**< System service call via SWI insruction */ - NVIC_DEBUG_MON = -4, /**< Debug monitor */ - NVIC_PEND_SVC = -2, /**< Pendable request for system service */ - NVIC_SYSTICK = -1, /**< System tick timer */ - - NVIC_WWDG = 0, /**< Window watchdog interrupt */ - NVIC_PVD = 1, /**< PVD through EXTI line detection */ - NVIC_TAMP_STAMP = 2, /**< Tamper */ - NVIC_RTC_WKUP = 3, /**< Real-time clock */ - NVIC_FLASH = 4, /**< Flash */ - NVIC_RCC = 5, /**< Reset and clock control */ - NVIC_EXTI0 = 6, /**< EXTI line 0 */ - NVIC_EXTI1 = 7, /**< EXTI line 1 */ - NVIC_EXTI2 = 8, /**< EXTI line 2 */ //FIXME capacitive touch - NVIC_EXTI3 = 9, /**< EXTI line 3 */ - NVIC_EXTI4 = 10, /**< EXTI line 4 */ - NVIC_DMA_CH1 = 11, /**< DMA1 channel 1 */ - NVIC_DMA_CH2 = 12, /**< DMA1 channel 2 */ - NVIC_DMA_CH3 = 13, /**< DMA1 channel 3 */ - NVIC_DMA_CH4 = 14, /**< DMA1 channel 4 */ - NVIC_DMA_CH5 = 15, /**< DMA1 channel 5 */ - NVIC_DMA_CH6 = 16, /**< DMA1 channel 6 */ - NVIC_DMA_CH7 = 17, /**< DMA1 channel 7 */ - NVIC_ADC1_2 = 18, /**< ADC1 and ADC2 */ - NVIC_USB_HP_CAN_TX = 19, /**< USB high priority or CAN TX */ - NVIC_USB_LP_CAN_RX0 = 20, /**< USB low priority or CAN RX0 */ - NVIC_CAN_RX1 = 21, /**< CAN RX1 */ - NVIC_CAN_SCE = 22, /**< CAN SCE */ - NVIC_EXTI_9_5 = 23, /**< EXTI line [9:5] */ - //NVIC_TIMER1_BRK_TIMER15 = 24, // FIXME hack - NVIC_TIMER1_BRK_TIMER9 = 24, /**< Timer 1 break, Timer 9. */ // FIXME rm - //NVIC_TIMER1_UP_TIMER16 = 25, // FIXME hack - NVIC_TIMER1_UP_TIMER10 = 25, /**< Timer 1 update, Timer 10. */ //FIXME rm - //NVIC_TIMER1_TRG_COM_TIMER17 = 26, // FIXME hack - NVIC_TIMER1_TRG_COM_TIMER11 = 26, /**< - * Timer 1 trigger and commutation, - * Timer 11. */ // FIXME rm - NVIC_TIMER1_CC = 27, /**< Timer 1 capture/compare */ - NVIC_TIMER2 = 28, /**< Timer 2 */ - NVIC_TIMER3 = 29, /**< Timer 3 */ - NVIC_TIMER4 = 30, /**< Timer 4 */ - NVIC_I2C1_EV = 31, /**< I2C1 event */ - NVIC_I2C1_ER = 32, /**< I2C1 error */ - NVIC_I2C2_EV = 33, /**< I2C2 event */ - NVIC_I2C2_ER = 34, /**< I2C2 error */ - NVIC_SPI1 = 35, /**< SPI1 */ - NVIC_SPI2 = 36, /**< SPI2 */ - NVIC_USART1 = 37, /**< USART1 */ - NVIC_USART2 = 38, /**< USART2 */ - NVIC_USART3 = 39, /**< USART3 */ - NVIC_EXTI_15_10 = 40, /**< EXTI line [15:10] */ - NVIC_RTC_ALARM = 41, /**< RTC alarm through EXTI line */ - NVIC_USB_WKUP = 42, /**< USB wakeup from suspend through - EXTI line */ - NVIC_TIMER8_BRK_TIMER12 = 43, /**< Timer 8 break, timer 12 */ //TODO rm TIMER12 - NVIC_TIMER8_UP_TIMER13 = 44, /**< Timer 8 update, timer 13 */ // TODO rm TIMER13 - NVIC_TIMER8_TRG_COM_TIMER14 = 45, /**< - * Timer 8 trigger and commutation, - * Timer 14. */ //TODO rm TIMER14 - NVIC_TIMER8_CC = 46, /**< Timer 8 capture/compare */ - NVIC_ADC3 = 47, /**< ADC3 */ - - NVIC_SPI3 = 51, /**< SPI3 */ - NVIC_UART4 = 52, /**< UART4 */ - NVIC_UART5 = 53, /**< UART5 */ - //NVIC_TIMER6_DAC = 54, // TODO hack - NVIC_TIMER6 = 54, /**< Timer 6 */ //TODO add DAC - NVIC_TIMER7 = 55, /**< Timer 7 */ - NVIC_DMA2_CH1 = 56, /**< DMA2 channel 1 */ - NVIC_DMA2_CH2 = 57, /**< DMA2 channel 2 */ - NVIC_DMA2_CH3 = 58, /**< DMA2 channel 3 */ - NVIC_DMA2_CH4 = 59, /**< DMA2 channel 4 */ - NVIC_DMA2_CH5 = 60, /**< DMA2 channel 5 */ - - NVIC_ADC4 = 61, /**< DMA2 channels 4 and 5 */ - - NVIC_COMP123 = 64, /**< DMA2 channels 4 and 5 */ - NVIC_COMP456 = 65, /**< DMA2 channels 4 and 5 */ - NVIC_COMP7 = 66, /**< DMA2 channels 4 and 5 */ - - NVIC_USB_HP = 74, /**< DMA2 channels 4 and 5 */ - NVIC_USB_LP = 75, /**< DMA2 channels 4 and 5 */ - NVIC_USB_WKUP2 = 76, /**< DMA2 channels 4 and 5 */ - - NVIC_FPU = 81, /**< DMA2 channels 4 and 5 */ -} nvic_irq_num; - -static inline void nvic_irq_disable_all(void) { - NVIC_BASE->ICER[0] = 0xFFFFFFFF; - NVIC_BASE->ICER[1] = 0xFFFFFFFF; - NVIC_BASE->ICER[2] = 0xFFFFFFFF; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/opamp.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/opamp.h deleted file mode 100644 index 858f1d86e..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/opamp.h +++ /dev/null @@ -1,123 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/ompamp.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 Operational Amplifier support. - */ - -#ifndef _LIBMAPLE_STM32F3_OPAMP_H_ -#define _LIBMAPLE_STM32F3_OPAMP_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include - -/* - * Register map - */ - -/* - * OpAmp individual register map type. - */ -typedef struct opamp_reg_map { - __io uint32 CSR; /**< */ -} opamp_reg_map; - -/** OpAmp device type. */ -typedef struct opamp_dev { - opamp_reg_map *regs; /**< Register map */ -} opamp_dev; - -/* - * Devices - */ - -extern const struct opamp_dev *OPAMP1; /* OpAmp amplifier 1 */ -extern const struct opamp_dev *OPAMP2; /* OpAmp amplifier 2 */ -extern const struct opamp_dev *OPAMP3; /* OpAmp amplifier 3 */ -extern const struct opamp_dev *OPAMP4; /* OpAmp amplifier 4 */ - -/* - * Register map base pointers - */ - -#define OPAMP1_BASE ((struct opamp_reg_map*)0x40010038) -#define OPAMP2_BASE ((struct opamp_reg_map*)0x4001003C) -#define OPAMP3_BASE ((struct opamp_reg_map*)0x40010040) -#define OPAMP4_BASE ((struct opamp_reg_map*)0x40010044) - -/* - * Register bit definitions - */ - -/* Control and status register */ -#define OPAMP_CSR_LOCK_BIT 31 -#define OPAMP_CSR_OUTCAL_BIT 30 -#define OPAMP_CSR_TSTREF_BIT 29 -#define OPAMP_CSR_TRIMOFFSETN_SHIFT 24 -#define OPAMP_CSR_TRIMOFFSETP_SHIFT 19 -#define OPAMP_CSR_USER_TRIM_BIT 18 -#define OPAMP_CSR_PGA_GAIN_SHIFT 14 -#define OPAMP_CSR_CAL_SEL_SHIFT 12 -#define OPAMP_CSR_CAL_ON_BIT 11 -#define OPAMP_CSR_VPS_SEL_SHIFT 9 -#define OPAMP_CSR_VMS_SEL_BIT 8 -#define OPAMP_CSR_TCM_EN_BIT 7 -#define OPAMP_CSR_VM_SEL_SHIFT 5 -#define OPAMP_CSR_VP_SEL_SHIFT 2 -#define OPAMP_CSR_FORCE_VP_BIT 1 -#define OPAMP_CSR_EN_BIT 0 - -#define OPAMP_CSR_LOCK (1U << OPAMP_CSR_LOCK_BIT) -#define OPAMP_CSR_OUTCAL (1U << OPAMP_CSR_OUTCAL_BIT) -#define OPAMP_CSR_TSTREF (1U << OPAMP_CSR_TSTREF_BIT) -#define COMP_CSR_TRIMOFFSETN (0x1F << COMP_CSR_TRIMOFFSETN_SHIFT) -#define COMP_CSR_TRIMOFFSETP (0x1F << COMP_CSR_TRIMOFFSETP_SHIFT) -#define OPAMP_CSR_USER_TRIM (1U << OPAMP_CSR_USER_TRIM_BIT) -#define COMP_CSR_PGA_GAIN (0xF << COMP_CSR_PGA_GAIN_SHIFT) -#define COMP_CSR_CAL_SEL (0x3 << COMP_CSR_CAL_SEL_SHIFT) -#define OPAMP_CSR_CAL_ON (1U << OPAMP_CSR_CAL_ON_BIT) -#define COMP_CSR_VPS_SEL (0x3 << COMP_CSR_VPS_SEL_SHIFT) -#define OPAMP_CSR_VMS_SEL (1U << OPAMP_CSR_VMS_SEL_BIT) -#define OPAMP_CSR_TCM_EN (1U << OPAMP_CSR_TCM_EN_BIT) -#define COMP_CSR_VM_SEL (0x3 << COMP_CSR_VM_SEL_SHIFT) -#define COMP_CSR_VP_SEL (0x3 << COMP_CSR_VP_SEL_SHIFT) -#define OPAMP_CSR_FORCE_VP (1U << OPAMP_CSR_FORCE_VP_BIT) -#define OPAMP_CSR_EN (1U << OPAMP_CSR_EN_BIT) - -/* TODO - * actually implement me ;-) - */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/pwr.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/pwr.h deleted file mode 100644 index d3564e8c6..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/pwr.h +++ /dev/null @@ -1,52 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f1/include/series/pwr.h - * @author Marti Bolivar - * @brief STM32F3 Power control (PWR) support. - */ - -#ifndef _LIBMAPLE_STM32F3_PWR_H_ -#define _LIBMAPLE_STM32F3_PWR_H_ - -/* - * Register bit definitions - */ - -/* Control register */ - -/* PVD level selection */ -#define PWR_CR_PLS_2_2V (0x0 << 5) -#define PWR_CR_PLS_2_3V (0x1 << 5) -#define PWR_CR_PLS_2_4V (0x2 << 5) -#define PWR_CR_PLS_2_5V (0x3 << 5) -#define PWR_CR_PLS_2_6V (0x4 << 5) -#define PWR_CR_PLS_2_7V (0x5 << 5) -#define PWR_CR_PLS_2_8V (0x6 << 5) -#define PWR_CR_PLS_2_9V (0x7 << 5) - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/simd.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/simd.h deleted file mode 100644 index 8325d5d47..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/simd.h +++ /dev/null @@ -1,109 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file libmaple/include/libmaple/simd.h - * @author F3-port by Hanspeter Portner - * @brief Convenience macros for the digital signal processing (DSP) - * instruction set of the ARM Cortex M4 microcontroller. - */ - -#ifndef _LIBMAPLE_DSP_H_ -#define _LIBMAPLE_DSP_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#define DSP3(ID, A, B, C) \ -({ \ - uint32_t X; \ - asm volatile (ID" %[res], %[val1], %[val2], %[val3]" \ - : [res]"=r" (X) \ - : [val1]"r" (A), [val2]"r" (B), [val3]"r" (C) \ - ); \ - (uint32_t)X; \ -}) - -#define DSP2(ID, A, B) \ -({ \ - uint32_t X; \ - asm volatile (ID" %[res], %[val1], %[val2]" \ - : [res]"=r" (X) \ - : [val1]"r" (A), [val2]"r" (B) \ - );\ - (uint32_t)X; \ -}) - -#define DSP1(ID, A) \ -({ \ - uint32_t X; \ - asm volatile (ID" %[res], %[val1]" \ - : [res]"=r" (X) \ - : [val1]"r" (A) \ - ); \ - (uint32_t)X; \ -}) - -/* General data processing instructions */ -#define __rev16(A) DSP1("REV16", A) - -/* SIMD instructions (single instruction multiple data) */ -#define __sadd16(A, B) DSP2("SADD16", A, B) -#define __shadd16(A, B) DSP2("SHADD16", A, B) -#define __ssub16(A, B) DSP2("SSUB16", A, B) -#define __shsub16(A, B) DSP2("SHSUB16", A, B) -#define __uadd16(A, B) DSP2("UADD16", A, B) -#define __uhadd16(A, B) DSP2("UHADD16", A, B) -#define __usub16(A, B) DSP2("USUB16", A, B) -#define __uhsub16(A, B) DSP2("UHSUB16", A, B) - -#define __sadd8(A, B) DSP2("SADD8", A, B) -#define __shadd8(A, B) DSP2("SHADD8", A, B) -#define __ssub8(A, B) DSP2("SSUB8", A, B) -#define __shsub8(A, B) DSP2("SHSUB8", A, B) -#define __uadd8(A, B) DSP2("UADD8", A, B) -#define __uhadd8(A, B) DSP2("UHADD8", A, B) -#define __usub8(A, B) DSP2("USUB8", A, B) -#define __uhsub8(A, B) DSP2("UHSUB8", A, B) - -#define __sasx(A, B) DSP2("SASX", A, B) -#define __ssax(A, B) DSP2("SSAX", A, B) -#define __shasx(A, B) DSP2("SHASX", A, B) -#define __shsax(A, B) DSP2("SHSAX", A, B) -#define __uasx(A, B) DSP2("UASX", A, B) -#define __usax(A, B) DSP2("USAX", A, B) -#define __uhasx(A, B) DSP2("UHASX", A, B) -#define __uhsax(A, B) DSP2("UHSAX", A, B) - -#define __usad8(A, B) DSP2("USAD8", A, B) -#define __usada8(A, B, C) DSP3("USADA8", A, B, C) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/spi.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/spi.h deleted file mode 100644 index 5b1de093c..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/spi.h +++ /dev/null @@ -1,178 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/spi.h - * @author Marti Bolivar , - * F3-port by Hanspeter Portner - * @brief STM32F3 SPI/I2S series header. - */ - -#ifndef _LIBMAPLE_STM32F3_SPI_H_ -#define _LIBMAPLE_STM32F3_SPI_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Register map base pointers - */ - -struct spi_reg_map; - -#define SPI1_BASE ((struct spi_reg_map*)0x40013000) -#define SPI2_BASE ((struct spi_reg_map*)0x40003800) -#define SPI3_BASE ((struct spi_reg_map*)0x40003C00) - -/* - * F3 additional registry items - */ - -/* Control register 1 */ -/* CRC length bitfield in F3 overwrites the data length field in F1/F2 */ -#define SPI_CR1_CRCL_BIT 11 - -#define SPI_CR1_CRCL (1U << SPI_CR1_CRCL_BIT) - -/* Control register 2 */ -#define SPI_CR2_LDMA_TX_BIT 14 -#define SPI_CR2_LDMA_RX_BIT 13 -#define SPI_CR2_FRXTH_BIT 12 -#define SPI_CR2_DS_SHIFT 8 -#define SPI_CR2_FRF_BIT 4 -#define SPI_CR2_NSSP_BIT 3 - -#define SPI_CR2_LDMA_TX (1U << SPI_CR2_LDMA_TX_BIT) -#define SPI_CR2_LDMA_RX (1U << SPI_CR2_LDMA_RX_BIT) -#define SPI_CR2_FRXTH (1U << SPI_CR2_FRXTH_BIT) -#define SPI_CR2_DS (0x7 << SPI_CR2_DS_SHIFT) -#define SPI_CR2_FRF (1U << SPI_CR2_FRF_BIT) -#define SPI_CR2_NSSP (1U << SPI_CR2_NSSP_BIT) - -/* Status register */ -#define SPI_SR_FTLVL_SHIFT 11 -#define SPI_SR_FRLVL_SHIFT 9 -#define SPI_SR_FRE_BIT 8 - -#define SPI_SR_FTLVL (0x3 << SPI_SR_FTLVL_SHIFT) -#define SPI_SR_FRLVL (0x3 << SPI_SR_FRLVL_SHIFT) -#define SPI_SR_FRE (1U << SPI_SR_FRE_SHIFT) - -/** - * @brief TODO document me - */ -typedef enum spi_crc_size { - SPI_CRC_SIZE_8_BIT = (0x0 << SPI_CR1_CRCL_BIT), - SPI_CRC_SIZE_16_BIT = (0x1 << SPI_CR1_CRCL_BIT), -} spi_crc_size; - -/** - * @brief TODO document me - */ -typedef enum spi_frame_format { - SPI_FRAME_FORMAT_MOTOROLA = (0x0 << SPI_CR2_FRF_BIT), - SPI_FRAME_FORMAT_TI = (0x1 << SPI_CR2_FRF_BIT), -} spi_frame_format; - -/** - * @brief TODO document me - */ -typedef enum spi_ds { - SPI_DATA_SIZE_DEFAULT = (0x0 << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_4_BIT = (0x3 << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_5_BIT = (0x4 << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_6_BIT = (0x5 << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_7_BIT = (0x6 << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_8_BIT = (0x7 << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_9_BIT = (0x8 << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_10_BIT = (0x9 << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_11_BIT = (0xA << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_12_BIT = (0xB << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_13_BIT = (0xC << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_14_BIT = (0xD << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_15_BIT = (0xE << SPI_CR2_DS_SHIFT), - SPI_DATA_SIZE_16_BIT = (0xF << SPI_CR2_DS_SHIFT), -} spi_ds; - -/** - * @brief TODO document me - */ -typedef enum spi_fifo_transmission_level { - SPI_FIFO_TRANSMISSION_LEVEL_EMPTY = (0x0 << SPI_SR_FTLVL_SHIFT), - SPI_FIFO_TRANSMISSION_LEVEL_QUARTER = (0x1 << SPI_SR_FTLVL_SHIFT), - SPI_FIFO_TRANSMISSION_LEVEL_HALF = (0x2 << SPI_SR_FTLVL_SHIFT), - SPI_FIFO_TRANSMISSION_LEVEL_FULL = (0x3 << SPI_SR_FTLVL_SHIFT), -} spi_fifo_transmission_level; - -/** - * @brief TODO document me - */ -typedef enum spi_fifo_reception_level { - SPI_FIFO_RECEPTION_LEVEL_EMPTY = (0x0 << SPI_SR_FRLVL_SHIFT), - SPI_FIFO_RECEPTION_LEVEL_QUARTER = (0x1 << SPI_SR_FRLVL_SHIFT), - SPI_FIFO_RECEPTION_LEVEL_HALF = (0x2 << SPI_SR_FRLVL_SHIFT), - SPI_FIFO_RECEPTION_LEVEL_FULL = (0x3 << SPI_SR_FRLVL_SHIFT), -} spi_fifo_reception_level; - -/* - * Device pointers - */ - -struct spi_dev; - -extern struct spi_dev *SPI1; -extern struct spi_dev *SPI2; -extern struct spi_dev *SPI3; - -/* - * Routines - */ - -struct gpio_dev; -extern void spi_config_gpios(struct spi_dev*, uint8, - struct gpio_dev*, uint8, - struct gpio_dev*, uint8, uint8, uint8); - -/** - * @brief Set the data size of the given SPI device. - * - * @param dev SPI device - * @param ds SPI data size - * @see spi_ds - * @see spi_reconfigure() - */ -extern void spi_data_size(struct spi_dev *, spi_ds); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/stm32.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/stm32.h deleted file mode 100644 index c40627c10..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/stm32.h +++ /dev/null @@ -1,238 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010, 2011 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f1/include/series/stm32.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 chip- and series-specific definitions. - */ - -#ifndef _LIBMAPLE_STM32F3_H_ -#define _LIBMAPLE_STM32F3_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define __CCM__ __attribute__((section(".CCM"))) - -#define STM32_MCU_SERIES STM32_SERIES_F3 - -/* The STM32F3 series is subdivided into "lines". libmaple currently - * officially supports STM32F303 performance line MCUs (see the - * MCU-specific value section below). - * - * You can use these F3 line defines if porting libmaple to support - * MCUs on other lines. */ -/** STM32F3 302 line (STM32F302 MCUs). */ -#define STM32_F3_LINE_302 0 -/** STM32F3 303 line (STM32F303 MCUs). */ -#define STM32_F3_LINE_303 1 - -/* - * MCU-specific values. - * - * You can use this section to override any of the below settings on a - * per-MCU basis. For example, if your MCU has different STM32_PCLK1 - * or STM32_PCLK2 values, you can set them here and the values for - * STM32F303 microcontrollers set below won't take effect. - */ - -#if defined(MCU_STM32F302CB) -# define STM32_F3_LINE STM32_F3_LINE_302 -# define STM32_NR_GPIO_PORTS 20 -# define STM32_SRAM_END ((void*)0x20008000) -# define STM32_MEDIUM_DENSITY // 48pin package - -#elif defined(MCU_STM32F302RB) -# define STM32_F3_LINE STM32_F3_LINE_302 -# define STM32_NR_GPIO_PORTS 27 -# define STM32_SRAM_END ((void*)0x20008000) -# define STM32_HIGH_DENSITY // 64pin package - -#elif defined(MCU_STM32F302VB) -# define STM32_F3_LINE STM32_F3_LINE_302 -# define STM32_NR_GPIO_PORTS 45 -# define STM32_SRAM_END ((void*)0x20008000) -# define STM32_XL_DENSITY // 100pin package - -#elif defined(MCU_STM32F302CC) -# define STM32_F3_LINE STM32_F3_LINE_302 -# define STM32_NR_GPIO_PORTS 20 -# define STM32_SRAM_END ((void*)0x2000A000) -# define STM32_MEDIUM_DENSITY // 48pin package - -#elif defined(MCU_STM32F302RC) -# define STM32_F3_LINE STM32_F3_LINE_302 -# define STM32_NR_GPIO_PORTS 27 -# define STM32_SRAM_END ((void*)0x2000A000) -# define STM32_HIGH_DENSITY // 64pin package - -#elif defined(MCU_STM32F302VC) -# define STM32_F3_LINE STM32_F3_LINE_302 -# define STM32_NR_GPIO_PORTS 45 -# define STM32_SRAM_END ((void*)0x2000A000) -# define STM32_XL_DENSITY // 100pin package - -#elif defined(MCU_STM32F303CB) -# define STM32_F3_LINE STM32_F3_LINE_303 -# define STM32_NR_GPIO_PORTS 20 -# define STM32_SRAM_END ((void*)0x2000A000) -# define STM32_MEDIUM_DENSITY // 48pin package - -#elif defined(MCU_STM32F303RB) -# define STM32_F3_LINE STM32_F3_LINE_303 -# define STM32_NR_GPIO_PORTS 27 -# define STM32_SRAM_END ((void*)0x2000A000) -# define STM32_HIGH_DENSITY // 64pin package - -#elif defined(MCU_STM32F303VB) -# define STM32_F3_LINE STM32_F3_LINE_303 -# define STM32_NR_GPIO_PORTS 45 -# define STM32_SRAM_END ((void*)0x2000A000) -# define STM32_XL_DENSITY // 100pin package - -#elif defined(MCU_STM32F303CC) -# define STM32_F3_LINE STM32_F3_LINE_303 -# define STM32_NR_GPIO_PORTS 20 -# define STM32_SRAM_END ((void*)0x2000C000) -# define STM32_MEDIUM_DENSITY // 48pin package - -#elif defined(MCU_STM32F303RC) -# define STM32_F3_LINE STM32_F3_LINE_303 -# define STM32_NR_GPIO_PORTS 27 -# define STM32_SRAM_END ((void*)0x2000C000) -# define STM32_HIGH_DENSITY // 64pin package - -#elif defined(MCU_STM32F303VC) -# define STM32_F3_LINE STM32_F3_LINE_303 -# define STM32_NR_GPIO_PORTS 45 -# define STM32_SRAM_END ((void*)0x2000C000) -// # define STM32_XL_DENSITY // 100pin package - -#else -#warning "Unsupported or unspecified STM32F3 MCU." -#endif - -/* - * Derived values. - */ - -#if STM32_F3_LINE == STM32_F3_LINE_302 -# define STM32_HAVE_USB 1 - -# ifdef STM32_MEDIUM_DENSITY -# define STM32_NR_INTERRUPTS 82 -# define STM32_TIMER_MASK 0b111000000001011110 -# define STM32_HAVE_FSMC 0 -# define STM32_HAVE_DAC 1 -# elif defined(STM32_HIGH_DENSITY) -# define STM32_NR_INTERRUPTS 82 -# define STM32_TIMER_MASK 0b111000000001011110 -# define STM32_HAVE_FSMC 0 -# define STM32_HAVE_DAC 1 -# elif defined(STM32_XL_DENSITY) -# define STM32_NR_INTERRUPTS 82 -# define STM32_TIMER_MASK 0b111000000001011110 -# define STM32_HAVE_FSMC 0 -# define STM32_HAVE_DAC 1 -# endif - -#elif STM32_F3_LINE == STM32_F3_LINE_303 -# define STM32_HAVE_USB 1 - -# ifdef STM32_MEDIUM_DENSITY -# define STM32_NR_INTERRUPTS 82 -# define STM32_TIMER_MASK 0b111000000111011110 -# define STM32_HAVE_FSMC 0 -# define STM32_HAVE_DAC 1 -# elif defined(STM32_HIGH_DENSITY) -# define STM32_NR_INTERRUPTS 82 -# define STM32_TIMER_MASK 0b111000000111011110 -# define STM32_HAVE_FSMC 0 -# define STM32_HAVE_DAC 1 -# elif defined(STM32_XL_DENSITY) -# define STM32_NR_INTERRUPTS 82 -# define STM32_TIMER_MASK 0b111000000111011110 -# define STM32_HAVE_FSMC 0 -# define STM32_HAVE_DAC 1 -# endif - -#endif - -/* - * Clock configuration. - * - * You can patch these for your line, MCU, clock configuration, - * etc. here or by setting cflags when compiling libmaple. - */ - -#ifndef STM32_PCLK1 -#define STM32_PCLK1 36000000U -#endif - -#ifndef STM32_PCLK2 -#define STM32_PCLK2 72000000U -#endif - -#ifndef STM32_DELAY_US_MULT -#define STM32_DELAY_US_MULT 12 /* FIXME: value is incorrect. */ -#endif - -/* - * Sanity checks. - * - * Make sure we have the F3-specific defines we need. - * will check that we've defined everything it needs. - */ - -#if !defined(STM32_F3_LINE) -#error "Bad STM32F3 configuration. Check STM32F3 header." -#endif - -/* - * Doxygen - */ - -#ifdef __DOXYGEN__ - -/** - * @brief STM32 line value for the STM32F3 MCU being targeted. - * - * At time of writing, allowed values are: STM32_F3_LINE_303, - * STM32_F3_LINE_302. This set of values may expand as libmaple adds - * support for more STM32F3 lines. - */ -#define STM32_F3_LINE - -#endif /* __DOXYGEN__ */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/syscfg.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/syscfg.h deleted file mode 100644 index 3519e78fc..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/syscfg.h +++ /dev/null @@ -1,138 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/syscfg.h - * @author F3-port by Hanspeter Portner - * @brief System configuration controller (SYSCFG) - */ - -#ifndef _LIBMAPLE_STM32F3_SYSCFG_H_ -#define _LIBMAPLE_STM32F3_SYSCFG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* - * Register map and base pointer - */ - -/** - * @brief SYSCFG register map type. - */ -typedef struct syscfg_reg_map { - __io uint32 CFGR1; /**< Configuration register 1*/ - __io uint32 RCR; /**< CCM SRAM protection register */ - __io uint32 EXTICR[4]; /**< External Interrupt configuration register */ - __io uint32 CFGR2; /**< Configuration register 2 */ -} syscfg_reg_map; - -/** SYSCFG register map base pointer */ -#define SYSCFG_BASE ((struct syscfg_reg_map*)0x40010000) - -/* - * Register bit definitions - */ - -/* Configuration register 1 */ - -#define SYSCFG_CFGR1_FPU_IE_SHIFT 26 -#define SYSCFG_CFGR1_ENCODE_MODE_SHIFT 22 -#define SYSCFG_CFGR1_I2C2_FM_PLUS_BIT 21 -#define SYSCFG_CFGR1_I2C1_FM_PLUS_BIT 20 -#define SYSCFG_CFGR1_I2C_PB9_FM_PLUS_BIT 19 -#define SYSCFG_CFGR1_I2C_PB8_FM_PLUS_BIT 18 -#define SYSCFG_CFGR1_I2C_PB7_FM_PLUS_BIT 17 -#define SYSCFG_CFGR1_I2C_PB6_FM_PLUS_BIT 16 -#define SYSCFG_CFGR1_TIM7_DAC2_DMA_RMP_BIT 14 -#define SYSCFG_CFGR1_TIM6_DAC1_DMA_RMP_BIT 13 -#define SYSCFG_CFGR1_TIM17_DMA_RMP_BIT 12 -#define SYSCFG_CFGR1_TIM16_DMA_RMP_BIT 11 -#define SYSCFG_CFGR1_ADC24_DMA_RMP_BIT 8 -#define SYSCFG_CFGR1_DAC_TRIG_RMP_BIT 7 -#define SYSCFG_CFGR1_TIM1_ITR3_RMP_BIT 6 -#define SYSCFG_CFGR1_USB_IT_RMP_BIT 5 - -//FIXME FPU_IE -//FIXME ENCODE_MODE -#define SYSCFG_CFGR1_I2C2_FM_PLUS (1U << SYSCFG_CFGR1_I2C2_FM_PLUS_BIT) -#define SYSCFG_CFGR1_I2C1_FM_PLUS (1U << SYSCFG_CFGR1_I2C1_FM_PLUS_BIT) -#define SYSCFG_CFGR1_I2C1_PB9_FM_PLUS (1U << SYSCFG_CFGR1_I2C1_PB9_FM_PLUS_BIT) -#define SYSCFG_CFGR1_I2C1_PB8_FM_PLUS (1U << SYSCFG_CFGR1_I2C1_PB8_FM_PLUS_BIT) -#define SYSCFG_CFGR1_I2C1_PB7_FM_PLUS (1U << SYSCFG_CFGR1_I2C1_PB7_FM_PLUS_BIT) -#define SYSCFG_CFGR1_I2C1_PB6_FM_PLUS (1U << SYSCFG_CFGR1_I2C1_PB6_FM_PLUS_BIT) -#define SYSCFG_CFGR1_TIM7_DAC2_DMA_RMP (1U << SYSCFG_CFGR1_TIM7_DAC2_DMA_RMP_BIT) -#define SYSCFG_CFGR1_TIM6_DAC1_DMA_RMP (1U << SYSCFG_CFGR1_TIM6_DAC1_DMA_RMP_BIT) -#define SYSCFG_CFGR1_TIM17_DMA_RMP (1U << SYSCFG_CFGR1_TIM17_DMA_RMP_BIT) -#define SYSCFG_CFGR1_TIM16_DMA_RMP (1U << SYSCFG_CFGR1_TIM16_DMA_RMP_BIT) -#define SYSCFG_CFGR1_ADC23_DMA_RMP (1U << SYSCFG_CFGR1_ADC23_DMA_RMP_BIT) -#define SYSCFG_CFGR1_DAC_TRIG_RMP (1U << SYSCFG_CFGR1_DAC_TRIG_RMP_BIT) -#define SYSCFG_CFGR1_TIM1_ITR3_RMP (1U << SYSCFG_CFGR1_TIM1_ITR3_RMP_BIT) -#define SYSCFG_CFGR1_USB_IT_RMP (1U << SYSCFG_CFGR1_USB_IT_RMP_BIT) -#define SYSCFG_CFGR1_MEM_MODE 0X3 - -/* CCM SRAM protection register */ - -#define SYSCFG_RCR_PAGE7_WP_BIT 7 -#define SYSCFG_RCR_PAGE6_WP_BIT 6 -#define SYSCFG_RCR_PAGE5_WP_BIT 5 -#define SYSCFG_RCR_PAGE4_WP_BIT 4 -#define SYSCFG_RCR_PAGE3_WP_BIT 3 -#define SYSCFG_RCR_PAGE2_WP_BIT 2 -#define SYSCFG_RCR_PAGE1_WP_BIT 1 -#define SYSCFG_RCR_PAGE0_WP_BIT 0 - -#define SYSCFG_RCR_PAGE_7 (1U << SYSCFG_RCR_PAGE7_WP_BIT) -#define SYSCFG_RCR_PAGE_6 (1U << SYSCFG_RCR_PAGE6_WP_BIT) -#define SYSCFG_RCR_PAGE_5 (1U << SYSCFG_RCR_PAGE5_WP_BIT) -#define SYSCFG_RCR_PAGE_4 (1U << SYSCFG_RCR_PAGE4_WP_BIT) -#define SYSCFG_RCR_PAGE_3 (1U << SYSCFG_RCR_PAGE3_WP_BIT) -#define SYSCFG_RCR_PAGE_2 (1U << SYSCFG_RCR_PAGE2_WP_BIT) -#define SYSCFG_RCR_PAGE_1 (1U << SYSCFG_RCR_PAGE1_WP_BIT) -#define SYSCFG_RCR_PAGE_0 (1U << SYSCFG_RCR_PAGE0_WP_BIT) - -/* Configuration register 2 */ - -#define SYSCFG_CFGR2_SRAM_PEF_BIT 8 -#define SYSCFG_CFGR2_BYP_ADDR_PAR_BIT 4 -#define SYSCFG_CFGR2_PVD_LOCK_BIT 2 -#define SYSCFG_CFGR2_SRAM_PARITY_LOCK_BIT 1 -#define SYSCFG_CFGR2_LOCKUP_LOCK_BIT 0 - -#define SYSCFG_CFGR2_SRAM_PEF (1U << SYSCFG_CFGR2_SRAM_PEF_BIT) -#define SYSCFG_CFGR2_BYP_ADDR_PAR (1U << SYSCFG_CFGR2_BYP_ADDR_PAR_BIT) -#define SYSCFG_CFGR2_PVD_LOCK (1U << SYSCFG_CFGR2_PVD_LOCK_BIT) -#define SYSCFG_CFGR2_SRAM_PARITY_LOCK (1U << SYSCFG_CFGR2_SRAM_PARITY_LOCK_BIT) -#define SYSCFG_CFGR2_LOCKUP_LOCK (1U << SYSCFG_CFGR2_LOCKUP_LOCK_BIT) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/timer.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/timer.h deleted file mode 100644 index fe13e4cb4..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/timer.h +++ /dev/null @@ -1,123 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/timer.h - * @author Marti Bolivar , - * F3-port by Hanspeter Portner - * @brief STM32F3 timer support. - */ - -#ifndef _LIBMAPLE_STM32F3_TIMER_H_ -#define _LIBMAPLE_STM32F3_TIMER_H_ - -#include -#include - -/* - * Register maps and base pointers - */ - -/** STM32F1 general purpose timer register map type */ -typedef struct timer_gen_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SMCR; /**< Slave mode control register */ - __io uint32 DIER; /**< DMA/Interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - __io uint32 CCMR1; /**< Capture/compare mode register 1 */ - __io uint32 CCMR2; /**< Capture/compare mode register 2 */ - __io uint32 CCER; /**< Capture/compare enable register */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ - const uint32 RESERVED1; /**< Reserved */ - __io uint32 CCR1; /**< Capture/compare register 1 */ - __io uint32 CCR2; /**< Capture/compare register 2 */ - __io uint32 CCR3; /**< Capture/compare register 3 */ - __io uint32 CCR4; /**< Capture/compare register 4 */ - const uint32 RESERVED2; /**< Reserved */ - __io uint32 DCR; /**< DMA control register */ - __io uint32 DMAR; /**< DMA address for full transfer */ -} timer_gen_reg_map; - -struct timer_adv_reg_map; -struct timer_bas_reg_map; - -/** Timer 1 register map base pointer */ -#define TIMER1_BASE ((struct timer_adv_reg_map*)0x40012C00) -/** Timer 2 register map base pointer */ -#define TIMER2_BASE ((struct timer_gen_reg_map*)0x40000000) -/** Timer 3 register map base pointer */ -#define TIMER3_BASE ((struct timer_gen_reg_map*)0x40000400) -/** Timer 4 register map base pointer */ -#define TIMER4_BASE ((struct timer_gen_reg_map*)0x40000800) - -/** Timer 6 register map base pointer */ -#define TIMER6_BASE ((struct timer_bas_reg_map*)0x40001000) -/** Timer 7 register map base pointer */ -#define TIMER7_BASE ((struct timer_bas_reg_map*)0x40001400) -/** Timer 8 register map base pointer */ -#define TIMER8_BASE ((struct timer_adv_reg_map*)0x40013400) - -/** Timer 15 register map base pointer */ -#define TIMER15_BASE ((struct timer_gen_reg_map*)0x40014000) -/** Timer 16 register map base pointer */ -#define TIMER16_BASE ((struct timer_gen_reg_map*)0x40014400) -/** Timer 17 register map base pointer */ -#define TIMER17_BASE ((struct timer_gen_reg_map*)0x40014800) - -/* - * Device pointers - * - * We only declare device pointers to timers which actually exist on - * the target MCU. - */ - -struct timer_dev; - -extern struct timer_dev *TIMER1; -extern struct timer_dev *TIMER2; /* FIXME 32bit-capable counter */ -extern struct timer_dev *TIMER3; -extern struct timer_dev *TIMER4; -extern struct timer_dev *TIMER6; -#if STM32_F3_LINE == STM32_F3_LINE_303 -extern struct timer_dev *TIMER7; -extern struct timer_dev *TIMER8; -#endif -extern struct timer_dev *TIMER15; -extern struct timer_dev *TIMER16; -extern struct timer_dev *TIMER17; - -/* - * Routines - */ - -gpio_af timer_get_af(struct timer_dev *dev); - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/usart.h b/STM32F3/cores/maple/libmaple/stm32f3/include/series/usart.h deleted file mode 100644 index d7edcb6b4..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/usart.h +++ /dev/null @@ -1,277 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/stm32f3/include/series/usart.h - * @author F3-port by Hanspeter Portner - * @brief STM32F3 USART support. - */ - -#ifndef _LIBMAPLE_STM32F3_USART_H_ -#define _LIBMAPLE_STM32F3_USART_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include /* for gpio_af */ - -/* - * Register maps - */ - -/** USART register map type */ -typedef struct usart_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 CR3; /**< Control register 3 */ - __io uint32 BRR; /**< Baud rate register */ - __io uint32 GTPR; /**< Guard time and prescaler register */ - __io uint32 RTOR; /**< Receiver timeout register */ - __io uint32 RQR; /**< Request register */ - __io uint32 SR; /**< ISR Interrupt and status register */ - __io uint32 ICR; /**< Interrupt clear register */ - __io uint16 RDR; /**< Receive data register */ - uint16 RESERVED1; - __io uint16 TDR; /**< Transmit data register */ - uint16 RESERVED2; -} usart_reg_map; - -/* - * Register map base pointers - */ - -/** USART1 register map base pointer */ -#define USART1_BASE ((struct usart_reg_map*)0x40013800) -/** USART2 register map base pointer */ -#define USART2_BASE ((struct usart_reg_map*)0x40004400) -/** USART3 register map base pointer */ -#define USART3_BASE ((struct usart_reg_map*)0x40004800) - -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) -/** UART4 register map base pointer */ -#define UART4_BASE ((struct usart_reg_map*)0x40004C00) -/** UART5 register map base pointer */ -#define UART5_BASE ((struct usart_reg_map*)0x40005000) -#endif - -/* - * Devices - */ - -struct usart_dev; -extern struct usart_dev *USART1; -extern struct usart_dev *USART2; -extern struct usart_dev *USART3; -#ifdef STM32_HIGH_DENSITY -extern struct usart_dev *UART4; -extern struct usart_dev *UART5; -#endif - -/* - * F3-only register bit definitions. - */ - -/* Control register 1 */ -#define USART_CR1_EOBIE_BIT 27 -#define USART_CR1_RTOIE_BIT 26 -#define USART_CR1_DEAT4_BIT 25 -#define USART_CR1_DEAT3_BIT 24 -#define USART_CR1_DEAT2_BIT 23 -#define USART_CR1_DEAT1_BIT 22 -#define USART_CR1_DEAT0_BIT 21 -#define USART_CR1_DEDT4_BIT 20 -#define USART_CR1_DEDT3_BIT 19 -#define USART_CR1_DEDT2_BIT 18 -#define USART_CR1_DEDT1_BIT 17 -#define USART_CR1_DEDT0_BIT 16 -#define USART_CR1_OVER8_BIT 15 -#define USART_CR1_CMIE_BIT 14 -#define USART_CR1_MME_BIT 13 -#define USART_CR1_UESM_BIT 1 -#define USART_CR1_UE_BIT 0 - -#define USART_CR1_EOBIE (1UL << USART_CR1_EOBIE_BIT) -#define USART_CR1_RTOIE (1UL << USART_CR1_RTOIE_BIT) -#define USART_CR1_DEAT4 (1UL << USART_CR1_DEAT4_BIT) -#define USART_CR1_DEAT3 (1UL << USART_CR1_DEAT3_BIT) -#define USART_CR1_DEAT2 (1UL << USART_CR1_DEAT2_BIT) -#define USART_CR1_DEAT1 (1UL << USART_CR1_DEAT1_BIT) -#define USART_CR1_DEAT0 (1UL << USART_CR1_DEAT0_BIT) -#define USART_CR1_DEDT4 (1UL << USART_CR1_DEDT4_BIT) -#define USART_CR1_DEDT3 (1UL << USART_CR1_DEDT3_BIT) -#define USART_CR1_DEDT2 (1UL << USART_CR1_DEDT2_BIT) -#define USART_CR1_DEDT1 (1UL << USART_CR1_DEDT1_BIT) -#define USART_CR1_DEDT0 (1UL << USART_CR1_DEDT0_BIT) -#define USART_CR1_OVER8 (1UL << USART_CR1_OVER8_BIT) -#define USART_CR1_CMIE (1UL << USART_CR1_CMIE_BIT) -#define USART_CR1_MME (1UL << USART_CR1_MME_BIT) -#define USART_CR1_UESM (1UL << USART_CR1_UESM_BIT) -#define USART_CR1_UE (1UL << USART_CR1_UE_BIT) - -/* Control register 2 */ -#define USART_CR2_ADD_SHIFT 24 -#define USART_CR2_RTOEN_BIT 23 -#define USART_CR2_ABRMOD1_BIT 22 -#define USART_CR2_ABRMOD0_BIT 21 -#define USART_CR2_ABREN_BIT 20 -#define USART_CR2_MSBFIRST_BIT 19 -#define USART_CR2_DATAINV_BIT 18 -#define USART_CR2_TXINV_BIT 17 -#define USART_CR2_RXINV_BIT 16 -#define USART_CR2_SWAP_BIT 15 -#define USART_CR2_ADDM7_BIT 4 - -#define USART_CR2_ADD (0xFF << USART_CR2_ADD_SHIFT) -#define USART_CR2_RTOEN (1UL << USART_CR2_RTOEN_BIT) -#define USART_CR2_ABRMOD1 (1UL << USART_CR2_ABRMOD1_BIT) -#define USART_CR2_ABRMOD0 (1UL << USART_CR2_ABRMOD0_BIT) -#define USART_CR2_ABREN (1UL << USART_CR2_ABREN_BIT) -#define USART_CR2_MSBFIRST (1UL << USART_CR2_MSBFIRST_BIT) -#define USART_CR2_DATAINV (1UL << USART_CR2_DATAINV_BIT) -#define USART_CR2_TXINV (1UL << USART_CR2_TXINV_BIT) -#define USART_CR2_RXINV (1UL << USART_CR2_RXINV_BIT) -#define USART_CR2_SWAP (1UL << USART_CR2_SWAP_BIT) -#define USART_CR2_ADDM7 (1UL << USART_CR2_ADDM7_BIT) - -/* Control register 3 */ -#define USART_CR3_WUFIE_BIT 22 -#define USART_CR3_WUS_SHIFT 20 -#define USART_CR3_SCAR_SHIFT 17 -#define USART_CR3_DEP_BIT 15 -#define USART_CR3_DEM_BIT 14 -#define USART_CR3_DDRE_BIT 13 -#define USART_CR3_OVRDIS_BIT 12 -#define USART_CR3_ONEBIT_BIT 11 - -#define USART_CR3_WUFIE (1UL << USART_CR3_WUFIE_BIT) -#define USART_CR3_WUS (0x3 << USART_CR3_WUS_SHIFT) -#define USART_CR3_SCAR (0x7 << USART_CR3_SCAR_SHIFT) -#define USART_CR3_DEP (1UL << USART_CR3_DEP_BIT) -#define USART_CR3_DEM (1UL << USART_CR3_DEM_BIT) -#define USART_CR3_DDRE (1UL << USART_CR3_DDRE_BIT) -#define USART_CR3_OVRDIS (1UL << USART_CR3_OVRDIS_BIT) -#define USART_CR3_ONEBIT (1UL << USART_CR3_ONEBIT_BIT) - -/* Receive timeout register */ -#define USART_RTOR_BLEN_SHIFT 24 -#define USART_RTOR_RTO_SHIFT 0 - -#define USART_RTOR_BLEN (0xF << USART_RTOR_BLEN_SHIFT) -#define USART_RTOR_RTO (0xFFF << USART_RTOR_RTO_SHIFT) - -/* Request register */ -#define USART_RQR_TXFRQ_BIT 4 -#define USART_RQR_RXFRQ_BIT 3 -#define USART_RQR_MMRQ_BIT 2 -#define USART_RQR_SBKRQ_BIT 1 -#define USART_RQR_ABRRQ_BIT 0 - -#define USART_RQR_TXFRQ (1UL << USART_RQR_TXFRQ_BIT) -#define USART_RQR_RXFRQ (1UL << USART_RQR_RXFRQ_BIT) -#define USART_RQR_MMRQ (1UL << USART_RQR_MMRQ_BIT) -#define USART_RQR_SBKRQ (1UL << USART_RQR_SBKRQ_BIT) -#define USART_RQR_ABRRQ (1UL << USART_RQR_ABRRQ_BIT) - -/* Interrupt and status register */ -// common register bits with other STM32 series are defined as USART_SR_* for compatibility -#define USART_SR_REACK_BIT 22 -#define USART_SR_TEACK_BIT 21 -#define USART_SR_WUF_BIT 20 -#define USART_SR_RWU_BIT 19 -#define USART_SR_SBKF_BIT 18 -#define USART_SR_CMF_BIT 17 -#define USART_SR_BUSY_BIT 16 -#define USART_SR_ABRF_BIT 15 -#define USART_SR_ABRE_BIT 14 -#define USART_SR_EOBF_BIT 12 -#define USART_SR_RTOF_BIT 11 -#define USART_SR_CTS_BIT 10 -#define USART_SR_CTSIF_BIT 9 - -#define USART_SR_REACK (1UL << USART_ISR_REACK_BIT) -#define USART_SR_TEACK (1UL << USART_ISR_TEACK_BIT) -#define USART_SR_WUF (1UL << USART_ISR_WUF_BIT) -#define USART_SR_RWU (1UL << USART_ISR_RWU_BIT) -#define USART_SR_SBKF (1UL << USART_ISR_SBKF_BIT) -#define USART_SR_CMF (1UL << USART_ISR_CMF_BIT) -#define USART_SR_BUSY (1UL << USART_ISR_BUSY_BIT) -#define USART_SR_ABRF (1UL << USART_ISR_ABRF_BIT) -#define USART_SR_ABRE (1UL << USART_ISR_ABRE_BIT) -#define USART_SR_EOBF (1UL << USART_ISR_EOBF_BIT) -#define USART_SR_RTOF (1UL << USART_ISR_RTOF_BIT) -#define USART_SR_CTS (1UL << USART_ISR_CTS_BIT) -#define USART_SR_CTSIF (1UL << USART_ISR_CTSIF_BIT) - -/* Interrupt clear register */ -#define USART_ICR_WUFCF_BIT 20 -#define USART_ICR_CMCF_BIT 17 -#define USART_ICR_EOBCF_BIT 12 -#define USART_ICR_RTOCF_BIT 11 -#define USART_ICR_CTSCF_BIT 9 -#define USART_ICR_LBDCF_BIT 8 -#define USART_ICR_TCCF_BIT 6 -#define USART_ICR_IDLECF_BIT 4 -#define USART_ICR_ORECF_BIT 3 -#define USART_ICR_NCF_BIT 2 -#define USART_ICR_FECF_BIT 1 -#define USART_ICR_PECF_BIT 0 - -#define USART_ICR_WUFCF (1UL << USART_ICR_WUFCF_BIT) -#define USART_ICR_CMCF (1UL << USART_ICR_CMCF_BIT) -#define USART_ICR_EOBCF (1UL << USART_ICR_EOBCF_BIT) -#define USART_ICR_RTOCF (1UL << USART_ICR_RTOCF_BIT) -#define USART_ICR_CTSCF (1UL << USART_ICR_CTSCF_BIT) -#define USART_ICR_LBDCF (1UL << USART_ICR_LBDCF_BIT) -#define USART_ICR_TCCF (1UL << USART_ICR_TCCF_BIT) -#define USART_ICR_IDLECF (1UL << USART_ICR_IDLECF_BIT) -#define USART_ICR_ORECF (1UL << USART_ICR_ORECF_BIT) -#define USART_ICR_NCF (1UL << USART_ICR_NCF_BIT) -#define USART_ICR_FECF (1UL << USART_ICR_FECF_BIT) -#define USART_ICR_PECF (1UL << USART_ICR_PECF_BIT) - -/* Receive data register */ -#define USART_RDR_RDR_SHIFT 0 - -#define USART_RDR_RDR (0x1FF << USART_RDR_RDR_SHIFT) - - -/* Transmit data register */ -#define USART_TDR_TDR_SHIFT 0 - -#define USART_TDR_TDR (0x1FF << USART_TDR_TDR_SHIFT) - -/* - * Routines - */ - -gpio_af usart_get_af(struct usart_dev *dev); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/stm32f3/rules.mk b/STM32F3/cores/maple/libmaple/stm32f3/rules.mk deleted file mode 100644 index f17f7451e..000000000 --- a/STM32F3/cores/maple/libmaple/stm32f3/rules.mk +++ /dev/null @@ -1,48 +0,0 @@ -# Standard things -sp := $(sp).x -dirstack_$(sp) := $(d) -d := $(dir) -BUILDDIRS += $(BUILD_PATH)/$(d) - -# Local flags -CFLAGS_$(d) = -I$(d) $(LIBMAPLE_PRIVATE_INCLUDES) $(LIBMAPLE_INCLUDES) -Wall -Werror -ASFLAGS_$(d) = -I$(d) $(LIBMAPLE_PRIVATE_INCLUDES) $(LIBMAPLE_INCLUDES) -Wall -Werror - -# Extra BUILDDIRS -BUILDDIRS += $(BUILD_PATH)/$(d)/F30xxx - -# Local rules and targets -sSRCS_$(d) := F30xxx/isrs.S -sSRCS_$(d) += F30xxx/vector_table.S - -cSRCS_$(d) := adc.c -cSRCS_$(d) += dma.c -cSRCS_$(d) += exti.c -cSRCS_$(d) += gpio.c -cSRCS_$(d) += i2c.c -cSRCS_$(d) += rcc.c -cSRCS_$(d) += spi.c -cSRCS_$(d) += timer.c -cSRCS_$(d) += usart.c -cSRCS_$(d) += syscfg.c -cSRCS_$(d) += fpu.c -cSRCS_$(d) += comp.c -cSRCS_$(d) += opamp.c -cSRCS_$(d) += bkp.c - -sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%) -cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) - -OBJS_$(d) := $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) \ - $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) -DEPS_$(d) := $(OBJS_$(d):%.o=%.d) - -$(OBJS_$(d)): TGT_ASFLAGS := $(ASFLAGS_$(d)) -$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) - -TGT_BIN += $(OBJS_$(d)) - -# Standard things --include $(DEPS_$(d)) -d := $(dirstack_$(sp)) -sp := $(basename $(sp)) diff --git a/STM32F3/cores/maple/libmaple/syscfg.c b/STM32F3/cores/maple/libmaple/syscfg.c deleted file mode 100644 index 8b3c96301..000000000 --- a/STM32F3/cores/maple/libmaple/syscfg.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/syscfg.c - * @brief System configuration controller (SYSCFG) - * @author F3-port by Hanspeter Portner - * - * Availability: STM32F2, STM32F3, STM32F4. - */ - -#include -#include - -void syscfg_init(void) { - rcc_clk_enable(RCC_SYSCFG); - rcc_reset_dev(RCC_SYSCFG); -} diff --git a/STM32F3/cores/maple/libmaple/systick.c b/STM32F3/cores/maple/libmaple/systick.c deleted file mode 100644 index 7568abe06..000000000 --- a/STM32F3/cores/maple/libmaple/systick.c +++ /dev/null @@ -1,88 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2010, 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/systick.c - * @brief System timer (SysTick). - */ - -#include - -volatile uint32 systick_uptime_millis; -static void (*systick_user_callback)(void); - -/** - * @brief Initialize and enable SysTick. - * - * Clocks the system timer with the core clock, turns it on, and - * enables interrupts. - * - * @param reload_val Appropriate reload counter to tick every 1 ms. - */ -void systick_init(uint32 reload_val) { - SYSTICK_BASE->RVR = reload_val; - systick_enable(); -} - -/** - * Clock the system timer with the core clock, but don't turn it - * on or enable interrupt. - */ -void systick_disable() { - SYSTICK_BASE->CSR = SYSTICK_CSR_CLKSOURCE_CORE; -} - -/** - * Clock the system timer with the core clock and turn it on; - * interrupt every 1 ms, for systick_timer_millis. - */ -void systick_enable() { - /* re-enables init registers without changing reload val */ - SYSTICK_BASE->CSR = (SYSTICK_CSR_CLKSOURCE_CORE | - SYSTICK_CSR_ENABLE | - SYSTICK_CSR_TICKINT_PEND); -} - -/** - * @brief Attach a callback to be called from the SysTick exception handler. - * - * To detach a callback, call this function again with a null argument. - */ -void systick_attach_callback(void (*callback)(void)) { - systick_user_callback = callback; -} - -/* - * SysTick ISR - */ - -void __exc_systick(void) { - systick_uptime_millis++; - if (systick_user_callback) { - systick_user_callback(); - } -} diff --git a/STM32F3/cores/maple/libmaple/timer.c b/STM32F3/cores/maple/libmaple/timer.c deleted file mode 100644 index e48cb1a57..000000000 --- a/STM32F3/cores/maple/libmaple/timer.c +++ /dev/null @@ -1,456 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/timer.c - * @author Marti Bolivar - * @brief Portable timer routines. - */ - -#include -#include -#include "timer_private.h" - -static void disable_channel(timer_dev *dev, uint8 channel); -static void pwm_mode(timer_dev *dev, uint8 channel); -static void output_compare_mode(timer_dev *dev, uint8 channel); - -static inline void enable_irq(timer_dev *dev, uint8 interrupt); - -/* - * Devices - * - * Defer to the timer_private API for declaring these. - */ - -#if STM32_HAVE_TIMER(1) -static timer_dev timer1 = ADVANCED_TIMER(1); -/** Timer 1 device (advanced) */ -timer_dev *TIMER1 = &timer1; -#endif -#if STM32_HAVE_TIMER(2) -static timer_dev timer2 = GENERAL_TIMER(2); -/** Timer 2 device (general-purpose) */ -timer_dev *TIMER2 = &timer2; -#endif -#if STM32_HAVE_TIMER(3) -static timer_dev timer3 = GENERAL_TIMER(3); -/** Timer 3 device (general-purpose) */ -timer_dev *TIMER3 = &timer3; -#endif -#if STM32_HAVE_TIMER(4) -static timer_dev timer4 = GENERAL_TIMER(4); -/** Timer 4 device (general-purpose) */ -timer_dev *TIMER4 = &timer4; -#endif -#if STM32_HAVE_TIMER(5) -static timer_dev timer5 = GENERAL_TIMER(5); -/** Timer 5 device (general-purpose) */ -timer_dev *TIMER5 = &timer5; -#endif -#if STM32_HAVE_TIMER(6) -static timer_dev timer6 = BASIC_TIMER(6); -/** Timer 6 device (basic) */ -timer_dev *TIMER6 = &timer6; -#endif -#if STM32_HAVE_TIMER(7) -static timer_dev timer7 = BASIC_TIMER(7); -/** Timer 7 device (basic) */ -timer_dev *TIMER7 = &timer7; -#endif -#if STM32_HAVE_TIMER(8) -static timer_dev timer8 = ADVANCED_TIMER(8); -/** Timer 8 device (advanced) */ -timer_dev *TIMER8 = &timer8; -#endif -#if STM32_HAVE_TIMER(9) -static timer_dev timer9 = RESTRICTED_GENERAL_TIMER(9, TIMER_DIER_TIE_BIT); -/** Timer 9 device (general-purpose) */ -timer_dev *TIMER9 = &timer9; -#endif -#if STM32_HAVE_TIMER(10) -static timer_dev timer10 = RESTRICTED_GENERAL_TIMER(10, TIMER_DIER_CC1IE_BIT); -/** Timer 10 device (general-purpose) */ -timer_dev *TIMER10 = &timer10; -#endif -#if STM32_HAVE_TIMER(11) -static timer_dev timer11 = RESTRICTED_GENERAL_TIMER(11, TIMER_DIER_CC1IE_BIT); -/** Timer 11 device (general-purpose) */ -timer_dev *TIMER11 = &timer11; -#endif -#if STM32_HAVE_TIMER(12) -static timer_dev timer12 = RESTRICTED_GENERAL_TIMER(12, TIMER_DIER_TIE_BIT); -/** Timer 12 device (general-purpose) */ -timer_dev *TIMER12 = &timer12; -#endif -#if STM32_HAVE_TIMER(13) -static timer_dev timer13 = RESTRICTED_GENERAL_TIMER(13, TIMER_DIER_CC1IE_BIT); -/** Timer 13 device (general-purpose) */ -timer_dev *TIMER13 = &timer13; -#endif -#if STM32_HAVE_TIMER(14) -static timer_dev timer14 = RESTRICTED_GENERAL_TIMER(14, TIMER_DIER_CC1IE_BIT); -/** Timer 14 device (general-purpose) */ -timer_dev *TIMER14 = &timer14; -#endif -#if STM32_HAVE_TIMER(15) -static timer_dev timer15 = RESTRICTED_GENERAL_TIMER(15, TIMER_DIER_TIE_BIT); //XXX -/** Timer 15 device (general-purpose) */ -timer_dev *TIMER15 = &timer15; -#endif -#if STM32_HAVE_TIMER(16) -static timer_dev timer16 = RESTRICTED_GENERAL_TIMER(16, TIMER_DIER_CC1IE_BIT); //XXX -/** Timer 16 device (general-purpose) */ -timer_dev *TIMER16 = &timer16; -#endif -#if STM32_HAVE_TIMER(17) -static timer_dev timer17 = RESTRICTED_GENERAL_TIMER(17, TIMER_DIER_CC1IE_BIT); //XXX -/** Timer 17 device (general-purpose) */ -timer_dev *TIMER17 = &timer17; -#endif - -/* - * Routines - */ - -/** - * @brief Call a function on timer devices. - * @param fn Function to call on each timer device. - */ -void timer_foreach(void (*fn)(timer_dev*)) { -#if STM32_HAVE_TIMER(1) - fn(TIMER1); -#endif -#if STM32_HAVE_TIMER(2) - fn(TIMER2); -#endif -#if STM32_HAVE_TIMER(3) - fn(TIMER3); -#endif -#if STM32_HAVE_TIMER(4) - fn(TIMER4); -#endif -#if STM32_HAVE_TIMER(5) - fn(TIMER5); -#endif -#if STM32_HAVE_TIMER(6) - fn(TIMER6); -#endif -#if STM32_HAVE_TIMER(7) - fn(TIMER7); -#endif -#if STM32_HAVE_TIMER(8) - fn(TIMER8); -#endif -#if STM32_HAVE_TIMER(9) - fn(TIMER9); -#endif -#if STM32_HAVE_TIMER(10) - fn(TIMER10); -#endif -#if STM32_HAVE_TIMER(11) - fn(TIMER11); -#endif -#if STM32_HAVE_TIMER(12) - fn(TIMER12); -#endif -#if STM32_HAVE_TIMER(13) - fn(TIMER13); -#endif -#if STM32_HAVE_TIMER(14) - fn(TIMER14); -#endif -#if STM32_HAVE_TIMER(15) - fn(TIMER15); -#endif -#if STM32_HAVE_TIMER(16) - fn(TIMER16); -#endif -#if STM32_HAVE_TIMER(17) - fn(TIMER17); -#endif -} - -/** - * Initialize a timer, and reset its register map. - * @param dev Timer to initialize - */ -void timer_init(timer_dev *dev) { - rcc_clk_enable(dev->clk_id); - rcc_reset_dev(dev->clk_id); -} - -/** - * @brief Disable a timer. - * - * The timer will stop counting, all DMA requests and interrupts will - * be disabled, and no state changes will be output. - * - * @param dev Timer to disable. - */ -void timer_disable(timer_dev *dev) { - (dev->regs).bas->CR1 = 0; - (dev->regs).bas->DIER = 0; - switch (dev->type) { - case TIMER_ADVANCED: /* fall-through */ - case TIMER_GENERAL: - (dev->regs).gen->CCER = 0; - break; - case TIMER_BASIC: - break; - } -} - -/** - * Sets the mode of an individual timer channel. - * - * Note that not all timers can be configured in every mode. For - * example, basic timers cannot be configured to output compare mode. - * Be sure to use a timer which is appropriate for the mode you want. - * - * @param dev Timer whose channel mode to set - * @param channel Relevant channel - * @param mode New timer mode for channel - */ -void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) { - ASSERT_FAULT(channel > 0 && channel <= 4); - - /* TODO decide about the basic timers */ - ASSERT(dev->type != TIMER_BASIC); - if (dev->type == TIMER_BASIC) - return; - - switch (mode) { - case TIMER_DISABLED: - disable_channel(dev, channel); - break; - case TIMER_PWM: - pwm_mode(dev, channel); - break; - case TIMER_OUTPUT_COMPARE: - output_compare_mode(dev, channel); - break; - } -} - -/** - * @brief Determine whether a timer has a particular capture/compare channel. - * - * Different timers have different numbers of capture/compare channels - * (and some have none at all). Use this function to test whether a - * given timer/channel combination will work. - * - * @param dev Timer device - * @param channel Capture/compare channel, from 1 to 4 - * @return Nonzero if dev has channel, zero otherwise. - */ -int timer_has_cc_channel(timer_dev *dev, uint8 channel) { - /* On all currently supported series: advanced and "full-featured" - * general purpose timers have all four channels. Of the - * restricted general timers, timers 9, 12 and 15 have channels 1 and - * 2; the others have channel 1 only. Basic timers have none. */ - rcc_clk_id id = dev->clk_id; - ASSERT((1 <= channel) && (channel <= 4)); - if (id <= RCC_TIMER5 || id == RCC_TIMER8) { - return 1; /* 1 and 8 are advanced, 2-5 are "full" general */ - } else if (id <= RCC_TIMER7) { - return 0; /* 6 and 7 are basic */ - } - /* The rest are restricted general. */ - return (((id == RCC_TIMER9 || id == RCC_TIMER12 || id == RCC_TIMER15) && channel <= 2) || - channel == 1); -} - -/** - * @brief Attach a timer interrupt. - * @param dev Timer device - * @param interrupt Interrupt number to attach to; this may be any - * timer_interrupt_id or timer_channel value appropriate - * for the timer. - * @param handler Handler to attach to the given interrupt. - * @see timer_interrupt_id - * @see timer_channel - */ -void timer_attach_interrupt(timer_dev *dev, - uint8 interrupt, - voidFuncPtr handler) { - dev->handlers[interrupt] = handler; - timer_enable_irq(dev, interrupt); - enable_irq(dev, interrupt); -} - -/** - * @brief Detach a timer interrupt. - * @param dev Timer device - * @param interrupt Interrupt number to detach; this may be any - * timer_interrupt_id or timer_channel value appropriate - * for the timer. - * @see timer_interrupt_id - * @see timer_channel - */ -void timer_detach_interrupt(timer_dev *dev, uint8 interrupt) { - timer_disable_irq(dev, interrupt); - dev->handlers[interrupt] = NULL; -} - -/* - * Utilities - */ - -static void disable_channel(timer_dev *dev, uint8 channel) { - timer_detach_interrupt(dev, channel); - timer_cc_disable(dev, channel); -} - -static void pwm_mode(timer_dev *dev, uint8 channel) { - timer_disable_irq(dev, channel); - timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE); - timer_cc_enable(dev, channel); -} - -static void output_compare_mode(timer_dev *dev, uint8 channel) { - timer_oc_set_mode(dev, channel, TIMER_OC_MODE_ACTIVE_ON_MATCH, 0); - timer_cc_enable(dev, channel); -} - -static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id); -static void enable_bas_gen_irq(timer_dev *dev); - -static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid) { - if (dev->type == TIMER_ADVANCED) { - enable_adv_irq(dev, iid); - } else { - enable_bas_gen_irq(dev); - } -} - -/* Advanced control timers have several IRQ lines corresponding to - * different timer interrupts. - * - * Note: This function assumes that the only advanced timers are TIM1 - * and TIM8, and needs the obvious changes if that assumption is - * violated by a later STM32 series. */ -static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id) { - uint8 is_tim1 = dev->clk_id == RCC_TIMER1; - nvic_irq_num irq_num; - switch (id) { - case TIMER_UPDATE_INTERRUPT: - irq_num = (is_tim1 ? - NVIC_TIMER1_UP_TIMER10 : - NVIC_TIMER8_UP_TIMER13); - break; - case TIMER_CC1_INTERRUPT: /* Fall through */ - case TIMER_CC2_INTERRUPT: /* ... */ - case TIMER_CC3_INTERRUPT: /* ... */ - case TIMER_CC4_INTERRUPT: - irq_num = is_tim1 ? NVIC_TIMER1_CC : NVIC_TIMER8_CC; - break; - case TIMER_COM_INTERRUPT: /* Fall through */ - case TIMER_TRG_INTERRUPT: - irq_num = (is_tim1 ? - NVIC_TIMER1_TRG_COM_TIMER11 : - NVIC_TIMER8_TRG_COM_TIMER14); - break; - case TIMER_BREAK_INTERRUPT: - irq_num = (is_tim1 ? - NVIC_TIMER1_BRK_TIMER9 : - NVIC_TIMER8_BRK_TIMER12); - break; - default: - /* Can't happen, but placate the compiler */ - ASSERT(0); - return; - } - nvic_irq_enable(irq_num); -} - -/* Basic and general purpose timers have a single IRQ line, which is - * shared by all interrupts supported by a particular timer. */ -static void enable_bas_gen_irq(timer_dev *dev) { - nvic_irq_num irq_num; - switch (dev->clk_id) { - case RCC_TIMER2: - irq_num = NVIC_TIMER2; - break; - case RCC_TIMER3: - irq_num = NVIC_TIMER3; - break; - case RCC_TIMER4: - irq_num = NVIC_TIMER4; - break; -#if STM32_HAVE_TIMER(5) - case RCC_TIMER5: - irq_num = NVIC_TIMER5; - break; -#endif - case RCC_TIMER6: - irq_num = NVIC_TIMER6; - break; - case RCC_TIMER7: - irq_num = NVIC_TIMER7; - break; - case RCC_TIMER9: - irq_num = NVIC_TIMER1_BRK_TIMER9; - break; - case RCC_TIMER10: - irq_num = NVIC_TIMER1_UP_TIMER10; - break; - case RCC_TIMER11: - irq_num = NVIC_TIMER1_TRG_COM_TIMER11; - break; - case RCC_TIMER12: - irq_num = NVIC_TIMER8_BRK_TIMER12; - break; - case RCC_TIMER13: - irq_num = NVIC_TIMER8_UP_TIMER13; - break; - case RCC_TIMER14: - irq_num = NVIC_TIMER8_TRG_COM_TIMER14; - break; -#if STM32_HAVE_TIMER(15) - case RCC_TIMER15: - //irq_num = NVIC_TIMER1_BRK_TIMER15; - irq_num = NVIC_TIMER1_BRK_TIMER9; - break; -#endif -#if STM32_HAVE_TIMER(16) - case RCC_TIMER16: - //irq_num = NVIC_TIMER1_UP_TIMER16; - irq_num = NVIC_TIMER1_UP_TIMER10; - break; -#endif -#if STM32_HAVE_TIMER(17) - case RCC_TIMER17: - //irq_num = NVIC_TIMER1_TRG_COM_TIMER17; - irq_num = NVIC_TIMER1_TRG_COM_TIMER11; - break; -#endif - default: - ASSERT_FAULT(0); - return; - } - nvic_irq_enable(irq_num); -} diff --git a/STM32F3/cores/maple/libmaple/timer_private.h b/STM32F3/cores/maple/libmaple/timer_private.h deleted file mode 100644 index 320c6364a..000000000 --- a/STM32F3/cores/maple/libmaple/timer_private.h +++ /dev/null @@ -1,235 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/timer_private.h - * @author Marti Bolivar - * @brief Private, internal timer APIs. - */ - -#ifndef _LIBMAPLE_TIMER_PRIVATE_H_ -#define _LIBMAPLE_TIMER_PRIVATE_H_ - -/* - * Helper macros for declaring timer_devs of various timer_types - */ - -/* The indexes of user handlers in a timer_dev.handlers are just like - * the corresponding DIER bits, as follows: */ - -/* Advanced timers: - * [0] = Update handler; - * [1,2,3,4] = capture/compare 1,2,3,4 handlers, respectively; - * [5] = COM; - * [6] = TRG; - * [7] = BRK. */ -#define NR_ADV_HANDLERS 8 -/* General purpose timers: - * [0] = update; - * [1,2,3,4] = capture/compare 1,2,3,4; - * [5] = ; - * [6] = trigger. */ -#define NR_GEN_HANDLERS 7 -/* Basic timers: - * [0] = update. */ -#define NR_BAS_HANDLERS 1 - -/* For declaring advanced timers. */ -#define ADVANCED_TIMER(num) \ - { \ - .regs = { .adv = TIMER##num##_BASE }, \ - .clk_id = RCC_TIMER##num, \ - .type = TIMER_ADVANCED, \ - .handlers = { [NR_ADV_HANDLERS - 1] = 0 }, \ - } - -/* For declaring full-featured general purpose timers. */ -#define GENERAL_TIMER(num) \ - { \ - .regs = { .gen = TIMER##num##_BASE }, \ - .clk_id = RCC_TIMER##num, \ - .type = TIMER_GENERAL, \ - .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, \ - } - -/* For declaring general purpose timers with limited interrupt - * capability (e.g. timers 9 through 14 on STM32F2 and XL-density - * STM32F1). */ -#define RESTRICTED_GENERAL_TIMER(num, max_dier_bit) \ - { \ - .regs = { .gen = TIMER##num##_BASE }, \ - .clk_id = RCC_TIMER##num, \ - .type = TIMER_GENERAL, \ - .handlers = { [max_dier_bit] = 0 }, \ - } - -/* For declaring basic timers (e.g. TIM6 and TIM7). */ -#define BASIC_TIMER(num) \ - { \ - .regs = { .bas = TIMER##num##_BASE }, \ - .clk_id = RCC_TIMER##num, \ - .type = TIMER_BASIC, \ - .handlers = { [NR_BAS_HANDLERS - 1] = 0 }, \ - } - -/* - * IRQ handlers - * - * These decode TIMx_DIER and TIMx_SR, then dispatch to the user-level - * IRQ handlers. They also clean up TIMx_SR afterwards, so the user - * doesn't have to deal with register details. - * - * Notes: - * - * - These dispatch routines make use of the fact that DIER interrupt - * enable bits and SR interrupt flags have common bit positions. - * Thus, ANDing DIER and SR lets us check if an interrupt is enabled - * and if it has occurred simultaneously. - * - * - We force these routines to inline to avoid call overhead, but - * there aren't any measurements to prove that this is actually a - * good idea. Profile-directed optimizations are definitely wanted. */ - -/* A special-case dispatch routine for timers which only serve a - * single interrupt on a given IRQ line. - * - * This function still checks DIER & SR, as in some cases, a timer may - * only serve a single interrupt on a particular NVIC line, but that - * line may be shared with another timer. For example, the timer 1 - * update interrupt shares an IRQ line with the timer 10 interrupt on - * STM32F1 (XL-density), STM32F2, and STM32F4. */ -static __always_inline void dispatch_single_irq(timer_dev *dev, - timer_interrupt_id iid, - uint32 irq_mask) { - timer_bas_reg_map *regs = (dev->regs).bas; - if (regs->DIER & regs->SR & irq_mask) { - void (*handler)(void) = dev->handlers[iid]; - if (handler) { - handler(); - regs->SR &= ~irq_mask; - } - } -} - -/* Helper macro for dispatch routines which service multiple interrupts. */ -#define handle_irq(dier_sr, irq_mask, handlers, iid, handled_irq) do { \ - if ((dier_sr) & (irq_mask)) { \ - void (*__handler)(void) = (handlers)[iid]; \ - if (__handler) { \ - __handler(); \ - handled_irq |= (irq_mask); \ - } \ - } \ - } while (0) - -static __always_inline void dispatch_adv_brk(timer_dev *dev) { - dispatch_single_irq(dev, TIMER_BREAK_INTERRUPT, TIMER_SR_BIF); -} - -static __always_inline void dispatch_adv_up(timer_dev *dev) { - dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); -} - -static __always_inline void dispatch_adv_trg_com(timer_dev *dev) { - timer_adv_reg_map *regs = (dev->regs).adv; - uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; - uint32 handled = 0; /* Logical OR of SR interrupt flags we end up - * handling. We clear these. User handlers - * must clear overcapture flags, to avoid - * wasting time in output mode. */ - - handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_COMIF, hs, TIMER_COM_INTERRUPT, handled); - - regs->SR &= ~handled; -} - -static __always_inline void dispatch_adv_cc(timer_dev *dev) { - timer_adv_reg_map *regs = (dev->regs).adv; - uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; - uint32 handled = 0; - - handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC3IF, hs, TIMER_CC3_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); - - regs->SR &= ~handled; -} - -static __always_inline void dispatch_general(timer_dev *dev) { - timer_gen_reg_map *regs = (dev->regs).gen; - uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; - uint32 handled = 0; - - handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC3IF, hs, TIMER_CC3_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); - - regs->SR &= ~handled; -} - -/* On F1 (XL-density), F2, and F4, TIM9 and TIM12 are restricted - * general-purpose timers with update, CC1, CC2, and TRG interrupts. */ -static __always_inline void dispatch_tim_9_12(timer_dev *dev) { - timer_gen_reg_map *regs = (dev->regs).gen; - uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; - uint32 handled = 0; - - handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); - - regs->SR &= ~handled; -} - -/* On F1 (XL-density), F2, and F4, timers 10, 11, 13, and 14 are - * restricted general-purpose timers with update and CC1 interrupts. */ -static __always_inline void dispatch_tim_10_11_13_14(timer_dev *dev) { - timer_gen_reg_map *regs = (dev->regs).gen; - uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; - uint32 handled = 0; - - handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); - - regs->SR &= ~handled; -} - -static __always_inline void dispatch_basic(timer_dev *dev) { - dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); -} - -#endif diff --git a/STM32F3/cores/maple/libmaple/usart.c b/STM32F3/cores/maple/libmaple/usart.c deleted file mode 100644 index 52da4d10f..000000000 --- a/STM32F3/cores/maple/libmaple/usart.c +++ /dev/null @@ -1,122 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/usart.c - * @author Marti Bolivar , - * Perry Hung - * @brief Portable USART routines - */ - -#include - -/** - * @brief Initialize a serial port. - * @param dev Serial port to be initialized - */ -void usart_init(usart_dev *dev) { - rb_init(dev->rb, USART_RX_BUF_SIZE, dev->rx_buf); - rcc_clk_enable(dev->clk_id); - nvic_irq_enable(dev->irq_num); -} - -/** - * @brief Enable a serial port. - * - * USART is enabled in single buffer transmission mode, multibuffer - * receiver mode, 8n1. - * - * Serial port must have a baud rate configured to work properly. - * - * @param dev Serial port to enable. - * @see usart_set_baud_rate() - */ -void usart_enable(usart_dev *dev) { - usart_reg_map *regs = dev->regs; - regs->CR1 = (USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE | - USART_CR1_M_8N1); - regs->CR1 |= USART_CR1_UE; -} - -/** - * @brief Turn off a serial port. - * @param dev Serial port to be disabled - */ -void usart_disable(usart_dev *dev) { - /* FIXME this misbehaves (on F1) if you try to use PWM on TX afterwards */ - usart_reg_map *regs = dev->regs; - - /* TC bit must be high before disabling the USART */ - while((regs->CR1 & USART_CR1_UE) && !(regs->SR & USART_SR_TC)) - ; - - /* Disable UE */ - regs->CR1 &= ~USART_CR1_UE; - - /* Clean up buffer */ - usart_reset_rx(dev); -} - -/** - * @brief Nonblocking USART receive. - * @param dev Serial port to receive bytes from - * @param buf Buffer to store received bytes into - * @param len Maximum number of bytes to store - * @return Number of bytes received - */ -uint32 usart_rx(usart_dev *dev, uint8 *buf, uint32 len) { - uint32 rxed = 0; - while (usart_data_available(dev) && rxed < len) { - *buf++ = usart_getc(dev); - rxed++; - } - return rxed; -} - -/** - * @brief Transmit an unsigned integer to the specified serial port in - * decimal format. - * - * This function blocks until the integer's digits have been - * completely transmitted. - * - * @param dev Serial port to send on - * @param val Number to print - */ -void usart_putudec(usart_dev *dev, uint32 val) { - char digits[12]; - int i = 0; - - do { - digits[i++] = val % 10 + '0'; - val /= 10; - } while (val > 0); - - while (--i >= 0) { - usart_putc(dev, digits[i]); - } -} diff --git a/STM32F3/cores/maple/libmaple/usart_private.c b/STM32F3/cores/maple/libmaple/usart_private.c deleted file mode 100644 index 0eaacdf17..000000000 --- a/STM32F3/cores/maple/libmaple/usart_private.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/usart_private.c - * @author Marti Bolivar - * @brief Private USART routines. - */ - -#include "usart_private.h" -#include -#include - -uint32 _usart_clock_freq(usart_dev *dev) { - rcc_clk_domain domain = rcc_dev_clk(dev->clk_id); - return (domain == RCC_APB1 ? STM32_PCLK1 : - (domain == RCC_APB2 ? STM32_PCLK2 : 0)); -} diff --git a/STM32F3/cores/maple/libmaple/usart_private.h b/STM32F3/cores/maple/libmaple/usart_private.h deleted file mode 100644 index e6044d874..000000000 --- a/STM32F3/cores/maple/libmaple/usart_private.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/usart_private.h - * @author Marti Bolivar - * @brief Private USART header. - */ - -#ifndef _LIBMAPLE_USART_PRIVATE_H_ -#define _LIBMAPLE_USART_PRIVATE_H_ - -#include -#include - -uint32 _usart_clock_freq(usart_dev *dev); - -#endif diff --git a/STM32F3/cores/maple/libmaple/usb/README b/STM32F3/cores/maple/libmaple/usb/README deleted file mode 100644 index d0fca8d00..000000000 --- a/STM32F3/cores/maple/libmaple/usb/README +++ /dev/null @@ -1,63 +0,0 @@ -The USB submodule of libmaple is a separate piece of the codebase for -reasons that are largely historical. - -Current Status: - - There's only support for the USB device peripheral found on - STM32F103s. - - We rely on the low level core library provided by ST to implement - the USB transfer protocol for control endpoint transfers. - - The virtual com port (which is exposed via - ) serves two important purposes. - - 1) It allows serial data transfers between user sketches an a - host computer. - - 2) It allows the host PC to issue a system reset into the DFU - bootloader with the DTR + RTS + "1EAF" sequence (see - leaflabs.com/docs/bootloader.html for more information on - this). - - After reset, Maple will run the DFU bootloader for a few seconds, - during which the user can begin a DFU upload operation (uploads - application binary into RAM/FLASH). Thus, without this virtual com - port, it would be necessary to find an alternative means to reset - the chip in order to enable the bootloader. - - If you would like to develop your own USB application for whatever - reason (e.g. to use faster isochronous enpoints for streaming - audio, or implement the USB HID or Mass Storage specs), then - ensure that you leave some hook for resetting Maple remotely in - order to spin up the DFU bootloader. Please make sure to get - yourself a unique vendor/product ID pair for your application, as - some operating systems will assign a host-side driver based on - these tags. - - It would be possible to build a compound USB device, that - implements endpoints for both the virtual COM port as well as some - other components (mass storage etc.). However, this turns out to - be a burden from the host driver side, as Windows and *nix handle - compound USB devices quite differently. - - Be mindful that enabling the USB peripheral isn't "free." The - device must respond to periodic bus activity (every few - milliseconds) by servicing an ISR. Therefore, the USB application - should be disabled inside of timing critical applications. - - In order to disconnect the device from the host, a USB_DISC pin is - asserted (e.g. on Maple, this is PC12). Alternatively, the NVIC - can be directly configured to disable the USB LP/HP IRQ's. - - The files inside of usb_lib were provided by ST and are subject to - their own license, all other files were written by the LeafLabs - team and fall under the MIT license. - -TODO: - - - Generic USB driver core with series-provided backends, like - libopencm3 has. - - Strip out ST code. - - Integration with a high level USB library (like LUFA/MyUSB) to - allow users to write custom USB applications. diff --git a/STM32F3/cores/maple/libmaple/usb/usb_cdcacm.c b/STM32F3/cores/maple/libmaple/usb/usb_cdcacm.c deleted file mode 100644 index bafb90ba6..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_cdcacm.c +++ /dev/null @@ -1,723 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/usb/stm32f1/usb_cdcacm.c - * @brief USB CDC ACM (a.k.a. virtual serial terminal, VCOM). - * - * FIXME: this works on the STM32F1 USB peripherals, and probably no - * place else. Nonportable bits really need to be factored out, and - * the result made cleaner. - */ - -#include - -#include -#include -#include - -/* Private headers */ -#include "usb_lib_globals.h" -#include "usb_reg_map.h" - -/* usb_lib headers */ -#include "usb_type.h" -#include "usb_core.h" -#include "usb_def.h" - -/****************************************************************************** - ****************************************************************************** - *** - *** HACK ALERT! FIXME FIXME FIXME FIXME! - *** - *** A bunch of LeafLabs-specific configuration lives in here for - *** now. This mess REALLY needs to get teased apart, with - *** appropriate pieces moved into Wirish. - *** - ****************************************************************************** - *****************************************************************************/ - -#if !(defined(BOARD_maple_mini_f3)) -#warning USB CDC ACM relies on LeafLabs board-specific configuration.\ - You may have problems on non-LeafLabs boards. -#endif - -static void vcomDataTxCb(void); -static void vcomDataRxCb(void); -static uint8* vcomGetSetLineCoding(uint16); - -static void usbInit(void); -static void usbReset(void); -static RESULT usbDataSetup(uint8 request); -static RESULT usbNoDataSetup(uint8 request); -static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting); -static uint8* usbGetDeviceDescriptor(uint16 length); -static uint8* usbGetConfigDescriptor(uint16 length); -static uint8* usbGetStringDescriptor(uint16 length); -static void usbSetConfiguration(void); -static void usbSetDeviceAddress(void); - -/* - * Descriptors - */ - -/* FIXME move to Wirish */ -#define LEAFLABS_ID_VENDOR 0x1EAF -#define MAPLE_ID_PRODUCT 0x0004 -static const usb_descriptor_device usbVcomDescriptor_Device = - USB_CDCACM_DECLARE_DEV_DESC(LEAFLABS_ID_VENDOR, MAPLE_ID_PRODUCT); - -typedef struct { - usb_descriptor_config_header Config_Header; - usb_descriptor_interface CCI_Interface; - CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader; - CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_CallManagement; - CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_ACM; - CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union; - usb_descriptor_endpoint ManagementEndpoint; - usb_descriptor_interface DCI_Interface; - usb_descriptor_endpoint DataOutEndpoint; - usb_descriptor_endpoint DataInEndpoint; -} __packed usb_descriptor_config; - -#define MAX_POWER (100 >> 1) -static const usb_descriptor_config usbVcomDescriptor_Config = { - .Config_Header = { - .bLength = sizeof(usb_descriptor_config_header), - .bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION, - .wTotalLength = sizeof(usb_descriptor_config), - .bNumInterfaces = 0x02, - .bConfigurationValue = 0x01, - .iConfiguration = 0x00, - .bmAttributes = (USB_CONFIG_ATTR_BUSPOWERED | - USB_CONFIG_ATTR_SELF_POWERED), - .bMaxPower = MAX_POWER, - }, - - .CCI_Interface = { - .bLength = sizeof(usb_descriptor_interface), - .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, - .bInterfaceNumber = 0x00, - .bAlternateSetting = 0x00, - .bNumEndpoints = 0x01, - .bInterfaceClass = USB_INTERFACE_CLASS_CDC, - .bInterfaceSubClass = USB_INTERFACE_SUBCLASS_CDC_ACM, - .bInterfaceProtocol = 0x01, /* Common AT Commands */ - .iInterface = 0x00, - }, - - .CDC_Functional_IntHeader = { - .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2), - .bDescriptorType = 0x24, - .SubType = 0x00, - .Data = {0x01, 0x10}, - }, - - .CDC_Functional_CallManagement = { - .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2), - .bDescriptorType = 0x24, - .SubType = 0x01, - .Data = {0x03, 0x01}, - }, - - .CDC_Functional_ACM = { - .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(1), - .bDescriptorType = 0x24, - .SubType = 0x02, - .Data = {0x06}, - }, - - .CDC_Functional_Union = { - .bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2), - .bDescriptorType = 0x24, - .SubType = 0x06, - .Data = {0x00, 0x01}, - }, - - .ManagementEndpoint = { - .bLength = sizeof(usb_descriptor_endpoint), - .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, - .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | - USB_CDCACM_MANAGEMENT_ENDP), - .bmAttributes = USB_EP_TYPE_INTERRUPT, - .wMaxPacketSize = USB_CDCACM_MANAGEMENT_EPSIZE, - .bInterval = 0xFF, - }, - - .DCI_Interface = { - .bLength = sizeof(usb_descriptor_interface), - .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE, - .bInterfaceNumber = 0x01, - .bAlternateSetting = 0x00, - .bNumEndpoints = 0x02, - .bInterfaceClass = USB_INTERFACE_CLASS_DIC, - .bInterfaceSubClass = 0x00, /* None */ - .bInterfaceProtocol = 0x00, /* None */ - .iInterface = 0x00, - }, - - .DataOutEndpoint = { - .bLength = sizeof(usb_descriptor_endpoint), - .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, - .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT | - USB_CDCACM_RX_ENDP), - .bmAttributes = USB_EP_TYPE_BULK, - .wMaxPacketSize = USB_CDCACM_RX_EPSIZE, - .bInterval = 0x00, - }, - - .DataInEndpoint = { - .bLength = sizeof(usb_descriptor_endpoint), - .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT, - .bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | USB_CDCACM_TX_ENDP), - .bmAttributes = USB_EP_TYPE_BULK, - .wMaxPacketSize = USB_CDCACM_TX_EPSIZE, - .bInterval = 0x00, - }, -}; - -/* - String Descriptors: - - we may choose to specify any or none of the following string - identifiers: - - iManufacturer: LeafLabs - iProduct: Maple - iSerialNumber: NONE - iConfiguration: NONE - iInterface(CCI): NONE - iInterface(DCI): NONE - -*/ - -/* Unicode language identifier: 0x0409 is US English */ -/* FIXME move to Wirish */ -static const usb_descriptor_string usbVcomDescriptor_LangID = { - .bLength = USB_DESCRIPTOR_STRING_LEN(1), - .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING, - .bString = {0x09, 0x04}, -}; - -/* FIXME move to Wirish */ -static const usb_descriptor_string usbVcomDescriptor_iManufacturer = { - .bLength = USB_DESCRIPTOR_STRING_LEN(8), - .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING, - .bString = {'L', 0, 'e', 0, 'a', 0, 'f', 0, - 'L', 0, 'a', 0, 'b', 0, 's', 0}, -}; - -/* FIXME move to Wirish */ -static const usb_descriptor_string usbVcomDescriptor_iProduct = { - .bLength = USB_DESCRIPTOR_STRING_LEN(5), - .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING, - .bString = {'M', 0, 'a', 0, 'p', 0, 'l', 0, 'e', 0}, -}; - -static ONE_DESCRIPTOR Device_Descriptor = { - (uint8*)&usbVcomDescriptor_Device, - sizeof(usb_descriptor_device) -}; - -static ONE_DESCRIPTOR Config_Descriptor = { - (uint8*)&usbVcomDescriptor_Config, - sizeof(usb_descriptor_config) -}; - -#define N_STRING_DESCRIPTORS 3 -static ONE_DESCRIPTOR String_Descriptor[N_STRING_DESCRIPTORS] = { - {(uint8*)&usbVcomDescriptor_LangID, USB_DESCRIPTOR_STRING_LEN(1)}, - {(uint8*)&usbVcomDescriptor_iManufacturer,USB_DESCRIPTOR_STRING_LEN(8)}, - {(uint8*)&usbVcomDescriptor_iProduct, USB_DESCRIPTOR_STRING_LEN(5)} -}; - -/* - * Etc. - */ - -/* I/O state */ - -/* Received data */ -static volatile uint8 vcomBufferRx[USB_CDCACM_RX_EPSIZE]; -/* Read index into vcomBufferRx */ -static volatile uint32 rx_offset = 0; -/* Number of bytes left to transmit */ -static volatile uint32 n_unsent_bytes = 0; -/* Are we currently sending an IN packet? */ -static volatile uint8 transmitting = 0; -/* Number of unread bytes */ -static volatile uint32 n_unread_bytes = 0; - -/* Other state (line coding, DTR/RTS) */ - -static volatile usb_cdcacm_line_coding line_coding = { - /* This default is 115200 baud, 8N1. */ - .dwDTERate = 115200, - .bCharFormat = USB_CDCACM_STOP_BITS_1, - .bParityType = USB_CDCACM_PARITY_NONE, - .bDataBits = 8, -}; - -/* DTR in bit 0, RTS in bit 1. */ -static volatile uint8 line_dtr_rts = 0; - -/* - * Endpoint callbacks - */ - -static void (*ep_int_in[7])(void) = - {vcomDataTxCb, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process}; - -static void (*ep_int_out[7])(void) = - {NOP_Process, - NOP_Process, - vcomDataRxCb, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process}; - -/* - * Globals required by usb_lib/ - * - * Mark these weak so they can be overriden to implement other USB - * functionality. - */ - -#define NUM_ENDPTS 0x04 -__weak DEVICE Device_Table = { - .Total_Endpoint = NUM_ENDPTS, - .Total_Configuration = 1 -}; - -#define MAX_PACKET_SIZE 0x40 /* 64B, maximum for USB FS Devices */ -__weak DEVICE_PROP Device_Property = { - .Init = usbInit, - .Reset = usbReset, - .Process_Status_IN = NOP_Process, - .Process_Status_OUT = NOP_Process, - .Class_Data_Setup = usbDataSetup, - .Class_NoData_Setup = usbNoDataSetup, - .Class_Get_Interface_Setting = usbGetInterfaceSetting, - .GetDeviceDescriptor = usbGetDeviceDescriptor, - .GetConfigDescriptor = usbGetConfigDescriptor, - .GetStringDescriptor = usbGetStringDescriptor, - .RxEP_buffer = NULL, - .MaxPacketSize = MAX_PACKET_SIZE -}; - -__weak USER_STANDARD_REQUESTS User_Standard_Requests = { - .User_GetConfiguration = NOP_Process, - .User_SetConfiguration = usbSetConfiguration, - .User_GetInterface = NOP_Process, - .User_SetInterface = NOP_Process, - .User_GetStatus = NOP_Process, - .User_ClearFeature = NOP_Process, - .User_SetEndPointFeature = NOP_Process, - .User_SetDeviceFeature = NOP_Process, - .User_SetDeviceAddress = usbSetDeviceAddress -}; - -/* - * User hooks - */ - -static void (*rx_hook)(unsigned, void*) = 0; -static void (*iface_setup_hook)(unsigned, void*) = 0; - -void usb_cdcacm_set_hooks(unsigned hook_flags, void (*hook)(unsigned, void*)) { - if (hook_flags & USB_CDCACM_HOOK_RX) { - rx_hook = hook; - } - if (hook_flags & USB_CDCACM_HOOK_IFACE_SETUP) { - iface_setup_hook = hook; - } -} - -/* - * CDC ACM interface - */ - -void usb_cdcacm_enable(gpio_dev *disc_dev, uint8 disc_bit) { - /* Present ourselves to the host. Writing 0 to "disc" pin must - * pull USB_DP pin up while leaving USB_DM pulled down by the - * transceiver. See USB 2.0 spec, section 7.1.7.3. */ - gpio_set_modef(disc_dev, disc_bit, GPIO_MODE_OUTPUT, GPIO_MODEF_TYPE_PP); - gpio_write_bit(disc_dev, disc_bit, 0); - - /* - * set USB_DP and USB_DM pins to alternate mode and set alternate function to USB - */ - gpio_set_modef(GPIOA, 12, GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - gpio_set_modef(GPIOA, 11, GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - gpio_set_af(GPIOA, 12, GPIO_AF_14); - gpio_set_af(GPIOA, 11, GPIO_AF_14); - - /* Initialize the USB peripheral. */ - usb_init_usblib(USBLIB, ep_int_in, ep_int_out); -} - -void usb_cdcacm_disable(gpio_dev *disc_dev, uint8 disc_bit) { - /* Turn off the interrupt and signal disconnect (see e.g. USB 2.0 - * spec, section 7.1.7.3). */ - nvic_irq_disable(NVIC_USB_LP_CAN_RX0); - gpio_write_bit(disc_dev, disc_bit, 1); - - /* - * set USB_DP and USB_DM pins to input floating mode, reset alternate function to system default - */ - gpio_set_modef(GPIOA, 12, GPIO_MODE_INPUT, GPIO_MODEF_PUPD_NONE); - gpio_set_modef(GPIOA, 11, GPIO_MODE_INPUT, GPIO_MODEF_PUPD_NONE); - gpio_set_af(GPIOA, 12, GPIO_AF_0); - gpio_set_af(GPIOA, 11, GPIO_AF_0); -} - -void usb_cdcacm_putc(char ch) { - while (!usb_cdcacm_tx((uint8*)&ch, 1)) - ; -} - -/* This function is non-blocking. - * - * It copies data from a usercode buffer into the USB peripheral TX - * buffer, and returns the number of bytes copied. */ -uint32 usb_cdcacm_tx(const uint8* buf, uint32 len) { - /* Last transmission hasn't finished, so abort. */ - if (usb_cdcacm_is_transmitting()) { - return 0; - } - - /* We can only put USB_CDCACM_TX_EPSIZE bytes in the buffer. */ - if (len > USB_CDCACM_TX_EPSIZE) { - len = USB_CDCACM_TX_EPSIZE; - } - - /* Queue bytes for sending. */ - if (len) { - usb_copy_to_pma(buf, len, USB_CDCACM_TX_ADDR); - } - // We still need to wait for the interrupt, even if we're sending - // zero bytes. (Sending zero-size packets is useful for flushing - // host-side buffers.) - usb_set_ep_tx_count(USB_CDCACM_TX_ENDP, len); - n_unsent_bytes = len; - transmitting = 1; - usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_VALID); - - return len; -} - -uint32 usb_cdcacm_data_available(void) { - return n_unread_bytes; -} - -uint8 usb_cdcacm_is_transmitting(void) { - return transmitting; -} - -uint16 usb_cdcacm_get_pending(void) { - return n_unsent_bytes; -} - -/* Nonblocking byte receive. - * - * Copies up to len bytes from our private data buffer (*NOT* the PMA) - * into buf and deq's the FIFO. */ -uint32 usb_cdcacm_rx(uint8* buf, uint32 len) { - /* Copy bytes to buffer. */ - uint32 n_copied = usb_cdcacm_peek(buf, len); - - /* Mark bytes as read. */ - n_unread_bytes -= n_copied; - rx_offset += n_copied; - - /* If all bytes have been read, re-enable the RX endpoint, which - * was set to NAK when the current batch of bytes was received. */ - if (n_unread_bytes == 0) { - usb_set_ep_rx_count(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_EPSIZE); - usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID); - rx_offset = 0; - } - - return n_copied; -} - -/* Nonblocking byte lookahead. - * - * Looks at unread bytes without marking them as read. */ -uint32 usb_cdcacm_peek(uint8* buf, uint32 len) { - int i; - - if (len > n_unread_bytes) { - len = n_unread_bytes; - } - - for (i = 0; i < len; i++) { - buf[i] = vcomBufferRx[i + rx_offset]; - } - - return len; -} - -uint8 usb_cdcacm_get_dtr() { - return ((line_dtr_rts & USB_CDCACM_CONTROL_LINE_DTR) != 0); -} - -uint8 usb_cdcacm_get_rts() { - return ((line_dtr_rts & USB_CDCACM_CONTROL_LINE_RTS) != 0); -} - -void usb_cdcacm_get_line_coding(usb_cdcacm_line_coding *ret) { - ret->dwDTERate = line_coding.dwDTERate; - ret->bCharFormat = line_coding.bCharFormat; - ret->bParityType = line_coding.bParityType; - ret->bDataBits = line_coding.bDataBits; -} - -int usb_cdcacm_get_baud(void) { - return line_coding.dwDTERate; -} - -int usb_cdcacm_get_stop_bits(void) { - return line_coding.bCharFormat; -} - -int usb_cdcacm_get_parity(void) { - return line_coding.bParityType; -} - -int usb_cdcacm_get_n_data_bits(void) { - return line_coding.bDataBits; -} - - -/* - * Callbacks - */ - -static void vcomDataTxCb(void) { - n_unsent_bytes = 0; - transmitting = 0; -} - -static void vcomDataRxCb(void) { - usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_NAK); - n_unread_bytes = usb_get_ep_rx_count(USB_CDCACM_RX_ENDP); - /* This copy won't overwrite unread bytes, since we've set the RX - * endpoint to NAK, and will only set it to VALID when all bytes - * have been read. */ - usb_copy_from_pma((uint8*)vcomBufferRx, n_unread_bytes, - USB_CDCACM_RX_ADDR); - - - if (n_unread_bytes == 0) { - usb_set_ep_rx_count(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_EPSIZE); - usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID); - rx_offset = 0; - } - - if (rx_hook) { - rx_hook(USB_CDCACM_HOOK_RX, 0); - } -} - -static uint8* vcomGetSetLineCoding(uint16 length) { - if (length == 0) { - pInformation->Ctrl_Info.Usb_wLength = sizeof(struct usb_cdcacm_line_coding); - } - return (uint8*)&line_coding; -} - -static void usbInit(void) { - pInformation->Current_Configuration = 0; - - USB_BASE->CNTR = USB_CNTR_FRES; - - USBLIB->irq_mask = 0; - USB_BASE->CNTR = USBLIB->irq_mask; - USB_BASE->ISTR = 0; - USBLIB->irq_mask = USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; - USB_BASE->CNTR = USBLIB->irq_mask; - - USB_BASE->ISTR = 0; - USBLIB->irq_mask = USB_ISR_MSK; - USB_BASE->CNTR = USBLIB->irq_mask; - - nvic_irq_enable(NVIC_USB_LP_CAN_RX0); - USBLIB->state = USB_UNCONNECTED; -} - -#define BTABLE_ADDRESS 0x00 -static void usbReset(void) { - pInformation->Current_Configuration = 0; - - /* current feature is current bmAttributes */ - pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED | - USB_CONFIG_ATTR_SELF_POWERED); - - USB_BASE->BTABLE = BTABLE_ADDRESS; - - /* setup control endpoint 0 */ - usb_set_ep_type(USB_EP0, USB_EP_EP_TYPE_CONTROL); - usb_set_ep_tx_stat(USB_EP0, USB_EP_STAT_TX_STALL); - usb_set_ep_rx_addr(USB_EP0, USB_CDCACM_CTRL_RX_ADDR); - usb_set_ep_tx_addr(USB_EP0, USB_CDCACM_CTRL_TX_ADDR); - usb_clear_status_out(USB_EP0); - - usb_set_ep_rx_count(USB_EP0, pProperty->MaxPacketSize); - usb_set_ep_rx_stat(USB_EP0, USB_EP_STAT_RX_VALID); - - /* setup management endpoint 1 */ - usb_set_ep_type(USB_CDCACM_MANAGEMENT_ENDP, USB_EP_EP_TYPE_INTERRUPT); - usb_set_ep_tx_addr(USB_CDCACM_MANAGEMENT_ENDP, - USB_CDCACM_MANAGEMENT_ADDR); - usb_set_ep_tx_stat(USB_CDCACM_MANAGEMENT_ENDP, USB_EP_STAT_TX_NAK); - usb_set_ep_rx_stat(USB_CDCACM_MANAGEMENT_ENDP, USB_EP_STAT_RX_DISABLED); - - /* TODO figure out differences in style between RX/TX EP setup */ - - /* set up data endpoint OUT (RX) */ - usb_set_ep_type(USB_CDCACM_RX_ENDP, USB_EP_EP_TYPE_BULK); - usb_set_ep_rx_addr(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_ADDR); - usb_set_ep_rx_count(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_EPSIZE); - usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID); - - /* set up data endpoint IN (TX) */ - usb_set_ep_type(USB_CDCACM_TX_ENDP, USB_EP_EP_TYPE_BULK); - usb_set_ep_tx_addr(USB_CDCACM_TX_ENDP, USB_CDCACM_TX_ADDR); - usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_NAK); - usb_set_ep_rx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_RX_DISABLED); - - USBLIB->state = USB_ATTACHED; - SetDeviceAddress(0); - - /* Reset the RX/TX state */ - n_unread_bytes = 0; - n_unsent_bytes = 0; - rx_offset = 0; -} - -static RESULT usbDataSetup(uint8 request) { - uint8* (*CopyRoutine)(uint16) = 0; - - if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { - switch (request) { - case USB_CDCACM_GET_LINE_CODING: - CopyRoutine = vcomGetSetLineCoding; - break; - case USB_CDCACM_SET_LINE_CODING: - CopyRoutine = vcomGetSetLineCoding; - break; - default: - break; - } - - /* Call the user hook. */ - if (iface_setup_hook) { - uint8 req_copy = request; - iface_setup_hook(USB_CDCACM_HOOK_IFACE_SETUP, &req_copy); - } - } - - if (CopyRoutine == NULL) { - return USB_UNSUPPORT; - } - - pInformation->Ctrl_Info.CopyData = CopyRoutine; - pInformation->Ctrl_Info.Usb_wOffset = 0; - (*CopyRoutine)(0); - return USB_SUCCESS; -} - -static RESULT usbNoDataSetup(uint8 request) { - RESULT ret = USB_UNSUPPORT; - - if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { - switch (request) { - case USB_CDCACM_SET_COMM_FEATURE: - /* We support set comm. feature, but don't handle it. */ - ret = USB_SUCCESS; - break; - case USB_CDCACM_SET_CONTROL_LINE_STATE: - /* Track changes to DTR and RTS. */ - line_dtr_rts = (pInformation->USBwValues.bw.bb0 & - (USB_CDCACM_CONTROL_LINE_DTR | - USB_CDCACM_CONTROL_LINE_RTS)); - ret = USB_SUCCESS; - break; - } - - /* Call the user hook. */ - if (iface_setup_hook) { - uint8 req_copy = request; - iface_setup_hook(USB_CDCACM_HOOK_IFACE_SETUP, &req_copy); - } - } - return ret; -} - -static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) { - if (alt_setting > 0) { - return USB_UNSUPPORT; - } else if (interface > 1) { - return USB_UNSUPPORT; - } - - return USB_SUCCESS; -} - -static uint8* usbGetDeviceDescriptor(uint16 length) { - return Standard_GetDescriptorData(length, &Device_Descriptor); -} - -static uint8* usbGetConfigDescriptor(uint16 length) { - return Standard_GetDescriptorData(length, &Config_Descriptor); -} - -static uint8* usbGetStringDescriptor(uint16 length) { - uint8 wValue0 = pInformation->USBwValue0; - - if (wValue0 > N_STRING_DESCRIPTORS) { - return NULL; - } - return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]); -} - -static void usbSetConfiguration(void) { - if (pInformation->Current_Configuration != 0) { - USBLIB->state = USB_CONFIGURED; - } -} - -static void usbSetDeviceAddress(void) { - USBLIB->state = USB_ADDRESSED; -} diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_core.c b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_core.c deleted file mode 100644 index 5cf9e8745..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_core.c +++ /dev/null @@ -1,1013 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_core.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Standard protocol processing (USB v2.0) -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define ValBit(VAR,Place) (VAR & (1 << Place)) -#define SetBit(VAR,Place) (VAR |= (1 << Place)) -#define ClrBit(VAR,Place) (VAR &= ((1 << Place) ^ 255)) - -#define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \ - vSetEPTxStatus(EP_TX_VALID); \ - } - -#define vSetEPRxStatus(st) (SaveRState = st) -#define vSetEPTxStatus(st) (SaveTState = st) - -#define USB_StatusIn() Send0LengthData() -#define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID) - -#define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */ -#define StatusInfo1 StatusInfo.bw.bb0 - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -u16_u8 StatusInfo; -USB_Bool Data_Mul_MaxPacketSize = FALSE; -/* Private function prototypes -----------------------------------------------*/ -static void DataStageOut(void); -static void DataStageIn(void); -static void NoData_Setup0(void); -static void Data_Setup0(void); -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : Standard_GetConfiguration. -* Description : Return the current configuration variable address. -* Input : Length - How many bytes are needed. -* Output : None. -* Return : Return 1 , if the request is invalid when "Length" is 0. -* Return "Buffer" if the "Length" is not 0. -*******************************************************************************/ -u8 *Standard_GetConfiguration(u16 Length) -{ - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = - sizeof(pInformation->Current_Configuration); - return 0; - } - pUser_Standard_Requests->User_GetConfiguration(); - return (u8 *)&pInformation->Current_Configuration; -} - -/******************************************************************************* -* Function Name : Standard_SetConfiguration. -* Description : This routine is called to set the configuration value -* Then each class should configure device themself. -* Input : None. -* Output : None. -* Return : Return USB_SUCCESS, if the request is performed. -* Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetConfiguration(void) -{ - - if ((pInformation->USBwValue0 <= - Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0) - && (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/ - { - pInformation->Current_Configuration = pInformation->USBwValue0; - pUser_Standard_Requests->User_SetConfiguration(); - return USB_SUCCESS; - } - else - { - return USB_UNSUPPORT; - } -} - -/******************************************************************************* -* Function Name : Standard_GetInterface. -* Description : Return the Alternate Setting of the current interface. -* Input : Length - How many bytes are needed. -* Output : None. -* Return : Return 0, if the request is invalid when "Length" is 0. -* Return "Buffer" if the "Length" is not 0. -*******************************************************************************/ -u8 *Standard_GetInterface(u16 Length) -{ - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = - sizeof(pInformation->Current_AlternateSetting); - return 0; - } - pUser_Standard_Requests->User_GetInterface(); - return (u8 *)&pInformation->Current_AlternateSetting; -} - -/******************************************************************************* -* Function Name : Standard_SetInterface. -* Description : This routine is called to set the interface. -* Then each class should configure the interface them self. -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetInterface(void) -{ - RESULT Re; - /*Test if the specified Interface and Alternate Setting are supported by - the application Firmware*/ - Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0); - - if (pInformation->Current_Configuration != 0) - { - if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0) - || (pInformation->USBwValue1 != 0)) - { - return USB_UNSUPPORT; - } - else if (Re == USB_SUCCESS) - { - pUser_Standard_Requests->User_SetInterface(); - pInformation->Current_Interface = pInformation->USBwIndex0; - pInformation->Current_AlternateSetting = pInformation->USBwValue0; - return USB_SUCCESS; - } - - } - - return USB_UNSUPPORT; -} - -/******************************************************************************* -* Function Name : Standard_GetStatus. -* Description : Copy the device request data to "StatusInfo buffer". -* Input : - Length - How many bytes are needed. -* Output : None. -* Return : Return 0, if the request is at end of data block, -* or is invalid when "Length" is 0. -*******************************************************************************/ -u8 *Standard_GetStatus(u16 Length) -{ - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = 2; - return 0; - } - - StatusInfo.w = 0; - /* Reset Status Information */ - - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - /*Get Device Status */ - u8 Feature = pInformation->Current_Feature; - - /* Remote Wakeup enabled */ - if (ValBit(Feature, 5)) - { - SetBit(StatusInfo0, 1); - } - - /* Bus-powered */ - if (ValBit(Feature, 6)) - { - ClrBit(StatusInfo0, 0); - } - else /* Self-powered */ - { - SetBit(StatusInfo0, 0); - } - } - /*Interface Status*/ - else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - { - return (u8 *)&StatusInfo; - } - /*Get EndPoint Status*/ - else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - { - u8 Related_Endpoint; - u8 wIndex0 = pInformation->USBwIndex0; - - Related_Endpoint = (wIndex0 & 0x0f); - if (ValBit(wIndex0, 7)) - { - /* IN endpoint */ - if (_GetTxStallStatus(Related_Endpoint)) - { - SetBit(StatusInfo0, 0); /* IN Endpoint stalled */ - } - } - else - { - /* OUT endpoint */ - if (_GetRxStallStatus(Related_Endpoint)) - { - SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */ - } - } - - } - else - { - return NULL; - } - pUser_Standard_Requests->User_GetStatus(); - return (u8 *)&StatusInfo; -} - -/******************************************************************************* -* Function Name : Standard_ClearFeature. -* Description : Clear or disable a specific feature. -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_ClearFeature(void) -{ - u32 Type_Rec = Type_Recipient; - u32 Status; - - - if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - {/*Device Clear Feature*/ - ClrBit(pInformation->Current_Feature, 5); - return USB_SUCCESS; - } - else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - {/*EndPoint Clear Feature*/ - DEVICE* pDev; - u32 Related_Endpoint; - u32 wIndex0; - u32 rEP; - - if ((pInformation->USBwValue != ENDPOINT_STALL) - || (pInformation->USBwIndex1 != 0)) - { - return USB_UNSUPPORT; - } - - pDev = &Device_Table; - wIndex0 = pInformation->USBwIndex0; - rEP = wIndex0 & ~0x80; - Related_Endpoint = ENDP0 + rEP; - - if (ValBit(pInformation->USBwIndex0, 7)) - { - /*Get Status of endpoint & stall the request if the related_ENdpoint - is Disabled*/ - Status = _GetEPTxStatus(Related_Endpoint); - } - else - { - Status = _GetEPRxStatus(Related_Endpoint); - } - - if ((rEP >= pDev->Total_Endpoint) || (Status == 0) - || (pInformation->Current_Configuration == 0)) - { - return USB_UNSUPPORT; - } - - - if (wIndex0 & 0x80) - { - /* IN endpoint */ - if (_GetTxStallStatus(Related_Endpoint )) - { - ClearDTOG_TX(Related_Endpoint); - SetEPTxStatus(Related_Endpoint, EP_TX_VALID); - } - } - else - { - /* OUT endpoint */ - if (_GetRxStallStatus(Related_Endpoint)) - { - if (Related_Endpoint == ENDP0) - { - /* After clear the STALL, enable the default endpoint receiver */ - SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize); - _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); - } - else - { - ClearDTOG_RX(Related_Endpoint); - _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); - } - } - } - pUser_Standard_Requests->User_ClearFeature(); - return USB_SUCCESS; - } - - return USB_UNSUPPORT; -} - -/******************************************************************************* -* Function Name : Standard_SetEndPointFeature -* Description : Set or enable a specific feature of EndPoint -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetEndPointFeature(void) -{ - u32 wIndex0; - u32 Related_Endpoint; - u32 rEP; - u32 Status; - - wIndex0 = pInformation->USBwIndex0; - rEP = wIndex0 & ~0x80; - Related_Endpoint = ENDP0 + rEP; - - if (ValBit(pInformation->USBwIndex0, 7)) - { - /* get Status of endpoint & stall the request if the related_ENdpoint - is Disabled*/ - Status = _GetEPTxStatus(Related_Endpoint); - } - else - { - Status = _GetEPRxStatus(Related_Endpoint); - } - - if (Related_Endpoint >= Device_Table.Total_Endpoint - || pInformation->USBwValue != 0 || Status == 0 - || pInformation->Current_Configuration == 0) - { - return USB_UNSUPPORT; - } - else - { - if (wIndex0 & 0x80) - { - /* IN endpoint */ - _SetEPTxStatus(Related_Endpoint, EP_TX_STALL); - } - - else - { - /* OUT endpoint */ - _SetEPRxStatus(Related_Endpoint, EP_RX_STALL); - } - } - pUser_Standard_Requests->User_SetEndPointFeature(); - return USB_SUCCESS; -} - -/******************************************************************************* -* Function Name : Standard_SetDeviceFeature. -* Description : Set or enable a specific feature of Device. -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetDeviceFeature(void) -{ - SetBit(pInformation->Current_Feature, 5); - pUser_Standard_Requests->User_SetDeviceFeature(); - return USB_SUCCESS; -} - -/******************************************************************************* -* Function Name : Standard_GetDescriptorData. -* Description : Standard_GetDescriptorData is used for descriptors transfer. -* : This routine is used for the descriptors resident in Flash -* or RAM -* pDesc can be in either Flash or RAM -* The purpose of this routine is to have a versatile way to -* response descriptors request. It allows user to generate -* certain descriptors with software or read descriptors from -* external storage part by part. -* Input : - Length - Length of the data in this transfer. -* - pDesc - A pointer points to descriptor struct. -* The structure gives the initial address of the descriptor and -* its original size. -* Output : None. -* Return : Address of a part of the descriptor pointed by the Usb_ -* wOffset The buffer pointed by this address contains at least -* Length bytes. -*******************************************************************************/ -u8 *Standard_GetDescriptorData(u16 Length, ONE_DESCRIPTOR *pDesc) -{ - u32 wOffset; - - wOffset = pInformation->Ctrl_Info.Usb_wOffset; - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset; - return 0; - } - - return pDesc->Descriptor + wOffset; -} - -/******************************************************************************* -* Function Name : DataStageOut. -* Description : Data stage of a Control Write Transfer. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void DataStageOut(void) -{ - ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; - u32 save_rLength; - - save_rLength = pEPinfo->Usb_rLength; - - if (pEPinfo->CopyData && save_rLength) - { - u8 *Buffer; - u32 Length; - - Length = pEPinfo->PacketSize; - if (Length > save_rLength) - { - Length = save_rLength; - } - - Buffer = (*pEPinfo->CopyData)(Length); - pEPinfo->Usb_rLength -= Length; - pEPinfo->Usb_rOffset += Length; - - PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); - } - - if (pEPinfo->Usb_rLength != 0) - { - vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */ - SetEPTxCount(ENDP0, 0); - vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */ - } - /* Set the next State*/ - if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) - { - pInformation->ControlState = OUT_DATA; - } - else - { - if (pEPinfo->Usb_rLength > 0) - { - pInformation->ControlState = LAST_OUT_DATA; - } - else if (pEPinfo->Usb_rLength == 0) - { - pInformation->ControlState = WAIT_STATUS_IN; - USB_StatusIn(); - } - } -} - -/******************************************************************************* -* Function Name : DataStageIn. -* Description : Data stage of a Control Read Transfer. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void DataStageIn(void) -{ - ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; - u32 save_wLength = pEPinfo->Usb_wLength; - u32 ControlState = pInformation->ControlState; - - u8 *DataBuffer; - u32 Length; - - if ((save_wLength == 0) && (ControlState == LAST_IN_DATA)) - { - if(Data_Mul_MaxPacketSize == TRUE) - { - /* No more data to send and empty packet */ - Send0LengthData(); - ControlState = LAST_IN_DATA; - Data_Mul_MaxPacketSize = FALSE; - } - else - { - /* No more data to send so STALL the TX Status*/ - ControlState = WAIT_STATUS_OUT; - vSetEPTxStatus(EP_TX_STALL); - } - - goto Expect_Status_Out; - } - - Length = pEPinfo->PacketSize; - ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA; - - if (Length > save_wLength) - { - Length = save_wLength; - } - - DataBuffer = (*pEPinfo->CopyData)(Length); - - UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length); - - SetEPTxCount(ENDP0, Length); - - pEPinfo->Usb_wLength -= Length; - pEPinfo->Usb_wOffset += Length; - vSetEPTxStatus(EP_TX_VALID); - - USB_StatusOut();/* Expect the host to abort the data IN stage */ - -Expect_Status_Out: - pInformation->ControlState = ControlState; -} - -/******************************************************************************* -* Function Name : NoData_Setup0. -* Description : Proceed the processing of setup request without data stage. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void NoData_Setup0(void) -{ - RESULT Result = USB_UNSUPPORT; - u32 RequestNo = pInformation->USBbRequest; - u32 ControlState; - - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - /* Device Request*/ - /* SET_CONFIGURATION*/ - if (RequestNo == SET_CONFIGURATION) - { - Result = Standard_SetConfiguration(); - } - - /*SET ADDRESS*/ - else if (RequestNo == SET_ADDRESS) - { - if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0) - || (pInformation->USBwIndex != 0) - || (pInformation->Current_Configuration != 0)) - /* Device Address should be 127 or less*/ - { - ControlState = STALLED; - goto exit_NoData_Setup0; - } - else - { - Result = USB_SUCCESS; - } - } - /*SET FEATURE for Device*/ - else if (RequestNo == SET_FEATURE) - { - if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP) - && (pInformation->USBwIndex == 0) - && (ValBit(pInformation->Current_Feature, 5))) - { - Result = Standard_SetDeviceFeature(); - } - else - { - Result = USB_UNSUPPORT; - } - } - /*Clear FEATURE for Device */ - else if (RequestNo == CLEAR_FEATURE) - { - if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP - && pInformation->USBwIndex == 0 - && ValBit(pInformation->Current_Feature, 5)) - { - Result = Standard_ClearFeature(); - } - else - { - Result = USB_UNSUPPORT; - } - } - - } - - /* Interface Request*/ - else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - { - /*SET INTERFACE*/ - if (RequestNo == SET_INTERFACE) - { - Result = Standard_SetInterface(); - } - } - - /* EndPoint Request*/ - else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - { - /*CLEAR FEATURE for EndPoint*/ - if (RequestNo == CLEAR_FEATURE) - { - Result = Standard_ClearFeature(); - } - /* SET FEATURE for EndPoint*/ - else if (RequestNo == SET_FEATURE) - { - Result = Standard_SetEndPointFeature(); - } - } - else - { - Result = USB_UNSUPPORT; - } - - - if (Result != USB_SUCCESS) - { - Result = (*pProperty->Class_NoData_Setup)(RequestNo); - if (Result == USB_NOT_READY) - { - ControlState = PAUSE; - goto exit_NoData_Setup0; - } - } - - if (Result != USB_SUCCESS) - { - ControlState = STALLED; - goto exit_NoData_Setup0; - } - - ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */ - - USB_StatusIn(); - -exit_NoData_Setup0: - pInformation->ControlState = ControlState; - return; -} - -/******************************************************************************* -* Function Name : Data_Setup0. -* Description : Proceed the processing of setup request with data stage. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void Data_Setup0(void) -{ - u8 *(*CopyRoutine)(u16); - RESULT Result; - u32 Request_No = pInformation->USBbRequest; - - u32 Related_Endpoint, Reserved; - u32 wOffset, Status; - - - - CopyRoutine = NULL; - wOffset = 0; - - if (Request_No == GET_DESCRIPTOR) - { - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - u8 wValue1 = pInformation->USBwValue1; - if (wValue1 == DEVICE_DESCRIPTOR) - { - CopyRoutine = pProperty->GetDeviceDescriptor; - } - else if (wValue1 == CONFIG_DESCRIPTOR) - { - CopyRoutine = pProperty->GetConfigDescriptor; - } - else if (wValue1 == STRING_DESCRIPTOR) - { - CopyRoutine = pProperty->GetStringDescriptor; - } /* End of GET_DESCRIPTOR */ - } - } - - /*GET STATUS*/ - else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0) - && (pInformation->USBwLength == 0x0002) - && (pInformation->USBwIndex1 == 0)) - { - /* GET STATUS for Device*/ - if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - && (pInformation->USBwIndex == 0)) - { - CopyRoutine = Standard_GetStatus; - } - - /* GET STATUS for Interface*/ - else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - { - if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS) - && (pInformation->Current_Configuration != 0)) - { - CopyRoutine = Standard_GetStatus; - } - } - - /* GET STATUS for EndPoint*/ - else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - { - Related_Endpoint = (pInformation->USBwIndex0 & 0x0f); - Reserved = pInformation->USBwIndex0 & 0x70; - - if (ValBit(pInformation->USBwIndex0, 7)) - { - /*Get Status of endpoint & stall the request if the related_ENdpoint - is Disabled*/ - Status = _GetEPTxStatus(Related_Endpoint); - } - else - { - Status = _GetEPRxStatus(Related_Endpoint); - } - - if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0) - && (Status != 0)) - { - CopyRoutine = Standard_GetStatus; - } - } - - } - - /*GET CONFIGURATION*/ - else if (Request_No == GET_CONFIGURATION) - { - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - CopyRoutine = Standard_GetConfiguration; - } - } - /*GET INTERFACE*/ - else if (Request_No == GET_INTERFACE) - { - if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0) - && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001) - && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)) - { - CopyRoutine = Standard_GetInterface; - } - - } - - if (CopyRoutine) - { - pInformation->Ctrl_Info.Usb_wOffset = wOffset; - pInformation->Ctrl_Info.CopyData = CopyRoutine; - /* sb in the original the cast to word was directly */ - /* now the cast is made step by step */ - (*CopyRoutine)(0); - Result = USB_SUCCESS; - } - else - { - Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest); - if (Result == USB_NOT_READY) - { - pInformation->ControlState = PAUSE; - return; - } - } - - if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF) - { - /* Data is not ready, wait it */ - pInformation->ControlState = PAUSE; - return; - } - if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0)) - { - /* Unsupported request */ - pInformation->ControlState = STALLED; - return; - } - - - if (ValBit(pInformation->USBbmRequestType, 7)) - { - /* Device ==> Host */ - vu32 wLength = pInformation->USBwLength; - - /* Restrict the data length to be the one host asks */ - if (pInformation->Ctrl_Info.Usb_wLength > wLength) - { - pInformation->Ctrl_Info.Usb_wLength = wLength; - } - - else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength) - { - if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize) - { - Data_Mul_MaxPacketSize = FALSE; - } - else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0) - { - Data_Mul_MaxPacketSize = TRUE; - } - } - - pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize; - DataStageIn(); - } - else - { - pInformation->ControlState = OUT_DATA; - vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */ - } - - return; -} - -/******************************************************************************* -* Function Name : Setup0_Process -* Description : Get the device request data and dispatch to individual process. -* Input : None. -* Output : None. -* Return : Post0_Process. -*******************************************************************************/ -u8 Setup0_Process(void) -{ - - union - { - u8* b; - u16* w; - } pBuf; - - pBuf.b = PMAAddr + (u8 *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */ - - if (pInformation->ControlState != PAUSE) - { - pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */ - pInformation->USBbRequest = *pBuf.b++; /* bRequest */ - pBuf.w++; /* word not accessed because of 32 bits addressing */ - pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */ - pBuf.w++; /* word not accessed because of 32 bits addressing */ - pInformation->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */ - pBuf.w++; /* word not accessed because of 32 bits addressing */ - pInformation->USBwLength = *pBuf.w; /* wLength */ - } - - pInformation->ControlState = SETTING_UP; - if (pInformation->USBwLength == 0) - { - /* Setup with no data stage */ - NoData_Setup0(); - } - else - { - /* Setup with data stage */ - Data_Setup0(); - } - return Post0_Process(); -} - -/******************************************************************************* -* Function Name : In0_Process -* Description : Process the IN token on all default endpoint. -* Input : None. -* Output : None. -* Return : Post0_Process. -*******************************************************************************/ -u8 In0_Process(void) -{ - u32 ControlState = pInformation->ControlState; - - if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) - { - DataStageIn(); - /* ControlState may be changed outside the function */ - ControlState = pInformation->ControlState; - } - - else if (ControlState == WAIT_STATUS_IN) - { - if ((pInformation->USBbRequest == SET_ADDRESS) && - (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))) - { - SetDeviceAddress(pInformation->USBwValue0); - pUser_Standard_Requests->User_SetDeviceAddress(); - } - (*pProperty->Process_Status_IN)(); - ControlState = STALLED; - } - - else - { - ControlState = STALLED; - } - - pInformation->ControlState = ControlState; - - return Post0_Process(); -} - -/******************************************************************************* -* Function Name : Out0_Process -* Description : Process the OUT token on all default endpoint. -* Input : None. -* Output : None. -* Return : Post0_Process. -*******************************************************************************/ -u8 Out0_Process(void) -{ - u32 ControlState = pInformation->ControlState; - - if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA)) - { - DataStageOut(); - ControlState = pInformation->ControlState; /* may be changed outside the function */ - } - - else if (ControlState == WAIT_STATUS_OUT) - { - (*pProperty->Process_Status_OUT)(); - ControlState = STALLED; - } - - else if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) - { - /* host aborts the transfer before finish */ - ControlState = STALLED; - } - - /* Unexpect state, STALL the endpoint */ - else - { - ControlState = STALLED; - } - - pInformation->ControlState = ControlState; - - return Post0_Process(); -} - -/******************************************************************************* -* Function Name : Post0_Process -* Description : Stall the Endpoint 0 in case of error. -* Input : None. -* Output : None. -* Return : - 0 if the control State is in PAUSE -* - 1 if not. -*******************************************************************************/ -u8 Post0_Process(void) -{ - SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); - - if (pInformation->ControlState == STALLED) - { - vSetEPRxStatus(EP_RX_STALL); - vSetEPTxStatus(EP_TX_STALL); - } - - return (pInformation->ControlState == PAUSE); -} - -/******************************************************************************* -* Function Name : SetDeviceAddress. -* Description : Set the device and all the used Endpoints addresses. -* Input : - Val: device adress. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetDeviceAddress(u8 Val) -{ - u32 i; - u32 nEP = Device_Table.Total_Endpoint; - - /* set address in every used endpoint */ - for (i = 0; i < nEP; i++) - { - _SetEPAddress((u8)i, (u8)i); - } /* for */ - _SetDADDR(Val | DADDR_EF); /* set device address and enable function */ -} - -/******************************************************************************* -* Function Name : NOP_Process -* Description : No operation function. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void NOP_Process(void) -{ -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_core.h b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_core.h deleted file mode 100644 index fa29a183b..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_core.h +++ /dev/null @@ -1,251 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_core.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Standard protocol processing functions prototypes -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CORE_H -#define __USB_CORE_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -typedef enum _CONTROL_STATE -{ - WAIT_SETUP, /* 0 */ - SETTING_UP, /* 1 */ - IN_DATA, /* 2 */ - OUT_DATA, /* 3 */ - LAST_IN_DATA, /* 4 */ - LAST_OUT_DATA, /* 5 */ - WAIT_STATUS_IN, /* 7 */ - WAIT_STATUS_OUT, /* 8 */ - STALLED, /* 9 */ - PAUSE /* 10 */ -} CONTROL_STATE; /* The state machine states of a control pipe */ - -typedef struct OneDescriptor -{ - u8 *Descriptor; - u16 Descriptor_Size; -} -ONE_DESCRIPTOR, *PONE_DESCRIPTOR; -/* All the request process routines return a value of this type - If the return value is not SUCCESS or NOT_READY, - the software will STALL the correspond endpoint */ -typedef enum _RESULT -{ - USB_SUCCESS = 0, /* Process sucessfully */ - USB_ERROR, - USB_UNSUPPORT, - USB_NOT_READY /* The process has not been finished, endpoint will be - NAK to further rquest */ -} RESULT; - - -/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/ -typedef struct _ENDPOINT_INFO -{ - /* When send data out of the device, - CopyData() is used to get data buffer 'Length' bytes data - if Length is 0, - CopyData() returns the total length of the data - if the request is not supported, returns 0 - (NEW Feature ) - if CopyData() returns -1, the calling routine should not proceed - further and will resume the SETUP process by the class device - if Length is not 0, - CopyData() returns a pointer to indicate the data location - Usb_wLength is the data remain to be sent, - Usb_wOffset is the Offset of original data - When receive data from the host, - CopyData() is used to get user data buffer which is capable - of Length bytes data to copy data from the endpoint buffer. - if Length is 0, - CopyData() returns the available data length, - if Length is not 0, - CopyData() returns user buffer address - Usb_rLength is the data remain to be received, - Usb_rPointer is the Offset of data buffer - */ - u16 Usb_wLength; - u16 Usb_wOffset; - u16 PacketSize; - u8 *(*CopyData)(u16 Length); -}ENDPOINT_INFO; - -/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/ - -typedef struct _DEVICE -{ - u8 Total_Endpoint; /* Number of endpoints that are used */ - u8 Total_Configuration;/* Number of configuration available */ -} -DEVICE; - -typedef union -{ - u16 w; - struct BW - { - u8 bb1; - u8 bb0; - } - bw; -} u16_u8; - -typedef struct _DEVICE_INFO -{ - u8 USBbmRequestType; /* bmRequestType */ - u8 USBbRequest; /* bRequest */ - u16_u8 USBwValues; /* wValue */ - u16_u8 USBwIndexs; /* wIndex */ - u16_u8 USBwLengths; /* wLength */ - - u8 ControlState; /* of type CONTROL_STATE */ - u8 Current_Feature; - u8 Current_Configuration; /* Selected configuration */ - u8 Current_Interface; /* Selected interface of current configuration */ - u8 Current_AlternateSetting;/* Selected Alternate Setting of current - interface*/ - - ENDPOINT_INFO Ctrl_Info; -}DEVICE_INFO; - -typedef struct _DEVICE_PROP -{ - void (*Init)(void); /* Initialize the device */ - void (*Reset)(void); /* Reset routine of this device */ - - /* Device dependent process after the status stage */ - void (*Process_Status_IN)(void); - void (*Process_Status_OUT)(void); - - /* Procedure of process on setup stage of a class specified request with data stage */ - /* All class specified requests with data stage are processed in Class_Data_Setup - Class_Data_Setup() - responses to check all special requests and fills ENDPOINT_INFO - according to the request - If IN tokens are expected, then wLength & wOffset will be filled - with the total transferring bytes and the starting position - If OUT tokens are expected, then rLength & rOffset will be filled - with the total expected bytes and the starting position in the buffer - - If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT - - CAUTION: - Since GET_CONFIGURATION & GET_INTERFACE are highly related to - the individual classes, they will be checked and processed here. - */ - RESULT (*Class_Data_Setup)(u8 RequestNo); - - /* Procedure of process on setup stage of a class specified request without data stage */ - /* All class specified requests without data stage are processed in Class_NoData_Setup - Class_NoData_Setup - responses to check all special requests and perform the request - - CAUTION: - Since SET_CONFIGURATION & SET_INTERFACE are highly related to - the individual classes, they will be checked and processed here. - */ - RESULT (*Class_NoData_Setup)(u8 RequestNo); - - /*Class_Get_Interface_Setting - This function is used by the file usb_core.c to test if the selected Interface - and Alternate Setting (u8 Interface, u8 AlternateSetting) are supported by - the application. - This function is writing by user. It should return "SUCCESS" if the Interface - and Alternate Setting are supported by the application or "UNSUPPORT" if they - are not supported. */ - - RESULT (*Class_Get_Interface_Setting)(u8 Interface, u8 AlternateSetting); - - u8* (*GetDeviceDescriptor)(u16 Length); - u8* (*GetConfigDescriptor)(u16 Length); - u8* (*GetStringDescriptor)(u16 Length); - - u8* RxEP_buffer; - u8 MaxPacketSize; - -}DEVICE_PROP; - -typedef struct _USER_STANDARD_REQUESTS -{ - void (*User_GetConfiguration)(void); /* Get Configuration */ - void (*User_SetConfiguration)(void); /* Set Configuration */ - void (*User_GetInterface)(void); /* Get Interface */ - void (*User_SetInterface)(void); /* Set Interface */ - void (*User_GetStatus)(void); /* Get Status */ - void (*User_ClearFeature)(void); /* Clear Feature */ - void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */ - void (*User_SetDeviceFeature)(void); /* Set Device Feature */ - void (*User_SetDeviceAddress)(void); /* Set Device Address */ -} -USER_STANDARD_REQUESTS; - -/* Exported constants --------------------------------------------------------*/ -#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) - -#define Usb_rLength Usb_wLength -#define Usb_rOffset Usb_wOffset - -#define USBwValue USBwValues.w -#define USBwValue0 USBwValues.bw.bb0 -#define USBwValue1 USBwValues.bw.bb1 -#define USBwIndex USBwIndexs.w -#define USBwIndex0 USBwIndexs.bw.bb0 -#define USBwIndex1 USBwIndexs.bw.bb1 -#define USBwLength USBwLengths.w -#define USBwLength0 USBwLengths.bw.bb0 -#define USBwLength1 USBwLengths.bw.bb1 - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -u8 Setup0_Process(void); -u8 Post0_Process(void); -u8 Out0_Process(void); -u8 In0_Process(void); - -RESULT Standard_SetEndPointFeature(void); -RESULT Standard_SetDeviceFeature(void); - -u8 *Standard_GetConfiguration(u16 Length); -RESULT Standard_SetConfiguration(void); -u8 *Standard_GetInterface(u16 Length); -RESULT Standard_SetInterface(void); -u8 *Standard_GetDescriptorData(u16 Length, PONE_DESCRIPTOR pDesc); - -u8 *Standard_GetStatus(u16 Length); -RESULT Standard_ClearFeature(void); -void SetDeviceAddress(u8); -void NOP_Process(void); - -extern DEVICE_PROP Device_Property; -extern USER_STANDARD_REQUESTS User_Standard_Requests; -extern DEVICE Device_Table; -extern DEVICE_INFO Device_Info; - -/* cells saving status during interrupt servicing */ -extern u16 SaveRState; -extern u16 SaveTState; - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_CORE_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_def.h b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_def.h deleted file mode 100644 index 80aa3038c..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_def.h +++ /dev/null @@ -1,88 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_def.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Definitions related to USB Core -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_DEF_H -#define __USB_DEF_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -typedef enum _RECIPIENT_TYPE -{ - DEVICE_RECIPIENT, /* Recipient device */ - INTERFACE_RECIPIENT, /* Recipient interface */ - ENDPOINT_RECIPIENT, /* Recipient endpoint */ - OTHER_RECIPIENT -} RECIPIENT_TYPE; - - -typedef enum _STANDARD_REQUESTS -{ - GET_STATUS = 0, - CLEAR_FEATURE, - RESERVED1, - SET_FEATURE, - RESERVED2, - SET_ADDRESS, - GET_DESCRIPTOR, - SET_DESCRIPTOR, - GET_CONFIGURATION, - SET_CONFIGURATION, - GET_INTERFACE, - SET_INTERFACE, - TOTAL_sREQUEST, /* Total number of Standard request */ - SYNCH_FRAME = 12 -} STANDARD_REQUESTS; - -/* Definition of "USBwValue" */ -typedef enum _DESCRIPTOR_TYPE -{ - DEVICE_DESCRIPTOR = 1, - CONFIG_DESCRIPTOR, - STRING_DESCRIPTOR, - INTERFACE_DESCRIPTOR, - ENDPOINT_DESCRIPTOR -} DESCRIPTOR_TYPE; - -/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */ -typedef enum _FEATURE_SELECTOR -{ - ENDPOINT_STALL, - DEVICE_REMOTE_WAKEUP -} FEATURE_SELECTOR; - -/* Exported constants --------------------------------------------------------*/ -/* Definition of "USBbmRequestType" */ -#define REQUEST_TYPE 0x60 /* Mask to get request type */ -#define STANDARD_REQUEST 0x00 /* Standard request */ -#define CLASS_REQUEST 0x20 /* Class request */ -#define VENDOR_REQUEST 0x40 /* Vendor request */ - -#define RECIPIENT 0x1F /* Mask to get recipient */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_DEF_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_init.c b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_init.c deleted file mode 100644 index 94f3a836a..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_init.c +++ /dev/null @@ -1,64 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_init.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Initialization routines & global variables -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* The number of current endpoint, it will be used to specify an endpoint */ - u8 EPindex; -/* The number of current device, it is an index to the Device_Table */ -/* u8 Device_no; */ -/* Points to the DEVICE_INFO structure of current device */ -/* The purpose of this register is to speed up the execution */ -DEVICE_INFO *pInformation; -/* Points to the DEVICE_PROP structure of current device */ -/* The purpose of this register is to speed up the execution */ -DEVICE_PROP *pProperty; -/* Temporary save the state of Rx & Tx status. */ -/* Whenever the Rx or Tx state is changed, its value is saved */ -/* in this variable first and will be set to the EPRB or EPRA */ -/* at the end of interrupt process */ -u16 SaveState ; -u16 wInterrupt_Mask; -DEVICE_INFO Device_Info; -USER_STANDARD_REQUESTS *pUser_Standard_Requests; - -/* Extern variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : USB_Init -* Description : USB system initialization -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void USB_Init(void) -{ - pInformation = &Device_Info; - pInformation->ControlState = 2; - pProperty = &Device_Property; - pUser_Standard_Requests = &User_Standard_Requests; - /* Initialize devices one by one */ - - pProperty->Init(); -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_init.h b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_init.h deleted file mode 100644 index 80ee2fb32..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_init.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_init.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Initialization routines & global variables -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_INIT_H -#define __USB_INIT_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -void USB_Init(void); - -/* External variables --------------------------------------------------------*/ -/* The number of current endpoint, it will be used to specify an endpoint */ -extern u8 EPindex; -/* The number of current device, it is an index to the Device_Table */ -/*extern u8 Device_no; */ -/* Points to the DEVICE_INFO structure of current device */ -/* The purpose of this register is to speed up the execution */ -extern DEVICE_INFO* pInformation; -/* Points to the DEVICE_PROP structure of current device */ -/* The purpose of this register is to speed up the execution */ -extern DEVICE_PROP* pProperty; -/* Temporary save the state of Rx & Tx status. */ -/* Whenever the Rx or Tx state is changed, its value is saved */ -/* in this variable first and will be set to the EPRB or EPRA */ -/* at the end of interrupt process */ -extern USER_STANDARD_REQUESTS *pUser_Standard_Requests; - -extern u16 SaveState ; -extern u16 wInterrupt_Mask; - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_INIT_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_lib.h b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_lib.h deleted file mode 100644 index 85f94abdf..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_lib.h +++ /dev/null @@ -1,36 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_lib.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : USB library include files -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_LIB_H -#define __USB_LIB_H - -/* Includes ------------------------------------------------------------------*/ -#include "usb_type.h" -#include "usb_regs.h" -#include "usb_def.h" -#include "usb_core.h" -#include "usb_init.h" -#include "usb_mem.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -/* External variables --------------------------------------------------------*/ - -#endif /* __USB_LIB_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_mem.c b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_mem.c deleted file mode 100644 index ad9740a18..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_mem.c +++ /dev/null @@ -1,73 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_mem.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Utility functions for memory transfers to/from PMA -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Extern variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ -/******************************************************************************* -* Function Name : UserToPMABufferCopy -* Description : Copy a buffer from user memory area to packet memory area (PMA) -* Input : - pbUsrBuf: pointer to user memory area. -* - wPMABufAddr: address into PMA. -* - wNBytes: no. of bytes to be copied. -* Output : None. -* Return : None . -*******************************************************************************/ -void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) -{ - u32 n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */ - u32 i, temp1, temp2; - u16 *pdwVal; - pdwVal = (u16 *)(wPMABufAddr * 2 + PMAAddr); - for (i = n; i != 0; i--) - { - temp1 = (u16) * pbUsrBuf; - pbUsrBuf++; - temp2 = temp1 | (u16) * pbUsrBuf << 8; - *pdwVal++ = temp2; - pdwVal++; - pbUsrBuf++; - } -} -/******************************************************************************* -* Function Name : PMAToUserBufferCopy -* Description : Copy a buffer from user memory area to packet memory area (PMA) -* Input : - pbUsrBuf = pointer to user memory area. -* - wPMABufAddr = address into PMA. -* - wNBytes = no. of bytes to be copied. -* Output : None. -* Return : None. -*******************************************************************************/ -void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) -{ - u32 n = (wNBytes + 1) >> 1;/* /2*/ - u32 i; - u32 *pdwVal; - pdwVal = (u32 *)(wPMABufAddr * 2 + PMAAddr); - for (i = n; i != 0; i--) - { - *(u16*)pbUsrBuf++ = *pdwVal++; - pbUsrBuf++; - } -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_mem.h b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_mem.h deleted file mode 100644 index b0e0474a9..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_mem.h +++ /dev/null @@ -1,40 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_mem.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Utility prototypes functions for memory/PMA transfers -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_MEM_H -#define __USB_MEM_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -#if defined(__cplusplus) -extern "C" { -#endif - -void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); -void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); - -#if defined(__cplusplus) -} -#endif - -/* External variables --------------------------------------------------------*/ - -#endif /*__USB_MEM_H*/ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_regs.c b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_regs.c deleted file mode 100644 index c7e0276fe..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_regs.c +++ /dev/null @@ -1,748 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_regs.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Interface functions to USB cell registers -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Extern variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : SetCNTR. -* Description : Set the CNTR register value. -* Input : wRegValue: new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetCNTR(u16 wRegValue) -{ - _SetCNTR(wRegValue); -} - -/******************************************************************************* -* Function Name : GetCNTR. -* Description : returns the CNTR register value. -* Input : None. -* Output : None. -* Return : CNTR register Value. -*******************************************************************************/ -u16 GetCNTR(void) -{ - return(_GetCNTR()); -} - -/******************************************************************************* -* Function Name : SetISTR. -* Description : Set the ISTR register value. -* Input : wRegValue: new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetISTR(u16 wRegValue) -{ - _SetISTR(wRegValue); -} - -/******************************************************************************* -* Function Name : GetISTR -* Description : Returns the ISTR register value. -* Input : None. -* Output : None. -* Return : ISTR register Value -*******************************************************************************/ -u16 GetISTR(void) -{ - return(_GetISTR()); -} - -/******************************************************************************* -* Function Name : GetFNR -* Description : Returns the FNR register value. -* Input : None. -* Output : None. -* Return : FNR register Value -*******************************************************************************/ -u16 GetFNR(void) -{ - return(_GetFNR()); -} - -/******************************************************************************* -* Function Name : SetDADDR -* Description : Set the DADDR register value. -* Input : wRegValue: new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetDADDR(u16 wRegValue) -{ - _SetDADDR(wRegValue); -} - -/******************************************************************************* -* Function Name : GetDADDR -* Description : Returns the DADDR register value. -* Input : None. -* Output : None. -* Return : DADDR register Value -*******************************************************************************/ -u16 GetDADDR(void) -{ - return(_GetDADDR()); -} - -/******************************************************************************* -* Function Name : SetBTABLE -* Description : Set the BTABLE. -* Input : wRegValue: New register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetBTABLE(u16 wRegValue) -{ - _SetBTABLE(wRegValue); -} - -/******************************************************************************* -* Function Name : GetBTABLE. -* Description : Returns the BTABLE register value. -* Input : None. -* Output : None. -* Return : BTABLE address. -*******************************************************************************/ -u16 GetBTABLE(void) -{ - return(_GetBTABLE()); -} - -/******************************************************************************* -* Function Name : SetENDPOINT -* Description : Setthe Endpoint register value. -* Input : bEpNum: Endpoint Number. -* wRegValue. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetENDPOINT(u8 bEpNum, u16 wRegValue) -{ - _SetENDPOINT(bEpNum, wRegValue); -} - -/******************************************************************************* -* Function Name : GetENDPOINT -* Description : Return the Endpoint register value. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint register value. -*******************************************************************************/ -u16 GetENDPOINT(u8 bEpNum) -{ - return(_GetENDPOINT(bEpNum)); -} - -/******************************************************************************* -* Function Name : SetEPType -* Description : sets the type in the endpoint register. -* Input : bEpNum: Endpoint Number. -* wType: type definition. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPType(u8 bEpNum, u16 wType) -{ - _SetEPType(bEpNum, wType); -} - -/******************************************************************************* -* Function Name : GetEPType -* Description : Returns the endpoint type. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Type -*******************************************************************************/ -u16 GetEPType(u8 bEpNum) -{ - return(_GetEPType(bEpNum)); -} - -/******************************************************************************* -* Function Name : SetEPTxStatus -* Description : Set the status of Tx endpoint. -* Input : bEpNum: Endpoint Number. -* wState: new state. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxStatus(u8 bEpNum, u16 wState) -{ - _SetEPTxStatus(bEpNum, wState); -} - -/******************************************************************************* -* Function Name : SetEPRxStatus -* Description : Set the status of Rx endpoint. -* Input : bEpNum: Endpoint Number. -* wState: new state. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxStatus(u8 bEpNum, u16 wState) -{ - _SetEPRxStatus(bEpNum, wState); -} - -/******************************************************************************* -* Function Name : SetDouBleBuffEPStall -* Description : sets the status for Double Buffer Endpoint to STALL -* Input : bEpNum: Endpoint Number. -* bDir: Endpoint direction. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetDouBleBuffEPStall(u8 bEpNum, u8 bDir) -{ - u16 Endpoint_DTOG_Status; - Endpoint_DTOG_Status = GetENDPOINT(bEpNum); - if (bDir == EP_DBUF_OUT) - { /* OUT double buffered endpoint */ - _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1); - } - else if (bDir == EP_DBUF_IN) - { /* IN double buffered endpoint */ - _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1); - } -} - -/******************************************************************************* -* Function Name : GetEPTxStatus -* Description : Returns the endpoint Tx status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint TX Status -*******************************************************************************/ -u16 GetEPTxStatus(u8 bEpNum) -{ - return(_GetEPTxStatus(bEpNum)); -} - -/******************************************************************************* -* Function Name : GetEPRxStatus -* Description : Returns the endpoint Rx status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint RX Status -*******************************************************************************/ -u16 GetEPRxStatus(u8 bEpNum) -{ - return(_GetEPRxStatus(bEpNum)); -} - -/******************************************************************************* -* Function Name : SetEPTxValid -* Description : Valid the endpoint Tx Status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxValid(u8 bEpNum) -{ - _SetEPTxStatus(bEpNum, EP_TX_VALID); -} - -/******************************************************************************* -* Function Name : SetEPRxValid -* Description : Valid the endpoint Rx Status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxValid(u8 bEpNum) -{ - _SetEPRxStatus(bEpNum, EP_RX_VALID); -} - -/******************************************************************************* -* Function Name : SetEP_KIND -* Description : Clear the EP_KIND bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEP_KIND(u8 bEpNum) -{ - _SetEP_KIND(bEpNum); -} - -/******************************************************************************* -* Function Name : ClearEP_KIND -* Description : set the EP_KIND bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEP_KIND(u8 bEpNum) -{ - _ClearEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : Clear_Status_Out -* Description : Clear the Status Out of the related Endpoint -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void Clear_Status_Out(u8 bEpNum) -{ - _ClearEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : Set_Status_Out -* Description : Set the Status Out of the related Endpoint -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void Set_Status_Out(u8 bEpNum) -{ - _SetEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : SetEPDoubleBuff -* Description : Enable the double buffer feature for the endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDoubleBuff(u8 bEpNum) -{ - _SetEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : ClearEPDoubleBuff -* Description : Disable the double buffer feature for the endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEPDoubleBuff(u8 bEpNum) -{ - _ClearEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : GetTxStallStatus -* Description : Returns the Stall status of the Tx endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Tx Stall status. -*******************************************************************************/ -u16 GetTxStallStatus(u8 bEpNum) -{ - return(_GetTxStallStatus(bEpNum)); -} -/******************************************************************************* -* Function Name : GetRxStallStatus -* Description : Returns the Stall status of the Rx endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx Stall status. -*******************************************************************************/ -u16 GetRxStallStatus(u8 bEpNum) -{ - return(_GetRxStallStatus(bEpNum)); -} -/******************************************************************************* -* Function Name : ClearEP_CTR_RX -* Description : Clear the CTR_RX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEP_CTR_RX(u8 bEpNum) -{ - _ClearEP_CTR_RX(bEpNum); -} -/******************************************************************************* -* Function Name : ClearEP_CTR_TX -* Description : Clear the CTR_TX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEP_CTR_TX(u8 bEpNum) -{ - _ClearEP_CTR_TX(bEpNum); -} -/******************************************************************************* -* Function Name : ToggleDTOG_RX -* Description : Toggle the DTOG_RX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ToggleDTOG_RX(u8 bEpNum) -{ - _ToggleDTOG_RX(bEpNum); -} -/******************************************************************************* -* Function Name : ToggleDTOG_TX -* Description : Toggle the DTOG_TX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ToggleDTOG_TX(u8 bEpNum) -{ - _ToggleDTOG_TX(bEpNum); -} -/******************************************************************************* -* Function Name : ClearDTOG_RX. -* Description : Clear the DTOG_RX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearDTOG_RX(u8 bEpNum) -{ - _ClearDTOG_RX(bEpNum); -} -/******************************************************************************* -* Function Name : ClearDTOG_TX. -* Description : Clear the DTOG_TX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearDTOG_TX(u8 bEpNum) -{ - _ClearDTOG_TX(bEpNum); -} -/******************************************************************************* -* Function Name : SetEPAddress -* Description : Set the endpoint address. -* Input : bEpNum: Endpoint Number. -* bAddr: New endpoint address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPAddress(u8 bEpNum, u8 bAddr) -{ - _SetEPAddress(bEpNum, bAddr); -} -/******************************************************************************* -* Function Name : GetEPAddress -* Description : Get the endpoint address. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint address. -*******************************************************************************/ -u8 GetEPAddress(u8 bEpNum) -{ - return(_GetEPAddress(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPTxAddr -* Description : Set the endpoint Tx buffer address. -* Input : bEpNum: Endpoint Number. -* wAddr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxAddr(u8 bEpNum, u16 wAddr) -{ - _SetEPTxAddr(bEpNum, wAddr); -} -/******************************************************************************* -* Function Name : SetEPRxAddr -* Description : Set the endpoint Rx buffer address. -* Input : bEpNum: Endpoint Number. -* wAddr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxAddr(u8 bEpNum, u16 wAddr) -{ - _SetEPRxAddr(bEpNum, wAddr); -} -/******************************************************************************* -* Function Name : GetEPTxAddr -* Description : Returns the endpoint Tx buffer address. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx buffer address. -*******************************************************************************/ -u16 GetEPTxAddr(u8 bEpNum) -{ - return(_GetEPTxAddr(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPRxAddr. -* Description : Returns the endpoint Rx buffer address. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx buffer address. -*******************************************************************************/ -u16 GetEPRxAddr(u8 bEpNum) -{ - return(_GetEPRxAddr(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPTxCount. -* Description : Set the Tx count. -* Input : bEpNum: Endpoint Number. -* wCount: new count value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxCount(u8 bEpNum, u16 wCount) -{ - _SetEPTxCount(bEpNum, wCount); -} -/******************************************************************************* -* Function Name : SetEPCountRxReg. -* Description : Set the Count Rx Register value. -* Input : *pdwReg: point to the register. -* wCount: the new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPCountRxReg(u32 *pdwReg, u16 wCount) -{ - _SetEPCountRxReg(dwReg, wCount); -} -/******************************************************************************* -* Function Name : SetEPRxCount -* Description : Set the Rx count. -* Input : bEpNum: Endpoint Number. -* wCount: the new count value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxCount(u8 bEpNum, u16 wCount) -{ - _SetEPRxCount(bEpNum, wCount); -} -/******************************************************************************* -* Function Name : GetEPTxCount -* Description : Get the Tx count. -* Input : bEpNum: Endpoint Number. -* Output : None -* Return : Tx count value. -*******************************************************************************/ -u16 GetEPTxCount(u8 bEpNum) -{ - return(_GetEPTxCount(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPRxCount -* Description : Get the Rx count. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx count value. -*******************************************************************************/ -u16 GetEPRxCount(u8 bEpNum) -{ - return(_GetEPRxCount(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPDblBuffAddr -* Description : Set the addresses of the buffer 0 and 1. -* Input : bEpNum: Endpoint Number. -* wBuf0Addr: new address of buffer 0. -* wBuf1Addr: new address of buffer 1. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuffAddr(u8 bEpNum, u16 wBuf0Addr, u16 wBuf1Addr) -{ - _SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr); -} -/******************************************************************************* -* Function Name : SetEPDblBuf0Addr -* Description : Set the Buffer 1 address. -* Input : bEpNum: Endpoint Number -* wBuf0Addr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf0Addr(u8 bEpNum, u16 wBuf0Addr) -{ - _SetEPDblBuf0Addr(bEpNum, wBuf0Addr); -} -/******************************************************************************* -* Function Name : SetEPDblBuf1Addr -* Description : Set the Buffer 1 address. -* Input : bEpNum: Endpoint Number -* wBuf1Addr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf1Addr(u8 bEpNum, u16 wBuf1Addr) -{ - _SetEPDblBuf1Addr(bEpNum, wBuf1Addr); -} -/******************************************************************************* -* Function Name : GetEPDblBuf0Addr -* Description : Returns the address of the Buffer 0. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -u16 GetEPDblBuf0Addr(u8 bEpNum) -{ - return(_GetEPDblBuf0Addr(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPDblBuf1Addr -* Description : Returns the address of the Buffer 1. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Address of the Buffer 1. -*******************************************************************************/ -u16 GetEPDblBuf1Addr(u8 bEpNum) -{ - return(_GetEPDblBuf1Addr(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPDblBuffCount -* Description : Set the number of bytes for a double Buffer -* endpoint. -* Input : bEpNum,bDir, wCount -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuffCount(u8 bEpNum, u8 bDir, u16 wCount) -{ - _SetEPDblBuffCount(bEpNum, bDir, wCount); -} -/******************************************************************************* -* Function Name : SetEPDblBuf0Count -* Description : Set the number of bytes in the buffer 0 of a double Buffer -* endpoint. -* Input : bEpNum, bDir, wCount -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf0Count(u8 bEpNum, u8 bDir, u16 wCount) -{ - _SetEPDblBuf0Count(bEpNum, bDir, wCount); -} -/******************************************************************************* -* Function Name : SetEPDblBuf1Count -* Description : Set the number of bytes in the buffer 0 of a double Buffer -* endpoint. -* Input : bEpNum, bDir, wCount -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf1Count(u8 bEpNum, u8 bDir, u16 wCount) -{ - _SetEPDblBuf1Count(bEpNum, bDir, wCount); -} -/******************************************************************************* -* Function Name : GetEPDblBuf0Count -* Description : Returns the number of byte received in the buffer 0 of a double -* Buffer endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Buffer 0 count -*******************************************************************************/ -u16 GetEPDblBuf0Count(u8 bEpNum) -{ - return(_GetEPDblBuf0Count(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPDblBuf1Count -* Description : Returns the number of data received in the buffer 1 of a double -* Buffer endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Buffer 1 count. -*******************************************************************************/ -u16 GetEPDblBuf1Count(u8 bEpNum) -{ - return(_GetEPDblBuf1Count(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPDblBufDir -* Description : gets direction of the double buffered endpoint -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : EP_DBUF_OUT, EP_DBUF_IN, -* EP_DBUF_ERR if the endpoint counter not yet programmed. -*******************************************************************************/ -EP_DBUF_DIR GetEPDblBufDir(u8 bEpNum) -{ - if ((u16)(*_pEPRxCount(bEpNum) & 0xFC00) != 0) - return(EP_DBUF_OUT); - else if (((u16)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0) - return(EP_DBUF_IN); - else - return(EP_DBUF_ERR); -} -/******************************************************************************* -* Function Name : FreeUserBuffer -* Description : free buffer used from the application realizing it to the line - toggles bit SW_BUF in the double buffered endpoint register -* Input : bEpNum, bDir -* Output : None. -* Return : None. -*******************************************************************************/ -void FreeUserBuffer(u8 bEpNum, u8 bDir) -{ - if (bDir == EP_DBUF_OUT) - { /* OUT double buffered endpoint */ - _ToggleDTOG_TX(bEpNum); - } - else if (bDir == EP_DBUF_IN) - { /* IN double buffered endpoint */ - _ToggleDTOG_RX(bEpNum); - } -} - -/******************************************************************************* -* Function Name : ToWord -* Description : merge two byte in a word. -* Input : bh: byte high, bl: bytes low. -* Output : None. -* Return : resulted word. -*******************************************************************************/ -u16 ToWord(u8 bh, u8 bl) -{ - u16 wRet; - wRet = (u16)bl | ((u16)bh << 8); - return(wRet); -} -/******************************************************************************* -* Function Name : ByteSwap -* Description : Swap two byte in a word. -* Input : wSwW: word to Swap. -* Output : None. -* Return : resulted word. -*******************************************************************************/ -u16 ByteSwap(u16 wSwW) -{ - u8 bTemp; - u16 wRet; - bTemp = (u8)(wSwW & 0xff); - wRet = (wSwW >> 8) | ((u16)bTemp << 8); - return(wRet); -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_regs.h b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_regs.h deleted file mode 100644 index b63cc5fd1..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_regs.h +++ /dev/null @@ -1,627 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_regs.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Interface prototype functions to USB cell registers -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_REGS_H -#define __USB_REGS_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -#if defined(__cplusplus) -extern "C" { -#endif - -typedef enum _EP_DBUF_DIR -{ - /* double buffered endpoint direction */ - EP_DBUF_ERR, - EP_DBUF_OUT, - EP_DBUF_IN -}EP_DBUF_DIR; - -/* endpoint buffer number */ -enum EP_BUF_NUM -{ - EP_NOBUF, - EP_BUF0, - EP_BUF1 -}; - -/* Exported constants --------------------------------------------------------*/ -#define RegBase (0x40005C00L) /* USB_IP Peripheral Registers base address */ -#define PMAAddr (0x40006000L) /* USB_IP Packet Memory Area base address */ - -/******************************************************************************/ -/* General registers */ -/******************************************************************************/ - -/* Control register */ -#define CNTR ((volatile unsigned *)(RegBase + 0x40)) -/* Interrupt status register */ -#define ISTR ((volatile unsigned *)(RegBase + 0x44)) -/* Frame number register */ -#define FNR ((volatile unsigned *)(RegBase + 0x48)) -/* Device address register */ -#define DADDR ((volatile unsigned *)(RegBase + 0x4C)) -/* Buffer Table address register */ -#define BTABLE ((volatile unsigned *)(RegBase + 0x50)) -/******************************************************************************/ -/* Endpoint registers */ -/******************************************************************************/ -#define EP0REG ((volatile unsigned *)(RegBase)) /* endpoint 0 register address */ - -/* endpoints enumeration */ -#define ENDP0 ((u8)0) -#define ENDP1 ((u8)1) -#define ENDP2 ((u8)2) -#define ENDP3 ((u8)3) -#define ENDP4 ((u8)4) -#define ENDP5 ((u8)5) -#define ENDP6 ((u8)6) -#define ENDP7 ((u8)7) -/******************************************************************************/ -/* ISTR interrupt events */ -/******************************************************************************/ -#define ISTR_CTR (0x8000) /* Correct TRansfer (clear-only bit) */ -#define ISTR_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */ -#define ISTR_ERR (0x2000) /* ERRor (clear-only bit) */ -#define ISTR_WKUP (0x1000) /* WaKe UP (clear-only bit) */ -#define ISTR_SUSP (0x0800) /* SUSPend (clear-only bit) */ -#define ISTR_RESET (0x0400) /* RESET (clear-only bit) */ -#define ISTR_SOF (0x0200) /* Start Of Frame (clear-only bit) */ -#define ISTR_ESOF (0x0100) /* Expected Start Of Frame (clear-only bit) */ - - -#define ISTR_DIR (0x0010) /* DIRection of transaction (read-only bit) */ -#define ISTR_EP_ID (0x000F) /* EndPoint IDentifier (read-only bit) */ - -#define CLR_CTR (~ISTR_CTR) /* clear Correct TRansfer bit */ -#define CLR_DOVR (~ISTR_DOVR) /* clear DMA OVeR/underrun bit*/ -#define CLR_ERR (~ISTR_ERR) /* clear ERRor bit */ -#define CLR_WKUP (~ISTR_WKUP) /* clear WaKe UP bit */ -#define CLR_SUSP (~ISTR_SUSP) /* clear SUSPend bit */ -#define CLR_RESET (~ISTR_RESET) /* clear RESET bit */ -#define CLR_SOF (~ISTR_SOF) /* clear Start Of Frame bit */ -#define CLR_ESOF (~ISTR_ESOF) /* clear Expected Start Of Frame bit */ - -/******************************************************************************/ -/* CNTR control register bits definitions */ -/******************************************************************************/ -#define CNTR_CTRM (0x8000) /* Correct TRansfer Mask */ -#define CNTR_DOVRM (0x4000) /* DMA OVeR/underrun Mask */ -#define CNTR_ERRM (0x2000) /* ERRor Mask */ -#define CNTR_WKUPM (0x1000) /* WaKe UP Mask */ -#define CNTR_SUSPM (0x0800) /* SUSPend Mask */ -#define CNTR_RESETM (0x0400) /* RESET Mask */ -#define CNTR_SOFM (0x0200) /* Start Of Frame Mask */ -#define CNTR_ESOFM (0x0100) /* Expected Start Of Frame Mask */ - - -#define CNTR_RESUME (0x0010) /* RESUME request */ -#define CNTR_FSUSP (0x0008) /* Force SUSPend */ -#define CNTR_LPMODE (0x0004) /* Low-power MODE */ -#define CNTR_PDWN (0x0002) /* Power DoWN */ -#define CNTR_FRES (0x0001) /* Force USB RESet */ - -/******************************************************************************/ -/* FNR Frame Number Register bit definitions */ -/******************************************************************************/ -#define FNR_RXDP (0x8000) /* status of D+ data line */ -#define FNR_RXDM (0x4000) /* status of D- data line */ -#define FNR_LCK (0x2000) /* LoCKed */ -#define FNR_LSOF (0x1800) /* Lost SOF */ -#define FNR_FN (0x07FF) /* Frame Number */ -/******************************************************************************/ -/* DADDR Device ADDRess bit definitions */ -/******************************************************************************/ -#define DADDR_EF (0x80) -#define DADDR_ADD (0x7F) -/******************************************************************************/ -/* Endpoint register */ -/******************************************************************************/ -/* bit positions */ -#define EP_CTR_RX (0x8000) /* EndPoint Correct TRansfer RX */ -#define EP_DTOG_RX (0x4000) /* EndPoint Data TOGGLE RX */ -#define EPRX_STAT (0x3000) /* EndPoint RX STATus bit field */ -#define EP_SETUP (0x0800) /* EndPoint SETUP */ -#define EP_T_FIELD (0x0600) /* EndPoint TYPE */ -#define EP_KIND (0x0100) /* EndPoint KIND */ -#define EP_CTR_TX (0x0080) /* EndPoint Correct TRansfer TX */ -#define EP_DTOG_TX (0x0040) /* EndPoint Data TOGGLE TX */ -#define EPTX_STAT (0x0030) /* EndPoint TX STATus bit field */ -#define EPADDR_FIELD (0x000F) /* EndPoint ADDRess FIELD */ - -/* EndPoint REGister MASK (no toggle fields) */ -#define EPREG_MASK (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD) - -/* EP_TYPE[1:0] EndPoint TYPE */ -#define EP_TYPE_MASK (0x0600) /* EndPoint TYPE Mask */ -#define EP_BULK (0x0000) /* EndPoint BULK */ -#define EP_CONTROL (0x0200) /* EndPoint CONTROL */ -#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */ -#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */ -#define EP_T_MASK (~EP_T_FIELD & EPREG_MASK) - - -/* EP_KIND EndPoint KIND */ -#define EPKIND_MASK (~EP_KIND & EPREG_MASK) - -/* STAT_TX[1:0] STATus for TX transfer */ -#define EP_TX_DIS (0x0000) /* EndPoint TX DISabled */ -#define EP_TX_STALL (0x0010) /* EndPoint TX STALLed */ -#define EP_TX_NAK (0x0020) /* EndPoint TX NAKed */ -#define EP_TX_VALID (0x0030) /* EndPoint TX VALID */ -#define EPTX_DTOG1 (0x0010) /* EndPoint TX Data TOGgle bit1 */ -#define EPTX_DTOG2 (0x0020) /* EndPoint TX Data TOGgle bit2 */ -#define EPTX_DTOGMASK (EPTX_STAT|EPREG_MASK) - -/* STAT_RX[1:0] STATus for RX transfer */ -#define EP_RX_DIS (0x0000) /* EndPoint RX DISabled */ -#define EP_RX_STALL (0x1000) /* EndPoint RX STALLed */ -#define EP_RX_NAK (0x2000) /* EndPoint RX NAKed */ -#define EP_RX_VALID (0x3000) /* EndPoint RX VALID */ -#define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */ -#define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */ -#define EPRX_DTOGMASK (EPRX_STAT|EPREG_MASK) -/* Exported macro ------------------------------------------------------------*/ -/* SetCNTR */ -#define _SetCNTR(wRegValue) (*CNTR = (u16)wRegValue) - -/* SetISTR */ -#define _SetISTR(wRegValue) (*ISTR = (u16)wRegValue) - -/* SetDADDR */ -#define _SetDADDR(wRegValue) (*DADDR = (u16)wRegValue) - -/* SetBTABLE */ -#define _SetBTABLE(wRegValue)(*BTABLE = (u16)(wRegValue & 0xFFF8)) - -/* GetCNTR */ -#define _GetCNTR() ((u16) *CNTR) - -/* GetISTR */ -#define _GetISTR() ((u16) *ISTR) - -/* GetFNR */ -#define _GetFNR() ((u16) *FNR) - -/* GetDADDR */ -#define _GetDADDR() ((u16) *DADDR) - -/* GetBTABLE */ -#define _GetBTABLE() ((u16) *BTABLE) - -/* SetENDPOINT */ -#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \ - (u16)wRegValue) - -/* GetENDPOINT */ -#define _GetENDPOINT(bEpNum) ((u16)(*(EP0REG + bEpNum))) - -/******************************************************************************* -* Macro Name : SetEPType -* Description : sets the type in the endpoint register(bits EP_TYPE[1:0]) -* Input : bEpNum: Endpoint Number. -* wType -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\ - ((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType))) - -/******************************************************************************* -* Macro Name : GetEPType -* Description : gets the type in the endpoint register(bits EP_TYPE[1:0]) -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Type -*******************************************************************************/ -#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD) - -/******************************************************************************* -* Macro Name : SetEPTxStatus -* Description : sets the status for tx transfer (bits STAT_TX[1:0]). -* Input : bEpNum: Endpoint Number. -* wState: new state -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxStatus(bEpNum,wState) {\ - register u16 _wRegVal; \ - _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\ - /* toggle first bit ? */ \ - if((EPTX_DTOG1 & wState)!= 0) \ - _wRegVal ^= EPTX_DTOG1; \ - /* toggle second bit ? */ \ - if((EPTX_DTOG2 & wState)!= 0) \ - _wRegVal ^= EPTX_DTOG2; \ - _SetENDPOINT(bEpNum, _wRegVal); \ - } /* _SetEPTxStatus */ - -/******************************************************************************* -* Macro Name : SetEPRxStatus -* Description : sets the status for rx transfer (bits STAT_TX[1:0]) -* Input : bEpNum: Endpoint Number. -* wState: new state. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPRxStatus(bEpNum,wState) {\ - register u16 _wRegVal; \ - \ - _wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\ - /* toggle first bit ? */ \ - if((EPRX_DTOG1 & wState)!= 0) \ - _wRegVal ^= EPRX_DTOG1; \ - /* toggle second bit ? */ \ - if((EPRX_DTOG2 & wState)!= 0) \ - _wRegVal ^= EPRX_DTOG2; \ - _SetENDPOINT(bEpNum, _wRegVal); \ - } /* _SetEPRxStatus */ -/******************************************************************************* -* Macro Name : GetEPTxStatus / GetEPRxStatus -* Description : gets the status for tx/rx transfer (bits STAT_TX[1:0] -* /STAT_RX[1:0]) -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : status . -*******************************************************************************/ -#define _GetEPTxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPTX_STAT) - -#define _GetEPRxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPRX_STAT) - -/******************************************************************************* -* Macro Name : SetEPTxValid / SetEPRxValid -* Description : sets directly the VALID tx/rx-status into the enpoint register -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxValid(bEpNum) (_SetEPTxStatus(bEpNum, EP_TX_VALID)) - -#define _SetEPRxValid(bEpNum) (_SetEPRxStatus(bEpNum, EP_RX_VALID)) - -/******************************************************************************* -* Macro Name : GetTxStallStatus / GetRxStallStatus. -* Description : checks stall condition in an endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : TRUE = endpoint in stall condition. -*******************************************************************************/ -#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \ - == EP_TX_STALL) -#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \ - == EP_RX_STALL) - -/******************************************************************************* -* Macro Name : SetEP_KIND / ClearEP_KIND. -* Description : set & clear EP_KIND bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \ - (_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK)) -#define _ClearEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \ - (_GetENDPOINT(bEpNum) & EPKIND_MASK))) - -/******************************************************************************* -* Macro Name : Set_Status_Out / Clear_Status_Out. -* Description : Sets/clears directly STATUS_OUT bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _Set_Status_Out(bEpNum) _SetEP_KIND(bEpNum) -#define _Clear_Status_Out(bEpNum) _ClearEP_KIND(bEpNum) - -/******************************************************************************* -* Macro Name : SetEPDoubleBuff / ClearEPDoubleBuff. -* Description : Sets/clears directly EP_KIND bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDoubleBuff(bEpNum) _SetEP_KIND(bEpNum) -#define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum) - -/******************************************************************************* -* Macro Name : ClearEP_CTR_RX / ClearEP_CTR_TX. -* Description : Clears bit CTR_RX / CTR_TX in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _ClearEP_CTR_RX(bEpNum) (_SetENDPOINT(bEpNum,\ - _GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK)) -#define _ClearEP_CTR_TX(bEpNum) (_SetENDPOINT(bEpNum,\ - _GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK)) - -/******************************************************************************* -* Macro Name : ToggleDTOG_RX / ToggleDTOG_TX . -* Description : Toggles DTOG_RX / DTOG_TX bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _ToggleDTOG_RX(bEpNum) (_SetENDPOINT(bEpNum, \ - EP_DTOG_RX | (_GetENDPOINT(bEpNum) & EPREG_MASK))) -#define _ToggleDTOG_TX(bEpNum) (_SetENDPOINT(bEpNum, \ - EP_DTOG_TX | (_GetENDPOINT(bEpNum) & EPREG_MASK))) - -/******************************************************************************* -* Macro Name : ClearDTOG_RX / ClearDTOG_TX. -* Description : Clears DTOG_RX / DTOG_TX bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _ClearDTOG_RX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\ - _ToggleDTOG_RX(bEpNum) -#define _ClearDTOG_TX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\ - _ToggleDTOG_TX(bEpNum) -/******************************************************************************* -* Macro Name : SetEPAddress. -* Description : Sets address in an endpoint register. -* Input : bEpNum: Endpoint Number. -* bAddr: Address. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\ - (_GetENDPOINT(bEpNum) & EPREG_MASK) | bAddr) - -/******************************************************************************* -* Macro Name : GetEPAddress. -* Description : Gets address in an endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _GetEPAddress(bEpNum) ((u8)(_GetENDPOINT(bEpNum) & EPADDR_FIELD)) - -#define _pEPTxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8 )*2 + PMAAddr)) -#define _pEPTxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr)) -#define _pEPRxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr)) -#define _pEPRxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr)) - -/******************************************************************************* -* Macro Name : SetEPTxAddr / SetEPRxAddr. -* Description : sets address of the tx/rx buffer. -* Input : bEpNum: Endpoint Number. -* wAddr: address to be set (must be word aligned). -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1)) -#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1)) - -/******************************************************************************* -* Macro Name : GetEPTxAddr / GetEPRxAddr. -* Description : Gets address of the tx/rx buffer. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : address of the buffer. -*******************************************************************************/ -#define _GetEPTxAddr(bEpNum) ((u16)*_pEPTxAddr(bEpNum)) -#define _GetEPRxAddr(bEpNum) ((u16)*_pEPRxAddr(bEpNum)) - -/******************************************************************************* -* Macro Name : SetEPCountRxReg. -* Description : Sets counter of rx buffer with no. of blocks. -* Input : pdwReg: pointer to counter. -* wCount: Counter. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _BlocksOf32(dwReg,wCount,wNBlocks) {\ - wNBlocks = wCount >> 5;\ - if((wCount & 0x1f) == 0)\ - wNBlocks--;\ - *pdwReg = (u32)((wNBlocks << 10) | 0x8000);\ - }/* _BlocksOf32 */ - -#define _BlocksOf2(dwReg,wCount,wNBlocks) {\ - wNBlocks = wCount >> 1;\ - if((wCount & 0x1) != 0)\ - wNBlocks++;\ - *pdwReg = (u32)(wNBlocks << 10);\ - }/* _BlocksOf2 */ - -#define _SetEPCountRxReg(dwReg,wCount) {\ - u16 wNBlocks;\ - if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\ - else {_BlocksOf2(dwReg,wCount,wNBlocks);}\ - }/* _SetEPCountRxReg */ - - - -#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\ - u32 *pdwReg = _pEPTxCount(bEpNum); \ - _SetEPCountRxReg(pdwReg, wCount);\ - } -/******************************************************************************* -* Macro Name : SetEPTxCount / SetEPRxCount. -* Description : sets counter for the tx/rx buffer. -* Input : bEpNum: endpoint number. -* wCount: Counter value. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount) -#define _SetEPRxCount(bEpNum,wCount) {\ - u32 *pdwReg = _pEPRxCount(bEpNum); \ - _SetEPCountRxReg(pdwReg, wCount);\ - } -/******************************************************************************* -* Macro Name : GetEPTxCount / GetEPRxCount. -* Description : gets counter of the tx buffer. -* Input : bEpNum: endpoint number. -* Output : None. -* Return : Counter value. -*******************************************************************************/ -#define _GetEPTxCount(bEpNum)((u16)(*_pEPTxCount(bEpNum)) & 0x3ff) -#define _GetEPRxCount(bEpNum)((u16)(*_pEPRxCount(bEpNum)) & 0x3ff) - -/******************************************************************************* -* Macro Name : SetEPDblBuf0Addr / SetEPDblBuf1Addr. -* Description : Sets buffer 0/1 address in a double buffer endpoint. -* Input : bEpNum: endpoint number. -* : wBuf0Addr: buffer 0 address. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);} -#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);} - -/******************************************************************************* -* Macro Name : SetEPDblBuffAddr. -* Description : Sets addresses in a double buffer endpoint. -* Input : bEpNum: endpoint number. -* : wBuf0Addr: buffer 0 address. -* : wBuf1Addr = buffer 1 address. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \ - _SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\ - _SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\ - } /* _SetEPDblBuffAddr */ - -/******************************************************************************* -* Macro Name : GetEPDblBuf0Addr / GetEPDblBuf1Addr. -* Description : Gets buffer 0/1 address of a double buffer endpoint. -* Input : bEpNum: endpoint number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum)) -#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum)) - -/******************************************************************************* -* Macro Name : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count. -* Description : Gets buffer 0/1 address of a double buffer endpoint. -* Input : bEpNum: endpoint number. -* : bDir: endpoint dir EP_DBUF_OUT = OUT -* EP_DBUF_IN = IN -* : wCount: Counter value -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDblBuf0Count(bEpNum, bDir, wCount) { \ - if(bDir == EP_DBUF_OUT)\ - /* OUT endpoint */ \ - {_SetEPRxDblBuf0Count(bEpNum,wCount);} \ - else if(bDir == EP_DBUF_IN)\ - /* IN endpoint */ \ - *_pEPTxCount(bEpNum) = (u32)wCount; \ - } /* SetEPDblBuf0Count*/ - -#define _SetEPDblBuf1Count(bEpNum, bDir, wCount) { \ - if(bDir == EP_DBUF_OUT)\ - /* OUT endpoint */ \ - {_SetEPRxCount(bEpNum,wCount);}\ - else if(bDir == EP_DBUF_IN)\ - /* IN endpoint */\ - *_pEPRxCount(bEpNum) = (u32)wCount; \ - } /* SetEPDblBuf1Count */ - -#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\ - _SetEPDblBuf0Count(bEpNum, bDir, wCount); \ - _SetEPDblBuf1Count(bEpNum, bDir, wCount); \ - } /* _SetEPDblBuffCount */ - -/******************************************************************************* -* Macro Name : GetEPDblBuf0Count / GetEPDblBuf1Count. -* Description : Gets buffer 0/1 rx/tx counter for double buffering. -* Input : bEpNum: endpoint number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum)) -#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum)) - - -/* External variables --------------------------------------------------------*/ -extern volatile u16 wIstr; /* ISTR register last read value */ - -/* Exported functions ------------------------------------------------------- */ -void SetCNTR(u16 /*wRegValue*/); -void SetISTR(u16 /*wRegValue*/); -void SetDADDR(u16 /*wRegValue*/); -void SetBTABLE(u16 /*wRegValue*/); -u16 GetCNTR(void); -u16 GetISTR(void); -u16 GetFNR(void); -u16 GetDADDR(void); -u16 GetBTABLE(void); -void SetENDPOINT(u8 /*bEpNum*/, u16 /*wRegValue*/); -u16 GetENDPOINT(u8 /*bEpNum*/); -void SetEPType(u8 /*bEpNum*/, u16 /*wType*/); -u16 GetEPType(u8 /*bEpNum*/); -void SetEPTxStatus(u8 /*bEpNum*/, u16 /*wState*/); -void SetEPRxStatus(u8 /*bEpNum*/, u16 /*wState*/); -void SetDouBleBuffEPStall(u8 /*bEpNum*/, u8 bDir); -u16 GetEPTxStatus(u8 /*bEpNum*/); -u16 GetEPRxStatus(u8 /*bEpNum*/); -void SetEPTxValid(u8 /*bEpNum*/); -void SetEPRxValid(u8 /*bEpNum*/); -u16 GetTxStallStatus(u8 /*bEpNum*/); -u16 GetRxStallStatus(u8 /*bEpNum*/); -void SetEP_KIND(u8 /*bEpNum*/); -void ClearEP_KIND(u8 /*bEpNum*/); -void Set_Status_Out(u8 /*bEpNum*/); -void Clear_Status_Out(u8 /*bEpNum*/); -void SetEPDoubleBuff(u8 /*bEpNum*/); -void ClearEPDoubleBuff(u8 /*bEpNum*/); -void ClearEP_CTR_RX(u8 /*bEpNum*/); -void ClearEP_CTR_TX(u8 /*bEpNum*/); -void ToggleDTOG_RX(u8 /*bEpNum*/); -void ToggleDTOG_TX(u8 /*bEpNum*/); -void ClearDTOG_RX(u8 /*bEpNum*/); -void ClearDTOG_TX(u8 /*bEpNum*/); -void SetEPAddress(u8 /*bEpNum*/, u8 /*bAddr*/); -u8 GetEPAddress(u8 /*bEpNum*/); -void SetEPTxAddr(u8 /*bEpNum*/, u16 /*wAddr*/); -void SetEPRxAddr(u8 /*bEpNum*/, u16 /*wAddr*/); -u16 GetEPTxAddr(u8 /*bEpNum*/); -u16 GetEPRxAddr(u8 /*bEpNum*/); -void SetEPCountRxReg(u32 * /*pdwReg*/, u16 /*wCount*/); -void SetEPTxCount(u8 /*bEpNum*/, u16 /*wCount*/); -void SetEPRxCount(u8 /*bEpNum*/, u16 /*wCount*/); -u16 GetEPTxCount(u8 /*bEpNum*/); -u16 GetEPRxCount(u8 /*bEpNum*/); -void SetEPDblBuf0Addr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/); -void SetEPDblBuf1Addr(u8 /*bEpNum*/, u16 /*wBuf1Addr*/); -void SetEPDblBuffAddr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/, u16 /*wBuf1Addr*/); -u16 GetEPDblBuf0Addr(u8 /*bEpNum*/); -u16 GetEPDblBuf1Addr(u8 /*bEpNum*/); -void SetEPDblBuffCount(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); -void SetEPDblBuf0Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); -void SetEPDblBuf1Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); -u16 GetEPDblBuf0Count(u8 /*bEpNum*/); -u16 GetEPDblBuf1Count(u8 /*bEpNum*/); -EP_DBUF_DIR GetEPDblBufDir(u8 /*bEpNum*/); -void FreeUserBuffer(u8 bEpNum/*bEpNum*/, u8 bDir); -u16 ToWord(u8, u8); -u16 ByteSwap(u16); - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_REGS_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_type.h b/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_type.h deleted file mode 100644 index 34b3bf5b7..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib/usb_type.h +++ /dev/null @@ -1,77 +0,0 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_type.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Type definitions used by the USB Library -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_TYPE_H -#define __USB_TYPE_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -#ifndef NULL -#define NULL ((void *)0) -#endif - -typedef signed long s32; -typedef signed short s16; -typedef signed char s8; - -typedef volatile signed long vs32; -typedef volatile signed short vs16; -typedef volatile signed char vs8; - -typedef unsigned long u32; -typedef unsigned short u16; -typedef unsigned char u8; - -typedef unsigned long const uc32; /* Read Only */ -typedef unsigned short const uc16; /* Read Only */ -typedef unsigned char const uc8; /* Read Only */ - -typedef volatile unsigned long vu32; -typedef volatile unsigned short vu16; -typedef volatile unsigned char vu8; - -typedef volatile unsigned long const vuc32; /* Read Only */ -typedef volatile unsigned short const vuc16; /* Read Only */ -typedef volatile unsigned char const vuc8; /* Read Only */ - - -typedef enum -{ - FALSE = 0, TRUE = !FALSE -} -USB_Bool; - -typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus; - -typedef enum { DISABLE = 0, ENABLE = !DISABLE} FunctionalState; - -typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus; - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -/* External variables --------------------------------------------------------*/ - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_TYPE_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/STM32F3/cores/maple/libmaple/usb/usb_lib_globals.h b/STM32F3/cores/maple/libmaple/usb/usb_lib_globals.h deleted file mode 100644 index 1cd27540c..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_lib_globals.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#ifndef _USB_LIB_GLOBALS_H_ -#define _USB_LIB_GLOBALS_H_ - -/* usb_lib headers */ -#include "usb_type.h" -#include "usb_core.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern USER_STANDARD_REQUESTS User_Standard_Requests; -extern USER_STANDARD_REQUESTS *pUser_Standard_Requests; - -extern DEVICE_PROP Device_Property; -extern DEVICE_PROP *pProperty; - -extern DEVICE_INFO Device_Info; -extern DEVICE_INFO *pInformation; - -extern DEVICE Device_Table; -extern u16 SaveRState; -extern u16 SaveTState; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/STM32F3/cores/maple/libmaple/usb/usb_reg_map.c b/STM32F3/cores/maple/libmaple/usb/usb_reg_map.c deleted file mode 100644 index ea60cb3c2..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_reg_map.c +++ /dev/null @@ -1,88 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include "usb_reg_map.h" - -/* TODO these could use some improvement; they're fairly - * straightforward ports of the analogous ST code. The PMA blit - * routines in particular are obvious targets for performance - * measurement and tuning. */ - -void usb_copy_to_pma(const uint8 *buf, uint16 len, uint16 pma_offset) { - uint16 *dst = (uint16*)usb_pma_ptr(pma_offset); - uint16 n = len >> 1; - uint16 i; - for (i = 0; i < n; i++) { - *dst = (uint16)(*buf) | *(buf + 1) << 8; - buf += 2; - dst += 2; - } - if (len & 1) { - *dst = *buf; - } -} - -void usb_copy_from_pma(uint8 *buf, uint16 len, uint16 pma_offset) { - uint32 *src = (uint32*)usb_pma_ptr(pma_offset); - uint16 *dst = (uint16*)buf; - uint16 n = len >> 1; - uint16 i; - for (i = 0; i < n; i++) { - *dst++ = *src++; - } - if (len & 1) { - *dst = *src & 0xFF; - } -} - -static void usb_set_ep_rx_count_common(uint32 *rxc, uint16 count) { - uint16 nblocks; - if (count > 62) { - /* use 32-byte memory block size */ - nblocks = count >> 5; - if ((count & 0x1F) == 0) { - nblocks--; - } - *rxc = (nblocks << 10) | 0x8000; - } else { - /* use 2-byte memory block size */ - nblocks = count >> 1; - if ((count & 0x1) != 0) { - nblocks++; - } - *rxc = nblocks << 10; - } -} - -void usb_set_ep_rx_buf0_count(uint8 ep, uint16 count) { - uint32 *rxc = usb_ep_rx_buf0_count_ptr(ep); - usb_set_ep_rx_count_common(rxc, count); -} - -void usb_set_ep_rx_count(uint8 ep, uint16 count) { - uint32 *rxc = usb_ep_rx_count_ptr(ep); - usb_set_ep_rx_count_common(rxc, count); -} diff --git a/STM32F3/cores/maple/libmaple/usb/usb_reg_map.h b/STM32F3/cores/maple/libmaple/usb/usb_reg_map.h deleted file mode 100644 index 2e3f6bc17..000000000 --- a/STM32F3/cores/maple/libmaple/usb/usb_reg_map.h +++ /dev/null @@ -1,617 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include -#include - -#ifndef _USB_REG_MAP_H_ -#define _USB_REG_MAP_H_ - -/* TODO: - * - Pick one of "endp", "ep" "endpt" - */ - -/* - * Register map and base pointer - */ - -#define USB_NR_EP_REGS 8 - -/** USB register map type */ -typedef struct usb_reg_map { - __io uint32 EP[USB_NR_EP_REGS]; /**< Endpoint registers */ - const uint32 RESERVED[8]; /**< Reserved */ - __io uint32 CNTR; /**< Control register */ - __io uint32 ISTR; /**< Interrupt status register */ - __io uint32 FNR; /**< Frame number register */ - __io uint32 DADDR; /**< Device address */ - __io uint32 BTABLE; /**< @brief Buffer table address - * - * Address offset within the USB - * packet memory area which points - * to the base of the buffer - * descriptor table. Must be - * aligned to an 8 byte boundary. - */ -} usb_reg_map; - -/** USB register map base pointer */ -#define USB_BASE ((struct usb_reg_map*)0x40005C00) - -/* - * Register bit definitions - */ - -/* Endpoint registers (USB_EPnR) */ - -#define USB_EP_CTR_RX_BIT 15 -#define USB_EP_DTOG_RX_BIT 14 -#define USB_EP_SETUP_BIT 11 -#define USB_EP_EP_KIND_BIT 8 -#define USB_EP_CTR_TX_BIT 7 -#define USB_EP_DTOG_TX_BIT 6 - -#define USB_EP_CTR_RX BIT(USB_EP_CTR_RX_BIT) -#define USB_EP_DTOG_RX BIT(USB_EP_DTOG_RX_BIT) -#define USB_EP_STAT_RX (0x3 << 12) -#define USB_EP_STAT_RX_DISABLED (0x0 << 12) -#define USB_EP_STAT_RX_STALL (0x1 << 12) -#define USB_EP_STAT_RX_NAK (0x2 << 12) -#define USB_EP_STAT_RX_VALID (0x3 << 12) -#define USB_EP_SETUP BIT(USB_EP_SETUP_BIT) -#define USB_EP_EP_TYPE (0x3 << 9) -#define USB_EP_EP_TYPE_BULK (0x0 << 9) -#define USB_EP_EP_TYPE_CONTROL (0x1 << 9) -#define USB_EP_EP_TYPE_ISO (0x2 << 9) -#define USB_EP_EP_TYPE_INTERRUPT (0x3 << 9) -#define USB_EP_EP_KIND BIT(USB_EP_EP_KIND_BIT) -#define USB_EP_EP_KIND_DBL_BUF (0x1 << USB_EP_EP_KIND_BIT) -#define USB_EP_CTR_TX BIT(USB_EP_CTR_TX_BIT) -#define USB_EP_DTOG_TX BIT(USB_EP_DTOG_TX_BIT) -#define USB_EP_STAT_TX (0x3 << 4) -#define USB_EP_STAT_TX_DISABLED (0x0 << 4) -#define USB_EP_STAT_TX_STALL (0x1 << 4) -#define USB_EP_STAT_TX_NAK (0x2 << 4) -#define USB_EP_STAT_TX_VALID (0x3 << 4) -#define USB_EP_EA 0xF - -/* Control register (USB_CNTR) */ - -#define USB_CNTR_CTRM_BIT 15 -#define USB_CNTR_PMAOVERM_BIT 14 -#define USB_CNTR_ERRM_BIT 13 -#define USB_CNTR_WKUPM_BIT 12 -#define USB_CNTR_SUSPM_BIT 11 -#define USB_CNTR_RESETM_BIT 10 -#define USB_CNTR_SOFM_BIT 9 -#define USB_CNTR_ESOFM_BIT 8 -#define USB_CNTR_RESUME_BIT 4 -#define USB_CNTR_FSUSP_BIT 3 -#define USB_CNTR_LP_MODE_BIT 2 -#define USB_CNTR_PDWN_BIT 1 -#define USB_CNTR_FRES_BIT 0 - -#define USB_CNTR_CTRM BIT(USB_CNTR_CTRM_BIT) -#define USB_CNTR_PMAOVERM BIT(USB_CNTR_PMAOVERM_BIT) -#define USB_CNTR_ERRM BIT(USB_CNTR_ERRM_BIT) -#define USB_CNTR_WKUPM BIT(USB_CNTR_WKUPM_BIT) -#define USB_CNTR_SUSPM BIT(USB_CNTR_SUSPM_BIT) -#define USB_CNTR_RESETM BIT(USB_CNTR_RESETM_BIT) -#define USB_CNTR_SOFM BIT(USB_CNTR_SOFM_BIT) -#define USB_CNTR_ESOFM BIT(USB_CNTR_ESOFM_BIT) -#define USB_CNTR_RESUME BIT(USB_CNTR_RESUME_BIT) -#define USB_CNTR_FSUSP BIT(USB_CNTR_FSUSP_BIT) -#define USB_CNTR_LP_MODE BIT(USB_CNTR_LP_MODE_BIT) -#define USB_CNTR_PDWN BIT(USB_CNTR_PDWN_BIT) -#define USB_CNTR_FRES BIT(USB_CNTR_FRES_BIT) - -/* Interrupt status register (USB_ISTR) */ - -#define USB_ISTR_CTR_BIT 15 -#define USB_ISTR_PMAOVR_BIT 14 -#define USB_ISTR_ERR_BIT 13 -#define USB_ISTR_WKUP_BIT 12 -#define USB_ISTR_SUSP_BIT 11 -#define USB_ISTR_RESET_BIT 10 -#define USB_ISTR_SOF_BIT 9 -#define USB_ISTR_ESOF_BIT 8 -#define USB_ISTR_DIR_BIT 4 - -#define USB_ISTR_CTR BIT(USB_ISTR_CTR_BIT) -#define USB_ISTR_PMAOVR BIT(USB_ISTR_PMAOVR_BIT) -#define USB_ISTR_ERR BIT(USB_ISTR_ERR_BIT) -#define USB_ISTR_WKUP BIT(USB_ISTR_WKUP_BIT) -#define USB_ISTR_SUSP BIT(USB_ISTR_SUSP_BIT) -#define USB_ISTR_RESET BIT(USB_ISTR_RESET_BIT) -#define USB_ISTR_SOF BIT(USB_ISTR_SOF_BIT) -#define USB_ISTR_ESOF BIT(USB_ISTR_ESOF_BIT) -#define USB_ISTR_DIR BIT(USB_ISTR_DIR_BIT) -#define USB_ISTR_EP_ID 0xF - -/* Frame number register (USB_FNR) */ - -#define USB_FNR_RXDP_BIT 15 -#define USB_FNR_RXDM_BIT 14 -#define USB_FNR_LCK_BIT 13 - -#define USB_FNR_RXDP BIT(USB_FNR_RXDP_BIT) -#define USB_FNR_RXDM BIT(USB_FNR_RXDM_BIT) -#define USB_FNR_LCK BIT(USB_FNR_LCK_BIT) -#define USB_FNR_LSOF (0x3 << 11) -#define USB_FNR_FN 0x7FF - -/* Device address (USB_DADDR) */ - -#define USB_DADDR_EF_BIT 7 -#define USB_DADDR_ADD6_BIT 6 -#define USB_DADDR_ADD5_BIT 5 -#define USB_DADDR_ADD4_BIT 4 -#define USB_DADDR_ADD3_BIT 3 -#define USB_DADDR_ADD2_BIT 2 -#define USB_DADDR_ADD1_BIT 1 -#define USB_DADDR_ADD0_BIT 0 - -#define USB_DADDR_EF BIT(USB_DADDR_EF_BIT) -#define USB_DADDR_ADD6 BIT(USB_DADDR_ADD6_BIT) -#define USB_DADDR_ADD5 BIT(USB_DADDR_ADD5_BIT) -#define USB_DADDR_ADD4 BIT(USB_DADDR_ADD4_BIT) -#define USB_DADDR_ADD3 BIT(USB_DADDR_ADD3_BIT) -#define USB_DADDR_ADD2 BIT(USB_DADDR_ADD2_BIT) -#define USB_DADDR_ADD1 BIT(USB_DADDR_ADD1_BIT) -#define USB_DADDR_ADD0 BIT(USB_DADDR_ADD0_BIT) - -/* Buffer table address (USB_BTABLE) */ - -#define USB_BTABLE_BTABLE (0x1FFF << 3) - -/* - * Register convenience routines - */ - -#define __EP_CTR_NOP (USB_EP_CTR_RX | USB_EP_CTR_TX) -#define __EP_NONTOGGLE (USB_EP_CTR_RX | USB_EP_SETUP | \ - USB_EP_EP_TYPE | USB_EP_EP_KIND | \ - USB_EP_CTR_TX | USB_EP_EA) - -static inline void usb_clear_ctr_rx(uint8 ep) { - uint32 epr = USB_BASE->EP[ep]; - USB_BASE->EP[ep] = epr & ~USB_EP_CTR_RX & __EP_NONTOGGLE; -} - -static inline void usb_clear_ctr_tx(uint8 ep) { - uint32 epr = USB_BASE->EP[ep]; - USB_BASE->EP[ep] = epr & ~USB_EP_CTR_TX & __EP_NONTOGGLE; -} - -static inline uint32 usb_get_ep_dtog_tx(uint8 ep) { - uint32 epr = USB_BASE->EP[ep]; - return epr & USB_EP_DTOG_TX; -} - -static inline uint32 usb_get_ep_dtog_rx(uint8 ep) { - uint32 epr = USB_BASE->EP[ep]; - return epr & USB_EP_DTOG_RX; -} - -static inline uint32 usb_get_ep_tx_sw_buf(uint8 ep) { - return usb_get_ep_dtog_rx(ep); -} - -static inline uint32 usb_get_ep_rx_sw_buf(uint8 ep) { - return usb_get_ep_dtog_tx(ep); -} - -static inline void usb_toggle_ep_dtog_tx(uint8 ep) { - uint32 epr = USB_BASE->EP[ep]; - epr &= __EP_NONTOGGLE; - epr |= USB_EP_DTOG_TX; - USB_BASE->EP[ep] = epr; -} - -static inline void usb_toggle_ep_dtog_rx(uint8 ep) { - uint32 epr = USB_BASE->EP[ep]; - epr &= __EP_NONTOGGLE; - epr |= USB_EP_DTOG_RX; - USB_BASE->EP[ep] = epr; -} - -static inline void usb_clear_ep_dtog_tx(uint8 ep) { - if (usb_get_ep_dtog_tx(ep) != 0) { - usb_toggle_ep_dtog_tx(ep); - } -} - -static inline void usb_clear_ep_dtog_rx(uint8 ep) { - if (usb_get_ep_dtog_rx(ep) != 0) { - usb_toggle_ep_dtog_rx(ep); - } -} - -static inline void usb_set_ep_dtog_tx(uint8 ep) { - if (usb_get_ep_dtog_tx(ep) == 0) { - usb_toggle_ep_dtog_tx(ep); - } -} - -static inline void usb_set_ep_dtog_rx(uint8 ep) { - if (usb_get_ep_dtog_rx(ep) == 0) { - usb_toggle_ep_dtog_rx(ep); - } -} - -static inline void usb_toggle_ep_rx_sw_buf(uint8 ep) { - usb_toggle_ep_dtog_tx(ep); -} - -static inline void usb_toggle_ep_tx_sw_buf(uint8 ep) { - usb_toggle_ep_dtog_rx(ep); -} - -static inline void usb_clear_ep_rx_sw_buf(uint8 ep) { - usb_clear_ep_dtog_tx(ep); -} - -static inline void usb_clear_ep_tx_sw_buf(uint8 ep) { - usb_clear_ep_dtog_rx(ep); -} - -static inline void usb_set_ep_rx_sw_buf(uint8 ep) { - usb_set_ep_dtog_tx(ep); -} - -static inline void usb_set_ep_tx_sw_buf(uint8 ep) { - usb_set_ep_dtog_rx(ep); -} - -static inline void usb_set_ep_rx_stat(uint8 ep, uint32 status) { - uint32 epr = USB_BASE->EP[ep]; - epr &= ~(USB_EP_STAT_TX | USB_EP_DTOG_RX | USB_EP_DTOG_TX); - epr |= __EP_CTR_NOP; - epr ^= status; - USB_BASE->EP[ep] = epr; -} - -static inline void usb_set_ep_tx_stat(uint8 ep, uint32 status) { - uint32 epr = USB_BASE->EP[ep]; - epr &= ~(USB_EP_STAT_RX | USB_EP_DTOG_RX | USB_EP_DTOG_TX); - epr |= __EP_CTR_NOP; - epr ^= status; - USB_BASE->EP[ep] = epr; -} - -static inline void usb_set_ep_type(uint8 ep, uint32 type) { - uint32 epr = USB_BASE->EP[ep]; - epr &= ~USB_EP_EP_TYPE & __EP_NONTOGGLE; - epr |= type; - USB_BASE->EP[ep] = epr; -} - -static inline void usb_set_ep_kind(uint8 ep, uint32 kind) { - uint32 epr = USB_BASE->EP[ep]; - epr &= ~USB_EP_EP_KIND & __EP_NONTOGGLE; - epr |= kind; - USB_BASE->EP[ep] = epr; -} - -static inline uint32 usb_get_ep_type(uint8 ep) { - uint32 epr = USB_BASE->EP[ep]; - return epr & USB_EP_EP_TYPE; -} - -static inline uint32 usb_get_ep_kind(uint8 ep) { - uint32 epr = USB_BASE->EP[ep]; - return epr & USB_EP_EP_TYPE; -} - - -static inline void usb_clear_status_out(uint8 ep) { - usb_set_ep_kind(ep, 0); -} - -/* - * Packet memory area (PMA) base pointer - */ - -/** - * @brief USB packet memory area (PMA) base pointer. - * - * The USB PMA is SRAM shared between USB and CAN. The USB peripheral - * accesses this memory directly via the packet buffer interface. */ -#define USB_PMA_BASE ((__io void*)0x40006000) - -/* - * PMA conveniences - */ - -void usb_copy_to_pma(const uint8 *buf, uint16 len, uint16 pma_offset); -void usb_copy_from_pma(uint8 *buf, uint16 len, uint16 pma_offset); - -static inline void* usb_pma_ptr(uint32 offset) { - return (void*)(USB_PMA_BASE + 2 * offset); -} - -/* - * BTABLE - */ - -/* (Forward-declared) BTABLE entry. - * - * The BTABLE can be viewed as an array of usb_btable_ent values; - * these vary in structure according to the configuration of the - * endpoint. - */ -union usb_btable_ent; - -/* Bidirectional endpoint BTABLE entry */ -typedef struct usb_btable_bidi { - __io uint16 addr_tx; const uint16 PAD1; - __io uint16 count_tx; const uint16 PAD2; - __io uint16 addr_rx; const uint16 PAD3; - __io uint16 count_rx; const uint16 PAD4; -} usb_btable_bidi; - -/* Unidirectional receive-only endpoint BTABLE entry */ -typedef struct usb_btable_uni_rx { - __io uint16 empty1; const uint16 PAD1; - __io uint16 empty2; const uint16 PAD2; - __io uint16 addr_rx; const uint16 PAD3; - __io uint16 count_rx; const uint16 PAD4; -} usb_btable_uni_rx; - -/* Unidirectional transmit-only endpoint BTABLE entry */ -typedef struct usb_btable_uni_tx { - __io uint16 addr_tx; const uint16 PAD1; - __io uint16 count_tx; const uint16 PAD2; - __io uint16 empty1; const uint16 PAD3; - __io uint16 empty2; const uint16 PAD4; -} usb_btable_uni_tx; - -/* Double-buffered transmission endpoint BTABLE entry */ -typedef struct usb_btable_dbl_tx { - __io uint16 addr_tx0; const uint16 PAD1; - __io uint16 count_tx0; const uint16 PAD2; - __io uint16 addr_tx1; const uint16 PAD3; - __io uint16 count_tx1; const uint16 PAD4; -} usb_btable_dbl_tx; - -/* Double-buffered reception endpoint BTABLE entry */ -typedef struct usb_btable_dbl_rx { - __io uint16 addr_rx0; const uint16 PAD1; - __io uint16 count_rx0; const uint16 PAD2; - __io uint16 addr_rx1; const uint16 PAD3; - __io uint16 count_rx1; const uint16 PAD4; -} usb_btable_dbl_rx; - -/* TODO isochronous endpoint entries */ - -/* Definition for above forward-declared BTABLE entry. */ -typedef union usb_btable_ent { - usb_btable_bidi bidi; - usb_btable_uni_rx u_rx; - usb_btable_uni_tx u_tx; - usb_btable_dbl_tx d_tx; - usb_btable_dbl_rx d_rx; -} usb_btable_ent; - -/* - * BTABLE conveniences - */ - -/* TODO (?) Convert usages of the many (and lengthily-named) - * accessors/mutators below to just manipulating usb_btable_entry - * values. */ - -static inline uint32* usb_btable_ptr(uint32 offset) { - return (uint32*)usb_pma_ptr(USB_BASE->BTABLE + offset); -} - -/* TX address */ - -static inline uint32* usb_ep_tx_addr_ptr(uint8 ep) { - return usb_btable_ptr(ep * 8); -} - -static inline uint16 usb_get_ep_tx_addr(uint8 ep) { - return (uint16)*usb_ep_tx_addr_ptr(ep); -} - -static inline void usb_set_ep_tx_addr(uint8 ep, uint16 addr) { - uint32 *tx_addr = usb_ep_tx_addr_ptr(ep); - *tx_addr = addr & ~0x1; -} - -/* RX address */ - -static inline uint32* usb_ep_rx_addr_ptr(uint8 ep) { - return usb_btable_ptr(ep * 8 + 4); -} - -static inline uint16 usb_get_ep_rx_addr(uint8 ep) { - return (uint16)*usb_ep_rx_addr_ptr(ep); -} - -static inline void usb_set_ep_rx_addr(uint8 ep, uint16 addr) { - uint32 *rx_addr = usb_ep_rx_addr_ptr(ep); - *rx_addr = addr & ~0x1; -} - -/* TX count (doesn't cover double-buffered and isochronous in) */ - -static inline uint32* usb_ep_tx_count_ptr(uint8 ep) { - return usb_btable_ptr(ep * 8 + 2); -} - -static inline uint16 usb_get_ep_tx_count(uint8 ep) { - /* FIXME: this is broken somehow; calling it seems to - * confuse/crash the chip. */ - return (uint16)(*usb_ep_tx_count_ptr(ep) & 0x3FF); -} - -static inline void usb_set_ep_tx_count(uint8 ep, uint16 count) { - uint32 *txc = usb_ep_tx_count_ptr(ep); - *txc = count; -} - -/* RX count */ - -static inline uint32* usb_ep_rx_count_ptr(uint8 ep) { - return usb_btable_ptr(ep * 8 + 6); -} - -static inline uint16 usb_get_ep_rx_count(uint8 ep) { - return (uint16)*usb_ep_rx_count_ptr(ep) & 0x3FF; -} - -void usb_set_ep_rx_count(uint8 ep, uint16 count); - -/* double buffer definitions */ -static inline uint32* usb_get_ep_tx_buf0_addr_ptr(uint8 ep) { - return usb_ep_tx_addr_ptr(ep); -} - -static inline uint16 usb_get_ep_tx_buf0_addr(uint8 ep) { - return usb_get_ep_tx_addr(ep); -} - -static inline void usb_set_ep_tx_buf0_addr(uint8 ep, uint16 addr) { - usb_set_ep_tx_addr(ep, addr); -} - -static inline uint32* usb_get_ep_tx_buf1_addr_ptr(uint8 ep) { - return usb_ep_rx_addr_ptr(ep); -} - -static inline uint16 usb_get_ep_tx_buf1_addr(uint8 ep) { - return usb_get_ep_rx_addr(ep); -} - -static inline void usb_set_ep_tx_buf1_addr(uint8 ep, uint16 addr) { - usb_set_ep_rx_addr(ep, addr); -} - -static inline uint32* usb_ep_tx_buf0_count_ptr(uint8 ep) { - return usb_ep_tx_count_ptr(ep); -} - -static inline uint16 usb_get_ep_tx_buf0_count(uint8 ep) { - return usb_get_ep_tx_count(ep); -} - -static inline void usb_set_ep_tx_buf0_count(uint8 ep, uint16 count) { - usb_set_ep_tx_count(ep, count); -} - -static inline uint32* usb_ep_tx_buf1_count_ptr(uint8 ep) { - return usb_ep_rx_count_ptr(ep); -} - -static inline uint16 usb_get_ep_tx_buf1_count(uint8 ep) { - return usb_get_ep_rx_count(ep); -} - -static inline void usb_set_ep_tx_buf1_count(uint8 ep, uint16 count) { - usb_set_ep_rx_count(ep, count); -} -static inline uint32* usb_get_ep_rx_buf0_addr_ptr(uint8 ep) { - return usb_ep_tx_addr_ptr(ep); -} - -static inline uint16 usb_get_ep_rx_buf0_addr(uint8 ep) { - return usb_get_ep_tx_addr(ep); -} - -static inline void usb_set_ep_rx_buf0_addr(uint8 ep, uint16 addr) { - usb_set_ep_tx_addr(ep, addr); -} - -static inline uint32* usb_get_ep_rx_buf1_addr_ptr(uint8 ep) { - return usb_ep_rx_addr_ptr(ep); -} - -static inline uint16 usb_get_ep_rx_buf1_addr(uint8 ep) { - return usb_get_ep_rx_addr(ep); -} - -static inline void usb_set_ep_rx_buf1_addr(uint8 ep, uint16 addr) { - usb_set_ep_rx_addr(ep, addr); -} - -static inline uint32* usb_ep_rx_buf0_count_ptr(uint8 ep) { - return usb_ep_tx_count_ptr(ep); -} - -static inline uint16 usb_get_ep_rx_buf0_count(uint8 ep) { - return usb_get_ep_tx_count(ep); -} - -void usb_set_ep_rx_buf0_count(uint8 ep, uint16 count); - -static inline uint32* usb_ep_rx_buf1_count_ptr(uint8 ep) { - return usb_ep_rx_count_ptr(ep); -} - -static inline uint16 usb_get_ep_rx_buf1_count(uint8 ep) { - return usb_get_ep_rx_count(ep); -} - -static inline void usb_set_ep_rx_buf1_count(uint8 ep, uint16 count) { - usb_set_ep_rx_count(ep, count); -} - -/* - * Misc. types - */ - -typedef enum usb_ep { - USB_EP0, - USB_EP1, - USB_EP2, - USB_EP3, - USB_EP4, - USB_EP5, - USB_EP6, - USB_EP7, -} usb_ep; - -typedef enum usb_ep_type { - USB_EP_T_CTL = USB_EP_EP_TYPE_CONTROL, - USB_EP_T_BULK = USB_EP_EP_TYPE_BULK, - USB_EP_T_INT = USB_EP_EP_TYPE_INTERRUPT, - USB_EP_T_ISO = USB_EP_EP_TYPE_ISO -} usb_ep_type; - -typedef enum usb_ep_stat { - USB_EP_ST_RX_DIS = USB_EP_STAT_RX_DISABLED, - USB_EP_ST_RX_STL = USB_EP_STAT_RX_STALL, - USB_EP_ST_RX_NAK = USB_EP_STAT_RX_NAK, - USB_EP_ST_RX_VAL = USB_EP_STAT_RX_VALID, - USB_EP_ST_TX_DIS = USB_EP_STAT_TX_DISABLED, - USB_EP_ST_TX_STL = USB_EP_STAT_TX_STALL, - USB_EP_ST_TX_NAK = USB_EP_STAT_TX_NAK, - USB_EP_ST_TX_VAL = USB_EP_STAT_TX_VALID -} usb_ep_stat; - -#endif diff --git a/STM32F3/cores/maple/libmaple/util.c b/STM32F3/cores/maple/libmaple/util.c deleted file mode 100644 index 4c0b2c8ec..000000000 --- a/STM32F3/cores/maple/libmaple/util.c +++ /dev/null @@ -1,150 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/util.c - * @brief Utility procedures for debugging - */ - -#include -#include -#include -#include - -/* (Undocumented) hooks used by Wirish to direct our behavior here */ -extern __weak void __lm_error(void); -extern __weak usart_dev* __lm_enable_error_usart(void); - -/* If you define ERROR_LED_PORT and ERROR_LED_PIN, then a failed - * ASSERT() will also throb() an LED connected to that port and pin. - */ -#if defined(ERROR_LED_PORT) && defined(ERROR_LED_PIN) -#define HAVE_ERROR_LED -#endif - -/* (Called from exc.S with global interrupts disabled.) */ -__attribute__((noreturn)) void __error(void) { - if (__lm_error) { - __lm_error(); - } - /* Reenable global interrupts */ - nvic_globalirq_enable(); - throb(); -} - -/* - * Print an error message on a UART upon a failed assertion (if one is - * available), and punt to __error(). - * - * @param file Source file of failed assertion - * @param line Source line of failed assertion - * @param exp String representation of failed assertion - * @sideeffect Turns of all peripheral interrupts except USB. - */ -void _fail(const char* file, int line, const char* exp) { - if (__lm_enable_error_usart) { - /* Initialize the error USART */ - usart_dev *err_usart = __lm_enable_error_usart(); - - /* Print failed assert message */ - usart_putstr(err_usart, "ERROR: FAILED ASSERT("); - usart_putstr(err_usart, exp); - usart_putstr(err_usart, "): "); - usart_putstr(err_usart, file); - usart_putstr(err_usart, ": "); - usart_putudec(err_usart, line); - usart_putc(err_usart, '\n'); - usart_putc(err_usart, '\r'); - } - /* Shutdown and error fade */ - __error(); -} - -/* - * Provide an __assert_func handler to libc so that calls to assert() - * get redirected to _fail. - */ -void __assert_func(const char* file, int line, const char* method, - const char* expression) { - _fail(file, line, expression); -} - -/* - * Provide an abort() implementation that aborts execution and punts - * to __error(). - */ -void abort() { - if (__lm_enable_error_usart) { - /* Initialize the error USART */ - usart_dev *err_usart = __lm_enable_error_usart(); - /* Print abort message. */ - usart_putstr(err_usart, "ERROR: PROGRAM ABORTED VIA abort()\r\n"); - } - - /* Shutdown and error fade */ - __error(); -} - -/* This was public as of v0.0.12, so we've got to keep it public. */ -/** - * @brief Fades the error LED on and off - * @sideeffect Sets output push-pull on ERROR_LED_PIN. - */ -__attribute__((noreturn)) void throb(void) { -#ifdef HAVE_ERROR_LED - int32 slope = 1; - uint32 CC = 0x0000; - uint32 TOP_CNT = 0x0200; - uint32 i = 0; - - gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT); - /* Error fade. */ - while (1) { - if (CC == TOP_CNT) { - slope = -1; - } else if (CC == 0) { - slope = 1; - } - - if (i == TOP_CNT) { - CC += slope; - i = 0; - } - - if (i < CC) { - gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 1); - } else { - gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 0); - } - i++; - } -#else - /* No error LED is defined; do nothing. */ - while (1) - ; -#endif -} diff --git a/STM32F3/cores/maple/main.cpp b/STM32F3/cores/maple/main.cpp deleted file mode 100644 index 7305100d9..000000000 --- a/STM32F3/cores/maple/main.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -extern void setup(void); -extern void loop(void); -extern void init(void); - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. - __attribute__(( constructor )) void premain() { - init(); -} - -int main(void) { - setup(); - - while (1) { - loop(); - } - return 0; -} diff --git a/STM32F3/cores/maple/wirish/HardwareSPI.cpp b/STM32F3/cores/maple/wirish/HardwareSPI.cpp deleted file mode 100644 index 60d210fbc..000000000 --- a/STM32F3/cores/maple/wirish/HardwareSPI.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @author Marti Bolivar - * @brief Wirish SPI implementation. - */ - -#include - -#include -#include -#include - -#include -#include - -#if CYCLES_PER_MICROSECOND != 72 -/* TODO [0.2.0?] something smarter than this */ -#warning "Unexpected clock speed; SPI frequency calculation will be incorrect" -#endif - -struct spi_pins { - uint8 nss; - uint8 sck; - uint8 miso; - uint8 mosi; -}; - -static const spi_pins* dev_to_spi_pins(spi_dev *dev); - -static void enable_device(spi_dev *dev, - bool as_master, - SPIFrequency frequency, - spi_cfg_flag endianness, - spi_mode mode); - -static const spi_pins board_spi_pins[] __FLASH__ = { - {BOARD_SPI1_NSS_PIN, - BOARD_SPI1_SCK_PIN, - BOARD_SPI1_MISO_PIN, - BOARD_SPI1_MOSI_PIN}, - {BOARD_SPI2_NSS_PIN, - BOARD_SPI2_SCK_PIN, - BOARD_SPI2_MISO_PIN, - BOARD_SPI2_MOSI_PIN}, -#if defined(STM32_HIGH_DENSITY) || (STM32_MCU_SERIES == STM32_SERIES_F3) - {BOARD_SPI3_NSS_PIN, - BOARD_SPI3_SCK_PIN, - BOARD_SPI3_MISO_PIN, - BOARD_SPI3_MOSI_PIN}, -#endif -}; - - -/* - * Constructor - */ - -HardwareSPI::HardwareSPI(uint32 spi_num) { - switch (spi_num) { - case 1: - this->spi_d = SPI1; - break; - case 2: - this->spi_d = SPI2; - break; -#if defined(STM32_HIGH_DENSITY) || (STM32_MCU_SERIES == STM32_SERIES_F3) - case 3: - this->spi_d = SPI3; - break; -#endif - default: - ASSERT(0); - } -} - -/* - * Set up/tear down - */ - -void HardwareSPI::begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode) { - if (mode >= 4) { - ASSERT(0); - return; - } - spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB; - spi_mode m = (spi_mode)mode; - enable_device(this->spi_d, true, frequency, end, m); -} - -void HardwareSPI::begin(void) { - this->begin(SPI_1_125MHZ, MSBFIRST, 0); -} - -void HardwareSPI::beginSlave(uint32 bitOrder, uint32 mode) { - if (mode >= 4) { - ASSERT(0); - return; - } - spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB; - spi_mode m = (spi_mode)mode; - enable_device(this->spi_d, false, (SPIFrequency)0, end, m); -} - -void HardwareSPI::beginSlave(void) { - this->beginSlave(MSBFIRST, 0); -} - -void HardwareSPI::end(void) { - if (!spi_is_enabled(this->spi_d)) { - return; - } - - // Follows RM0008's sequence for disabling a SPI in master/slave - // full duplex mode. - while (spi_is_rx_nonempty(this->spi_d)) { - // FIXME [0.1.0] remove this once you have an interrupt based driver - volatile uint16 rx __attribute__((unused)) = spi_rx_reg(this->spi_d); - } - while (!spi_is_tx_empty(this->spi_d)) - ; - while (spi_is_busy(this->spi_d)) - ; - spi_peripheral_disable(this->spi_d); -} - -/* - * I/O - */ - -uint8 HardwareSPI::read(void) { - uint8 buf[1]; - this->read(buf, 1); - return buf[0]; -} - -void HardwareSPI::read(uint8 *buf, uint32 len) { - uint32 rxed = 0; - while (rxed < len) { - while (!spi_is_rx_nonempty(this->spi_d)) - ; - buf[rxed++] = (uint8)spi_rx_reg(this->spi_d); - } -} - -void HardwareSPI::write(uint8 byte) { - this->write(&byte, 1); -} - -void HardwareSPI::write(const uint8 *data, uint32 length) { - uint32 txed = 0; - while (txed < length) { - txed += spi_tx(this->spi_d, data + txed, length - txed); - } -} - -uint8 HardwareSPI::transfer(uint8 byte) { - this->write(byte); - return this->read(); -} - -/* - * Pin accessors - */ - -uint8 HardwareSPI::misoPin(void) { - return dev_to_spi_pins(this->spi_d)->miso; -} - -uint8 HardwareSPI::mosiPin(void) { - return dev_to_spi_pins(this->spi_d)->mosi; -} - -uint8 HardwareSPI::sckPin(void) { - return dev_to_spi_pins(this->spi_d)->sck; -} - -uint8 HardwareSPI::nssPin(void) { - return dev_to_spi_pins(this->spi_d)->nss; -} - -/* - * Deprecated functions - */ - -uint8 HardwareSPI::send(uint8 data) { - uint8 buf[] = {data}; - return this->send(buf, 1); -} - -uint8 HardwareSPI::send(uint8 *buf, uint32 len) { - uint32 txed = 0; - uint8 ret = 0; - while (txed < len) { - this->write(buf[txed++]); - ret = this->read(); - } - return ret; -} - -uint8 HardwareSPI::recv(void) { - return this->read(); -} - -/* - * Auxiliary functions - */ - -static void configure_gpios(spi_dev *dev, bool as_master); -static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq); - -static const spi_pins* dev_to_spi_pins(spi_dev *dev) { - switch (dev->clk_id) { - case RCC_SPI1: return board_spi_pins; - case RCC_SPI2: return board_spi_pins + 1; -#if defined(STM32_HIGH_DENSITY) || (STM32_MCU_SERIES == STM32_SERIES_F3) - case RCC_SPI3: return board_spi_pins + 2; -#endif - default: return NULL; - } -} - -/* Enables the device in master or slave full duplex mode. If you - * change this code, you must ensure that appropriate changes are made - * to HardwareSPI::end(). */ -static void enable_device(spi_dev *dev, - bool as_master, - SPIFrequency freq, - spi_cfg_flag endianness, - spi_mode mode) { - spi_baud_rate baud = determine_baud_rate(dev, freq); - uint32 cfg_flags = (endianness | SPI_DFF_8_BIT | SPI_SW_SLAVE | - (as_master ? SPI_SOFT_SS : 0)); - - spi_init(dev); - configure_gpios(dev, as_master); - if (as_master) { - spi_master_enable(dev, baud, mode, cfg_flags); - } else { - spi_slave_enable(dev, mode, cfg_flags); - } -} - -static void disable_pwm(const stm32_pin_info *i) { - if (i->timer_device) { - timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED); - } -} - -static void configure_gpios(spi_dev *dev, bool as_master) { - const spi_pins *pins = dev_to_spi_pins(dev); - - if (!pins) { - return; - } - - const stm32_pin_info *nssi = &PIN_MAP[pins->nss]; - const stm32_pin_info *scki = &PIN_MAP[pins->sck]; - const stm32_pin_info *misoi = &PIN_MAP[pins->miso]; - const stm32_pin_info *mosii = &PIN_MAP[pins->mosi]; - - disable_pwm(nssi); - disable_pwm(scki); - disable_pwm(misoi); - disable_pwm(mosii); - - spi_config_gpios(dev, as_master, nssi->gpio_device, nssi->gpio_bit, - scki->gpio_device, scki->gpio_bit, misoi->gpio_bit, - mosii->gpio_bit); -} - -static const spi_baud_rate baud_rates[MAX_SPI_FREQS] __FLASH__ = { - SPI_BAUD_PCLK_DIV_2, - SPI_BAUD_PCLK_DIV_4, - SPI_BAUD_PCLK_DIV_8, - SPI_BAUD_PCLK_DIV_16, - SPI_BAUD_PCLK_DIV_32, - SPI_BAUD_PCLK_DIV_64, - SPI_BAUD_PCLK_DIV_128, - SPI_BAUD_PCLK_DIV_256, -}; - -/* - * Note: This assumes you're on a LeafLabs-style board - * (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz). - */ -static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq) { - if (rcc_dev_clk(dev->clk_id) == RCC_APB2 && freq == SPI_140_625KHZ) { - /* APB2 peripherals are too fast for 140.625 KHz */ - ASSERT(0); - return (spi_baud_rate)~0; - } - return (rcc_dev_clk(dev->clk_id) == RCC_APB2 ? - baud_rates[freq + 1] : - baud_rates[freq]); -} diff --git a/STM32F3/cores/maple/wirish/HardwareSPI.h b/STM32F3/cores/maple/wirish/HardwareSPI.h deleted file mode 100644 index 4b61b58cc..000000000 --- a/STM32F3/cores/maple/wirish/HardwareSPI.h +++ /dev/null @@ -1,225 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/include/wirish/HardwareSPI.h - * @brief High-level SPI interface - * - * This is a "bare essentials" polling driver for now. - */ - -/* TODO [0.1.0] Remove deprecated methods. */ - -#include -#include - -#include - -#ifndef _WIRISH_HARDWARESPI_H_ -#define _WIRISH_HARDWARESPI_H_ - -/** - * @brief Defines the possible SPI communication speeds. - */ -typedef enum SPIFrequency { - SPI_18MHZ = 0, /**< 18 MHz */ - SPI_9MHZ = 1, /**< 9 MHz */ - SPI_4_5MHZ = 2, /**< 4.5 MHz */ - SPI_2_25MHZ = 3, /**< 2.25 MHz */ - SPI_1_125MHZ = 4, /**< 1.125 MHz */ - SPI_562_500KHZ = 5, /**< 562.500 KHz */ - SPI_281_250KHZ = 6, /**< 281.250 KHz */ - SPI_140_625KHZ = 7, /**< 140.625 KHz */ -} SPIFrequency; - -#define MAX_SPI_FREQS 8 - -/** - * @brief Wirish SPI interface. - * - * This implementation uses software slave management, so the caller - * is responsible for controlling the slave select line. - */ -class HardwareSPI { -public: - /** - * @param spiPortNumber Number of the SPI port to manage. - */ - HardwareSPI(uint32 spiPortNumber); - - /* - * Set up/tear down - */ - - /** - * @brief Turn on a SPI port and set its GPIO pin modes for use as master. - * - * SPI port is enabled in full duplex mode, with software slave management. - * - * @param frequency Communication frequency - * @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST (big-endian) - * @param mode SPI mode to use, one of SPI_MODE_0, SPI_MODE_1, - * SPI_MODE_2, and SPI_MODE_3. - */ - void begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode); - - /** - * @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0). - */ - void begin(void); - - /** - * @brief Turn on a SPI port and set its GPIO pin modes for use as a slave. - * - * SPI port is enabled in full duplex mode, with software slave management. - * - * @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST(big-endian) - * @param mode SPI mode to use - */ - void beginSlave(uint32 bitOrder, uint32 mode); - - /** - * @brief Equivalent to beginSlave(MSBFIRST, 0). - */ - void beginSlave(void); - - /** - * @brief Disables the SPI port, but leaves its GPIO pin modes unchanged. - */ - void end(void); - - /* - * I/O - */ - - /** - * @brief Return the next unread byte. - * - * If there is no unread byte waiting, this function will block - * until one is received. - */ - uint8 read(void); - - /** - * @brief Read length bytes, storing them into buffer. - * @param buffer Buffer to store received bytes into. - * @param length Number of bytes to store in buffer. This - * function will block until the desired number of - * bytes have been read. - */ - void read(uint8 *buffer, uint32 length); - - /** - * @brief Transmit a byte. - * @param data Byte to transmit. - */ - void write(uint8 data); - - /** - * @brief Transmit multiple bytes. - * @param buffer Bytes to transmit. - * @param length Number of bytes in buffer to transmit. - */ - void write(const uint8 *buffer, uint32 length); - - /** - * @brief Transmit a byte, then return the next unread byte. - * - * This function transmits before receiving. - * - * @param data Byte to transmit. - * @return Next unread byte. - */ - uint8 transfer(uint8 data); - - /* - * Pin accessors - */ - - /** - * @brief Return the number of the MISO (master in, slave out) pin - */ - uint8 misoPin(void); - - /** - * @brief Return the number of the MOSI (master out, slave in) pin - */ - uint8 mosiPin(void); - - /** - * @brief Return the number of the SCK (serial clock) pin - */ - uint8 sckPin(void); - - /** - * @brief Return the number of the NSS (slave select) pin - */ - uint8 nssPin(void); - - /* Escape hatch */ - - /** - * @brief Get a pointer to the underlying libmaple spi_dev for - * this HardwareSPI instance. - */ - spi_dev* c_dev(void) { return this->spi_d; } - - /* -- The following methods are deprecated --------------------------- */ - - /** - * @brief Deprecated. - * - * Use HardwareSPI::transfer() instead. - * - * @see HardwareSPI::transfer() - */ - uint8 send(uint8 data); - - /** - * @brief Deprecated. - * - * Use HardwareSPI::write() in combination with - * HardwareSPI::read() (or HardwareSPI::transfer()) instead. - * - * @see HardwareSPI::write() - * @see HardwareSPI::read() - * @see HardwareSPI::transfer() - */ - uint8 send(uint8 *data, uint32 length); - - /** - * @brief Deprecated. - * - * Use HardwareSPI::read() instead. - * - * @see HardwareSPI::read() - */ - uint8 recv(void); -private: - spi_dev *spi_d; -}; - -#endif diff --git a/STM32F3/cores/maple/wirish/HardwareSerial.cpp b/STM32F3/cores/maple/wirish/HardwareSerial.cpp deleted file mode 100644 index 87f80d1bd..000000000 --- a/STM32F3/cores/maple/wirish/HardwareSerial.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/HardwareSerial.cpp - * @brief Wirish serial port implementation. - */ - -#include - -#include -#include -#include -#include - -#define DEFINE_HWSERIAL(name, n) \ - HardwareSerial name(USART##n, \ - BOARD_USART##n##_TX_PIN, \ - BOARD_USART##n##_RX_PIN) - -#if BOARD_HAVE_USART1 -DEFINE_HWSERIAL(Serial1, 1); -#endif -#if BOARD_HAVE_USART2 -DEFINE_HWSERIAL(Serial2, 2); -#endif -#if BOARD_HAVE_USART3 -DEFINE_HWSERIAL(Serial3, 3); -#endif -#if BOARD_HAVE_UART4 -DEFINE_HWSERIAL(Serial4, 4); -#endif -#if BOARD_HAVE_UART5 -DEFINE_HWSERIAL(Serial5, 5); -#endif -#if BOARD_HAVE_USART6 -DEFINE_HWSERIAL(Serial6, 6); -#endif - -HardwareSerial::HardwareSerial(usart_dev *usart_device, - uint8 tx_pin, - uint8 rx_pin) { - this->usart_device = usart_device; - this->tx_pin = tx_pin; - this->rx_pin = rx_pin; -} - -/* - * Set up/tear down - */ - -#if STM32_MCU_SERIES == STM32_SERIES_F1 -/* F1 MCUs have no GPIO_AFR[HL], so turn off PWM if there's a conflict - * on this GPIO bit. */ -static void disable_timer_if_necessary(timer_dev *dev, uint8 ch) { - if (dev != NULL) { - timer_set_mode(dev, ch, TIMER_DISABLED); - } -} -#elif (STM32_MCU_SERIES == STM32_SERIES_F2) || \ - (STM32_MCU_SERIES == STM32_SERIES_F3) || \ - (STM32_MCU_SERIES == STM32_SERIES_F4) -#define disable_timer_if_necessary(dev, ch) ((void)0) -#else -#warning "Unsupported STM32 series; timer conflicts are possible" -#endif - -void HardwareSerial::begin(uint32 baud) { - ASSERT(baud <= this->usart_device->max_baud); - - if (baud > this->usart_device->max_baud) { - return; - } - - const stm32_pin_info *txi = &PIN_MAP[this->tx_pin]; - const stm32_pin_info *rxi = &PIN_MAP[this->rx_pin]; - - disable_timer_if_necessary(txi->timer_device, txi->timer_channel); - - usart_config_gpios_async(this->usart_device, - rxi->gpio_device, rxi->gpio_bit, - txi->gpio_device, txi->gpio_bit, - 0); - usart_init(this->usart_device); - usart_set_baud_rate(this->usart_device, USART_USE_PCLK, baud); - usart_enable(this->usart_device); -} - -void HardwareSerial::end(void) { - usart_disable(this->usart_device); -} - -/* - * I/O - */ - -int HardwareSerial::read(void) { - if(usart_data_available(usart_device) > 0) { - return usart_getc(usart_device); - } else { - return -1; - } -} - -uint32 HardwareSerial::available(void) { - return usart_data_available(this->usart_device); -} - -void HardwareSerial::write(unsigned char ch) { - usart_putc(this->usart_device, ch); -} - -void HardwareSerial::flush(void) { - usart_reset_rx(this->usart_device); -} diff --git a/STM32F3/cores/maple/wirish/HardwareSerial.h b/STM32F3/cores/maple/wirish/HardwareSerial.h deleted file mode 100644 index 260a99e5b..000000000 --- a/STM32F3/cores/maple/wirish/HardwareSerial.h +++ /dev/null @@ -1,102 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/include/wirish/HardwareSerial.h - * @brief Wirish serial port interface. - */ - -#ifndef _WIRISH_HARDWARESERIAL_H_ -#define _WIRISH_HARDWARESERIAL_H_ - -#include - -#include -#include - -/* - * IMPORTANT: - * - * This class documented "by hand" (i.e., not using Doxygen) in the - * leaflabs-docs/ repository. - * - * If you alter the public HardwareSerial interface, you MUST update - * the documentation accordingly. - */ - -struct usart_dev; - -class HardwareSerial : public Print { -public: - HardwareSerial(struct usart_dev *usart_device, - uint8 tx_pin, - uint8 rx_pin); - - /* Set up/tear down */ - void begin(uint32 baud); - void end(void); - - /* I/O */ - uint32 available(void); - int read(void); - void flush(void); - virtual void write(unsigned char); - using Print::write; - - /* Pin accessors */ - int txPin(void) { return this->tx_pin; } - int rxPin(void) { return this->rx_pin; } - - /* Escape hatch into libmaple */ - /* FIXME [0.0.13] documentation */ - struct usart_dev* c_dev(void) { return this->usart_device; } -private: - struct usart_dev *usart_device; - uint8 tx_pin; - uint8 rx_pin; -}; - -#if BOARD_HAVE_USART1 -extern HardwareSerial Serial1; -#endif -#if BOARD_HAVE_USART2 -extern HardwareSerial Serial2; -#endif -#if BOARD_HAVE_USART3 -extern HardwareSerial Serial3; -#endif -#if BOARD_HAVE_UART4 -extern HardwareSerial Serial4; -#endif -#if BOARD_HAVE_UART5 -extern HardwareSerial Serial5; -#endif -#if BOARD_HAVE_USART6 -extern HardwareSerial Serial6; -#endif - -#endif diff --git a/STM32F3/cores/maple/wirish/HardwareTimer.cpp b/STM32F3/cores/maple/wirish/HardwareTimer.cpp deleted file mode 100644 index 4f68ad724..000000000 --- a/STM32F3/cores/maple/wirish/HardwareTimer.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include - -#include -#include // for noInterrupts(), interrupts() -#include -#include // for CYCLES_PER_MICROSECOND - -// TODO [0.1.0] Remove deprecated pieces - -/* - * Evil hack to infer this->dev from timerNum in the HardwareTimer - * constructor. See: - * - * http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2 - * http://yosefk.com/c++fqa/function.html#fqa-33.2 - */ - -extern "C" { - static timer_dev **this_devp; - static rcc_clk_id this_id; - static void set_this_dev(timer_dev *dev) { - if (dev->clk_id == this_id) { - *this_devp = dev; - } - } -} - -/* - * HardwareTimer routines - */ - -HardwareTimer::HardwareTimer(uint8 timerNum) { - rcc_clk_id timerID = (rcc_clk_id)(RCC_TIMER1 + (timerNum - 1)); - this->dev = NULL; - noInterrupts(); // Hack to ensure we're the only ones using - // set_this_dev() and friends. TODO: use a lock. - this_id = timerID; - this_devp = &this->dev; - timer_foreach(set_this_dev); - interrupts(); - ASSERT(this->dev != NULL); -} - -void HardwareTimer::pause(void) { - timer_pause(this->dev); -} - -void HardwareTimer::resume(void) { - timer_resume(this->dev); -} - -uint32 HardwareTimer::getPrescaleFactor(void) { - return timer_get_prescaler(this->dev) + 1; -} - -void HardwareTimer::setPrescaleFactor(uint32 factor) { - timer_set_prescaler(this->dev, (uint16)(factor - 1)); -} - -uint16 HardwareTimer::getOverflow() { - return timer_get_reload(this->dev); -} - -void HardwareTimer::setOverflow(uint16 val) { - timer_set_reload(this->dev, val); -} - -uint16 HardwareTimer::getCount(void) { - return timer_get_count(this->dev); -} - -void HardwareTimer::setCount(uint16 val) { - uint16 ovf = this->getOverflow(); - timer_set_count(this->dev, min(val, ovf)); -} - -#define MAX_RELOAD ((1 << 16) - 1) -uint16 HardwareTimer::setPeriod(uint32 microseconds) { - // Not the best way to handle this edge case? - if (!microseconds) { - this->setPrescaleFactor(1); - this->setOverflow(1); - return this->getOverflow(); - } - - uint32 period_cyc = microseconds * CYCLES_PER_MICROSECOND; - uint16 prescaler = (uint16)(period_cyc / MAX_RELOAD + 1); - uint16 overflow = (uint16)((period_cyc + (prescaler / 2)) / prescaler); - this->setPrescaleFactor(prescaler); - this->setOverflow(overflow); - return overflow; -} - -void HardwareTimer::setMode(int channel, timer_mode mode) { - timer_set_mode(this->dev, (uint8)channel, (timer_mode)mode); -} - -uint16 HardwareTimer::getCompare(int channel) { - return timer_get_compare(this->dev, (uint8)channel); -} - -void HardwareTimer::setCompare(int channel, uint16 val) { - uint16 ovf = this->getOverflow(); - timer_set_compare(this->dev, (uint8)channel, min(val, ovf)); -} - -void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) { - timer_attach_interrupt(this->dev, (uint8)channel, handler); -} - -void HardwareTimer::detachInterrupt(int channel) { - timer_detach_interrupt(this->dev, (uint8)channel); -} - -void HardwareTimer::refresh(void) { - timer_generate_update(this->dev); -} - -/* -- Deprecated predefined instances -------------------------------------- */ - -HardwareTimer Timer1(1); -HardwareTimer Timer2(2); -HardwareTimer Timer3(3); -HardwareTimer Timer4(4); -#ifdef STM32_HIGH_DENSITY -HardwareTimer Timer5(5); -HardwareTimer Timer6(6); -HardwareTimer Timer7(7); -HardwareTimer Timer8(8); -#endif diff --git a/STM32F3/cores/maple/wirish/HardwareTimer.h b/STM32F3/cores/maple/wirish/HardwareTimer.h deleted file mode 100644 index 22aa01012..000000000 --- a/STM32F3/cores/maple/wirish/HardwareTimer.h +++ /dev/null @@ -1,337 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief Wirish timer class. - */ - -#ifndef _WIRISH_HARDWARETIMER_H_ -#define _WIRISH_HARDWARETIMER_H_ - -// TODO [0.1.0] Remove deprecated pieces, pick a better API - -#include - -/** Timer mode. */ -typedef timer_mode TimerMode; - -/** - * @brief Interface to one of the 16-bit timer peripherals. - */ -class HardwareTimer { -private: - timer_dev *dev; - -public: - /** - * @brief Construct a new HardwareTimer instance. - * @param timerNum number of the timer to control. - */ - HardwareTimer(uint8 timerNum); - - /** - * @brief Stop the counter, without affecting its configuration. - * - * @see HardwareTimer::resume() - */ - void pause(void); - - /** - * @brief Resume a paused timer, without affecting its configuration. - * - * The timer will resume counting and firing interrupts as - * appropriate. - * - * Note that there is some function call overhead associated with - * using this method, so using it in concert with - * HardwareTimer::pause() is not a robust way to align multiple - * timers to the same count value. - * - * @see HardwareTimer::pause() - */ - void resume(void); - - /** - * @brief Get the timer's prescale factor. - * @return Timer prescaler, from 1 to 65,536. - * @see HardwareTimer::setPrescaleFactor() - */ - uint32 getPrescaleFactor(); - - /** - * @brief Set the timer's prescale factor. - * - * The new value won't take effect until the next time the counter - * overflows. You can force the counter to reset using - * HardwareTimer::refresh(). - * - * @param factor The new prescale value to set, from 1 to 65,536. - * @see HardwareTimer::refresh() - */ - void setPrescaleFactor(uint32 factor); - - /** - * @brief Get the timer overflow value. - * @see HardwareTimer::setOverflow() - */ - uint16 getOverflow(); - - /** - * @brief Set the timer overflow (or "reload") value. - * - * The new value won't take effect until the next time the counter - * overflows. You can force the counter to reset using - * HardwareTimer::refresh(). - * - * @param val The new overflow value to set - * @see HardwareTimer::refresh() - */ - void setOverflow(uint16 val); - - /** - * @brief Get the current timer count. - * - * @return The timer's current count value - */ - uint16 getCount(void); - - /** - * @brief Set the current timer count. - * - * @param val The new count value to set. If this value exceeds - * the timer's overflow value, it is truncated to the - * overflow value. - */ - void setCount(uint16 val); - - /** - * @brief Set the timer's period in microseconds. - * - * Configures the prescaler and overflow values to generate a timer - * reload with a period as close to the given number of - * microseconds as possible. - * - * @param microseconds The desired period of the timer. This must be - * greater than zero. - * @return The new overflow value. - */ - uint16 setPeriod(uint32 microseconds); - - /** - * @brief Configure a timer channel's mode. - * @param channel Timer channel, from 1 to 4 - * @param mode Mode to set - */ - void setMode(int channel, timer_mode mode); - - /** - * @brief Get the compare value for the given channel. - * @see HardwareTimer::setCompare() - */ - uint16 getCompare(int channel); - - /** - * @brief Set the compare value for the given channel. - * - * @param channel the channel whose compare to set, from 1 to 4. - * @param compare The compare value to set. If greater than this - * timer's overflow value, it will be truncated to - * the overflow value. - * - * @see timer_mode - * @see HardwareTimer::setMode() - * @see HardwareTimer::attachInterrupt() - */ - void setCompare(int channel, uint16 compare); - - /** - * @brief Attach an interrupt handler to the given channel. - * - * This interrupt handler will be called when the timer's counter - * reaches the given channel compare value. - * - * @param channel the channel to attach the ISR to, from 1 to 4. - * @param handler The ISR to attach to the given channel. - * @see voidFuncPtr - */ - void attachInterrupt(int channel, voidFuncPtr handler); - - /** - * @brief Remove the interrupt handler attached to the given - * channel, if any. - * - * The handler will no longer be called by this timer. - * - * @param channel the channel whose interrupt to detach, from 1 to 4. - * @see HardwareTimer::attachInterrupt() - */ - void detachInterrupt(int channel); - - /** - * @brief Reset the counter, and update the prescaler and overflow - * values. - * - * This will reset the counter to 0 in upcounting mode (the - * default). It will also update the timer's prescaler and - * overflow, if you have set them up to be changed using - * HardwareTimer::setPrescaleFactor() or - * HardwareTimer::setOverflow(). - * - * @see HardwareTimer::setPrescaleFactor() - * @see HardwareTimer::setOverflow() - */ - void refresh(void); - - /* Escape hatch */ - - /** - * @brief Get a pointer to the underlying libmaple timer_dev for - * this HardwareTimer instance. - */ - timer_dev* c_dev(void) { return this->dev; } - -/* -- The rest of this file is deprecated. --------------------------------- */ - - /** @brief Deprecated; use setMode(channel, mode) instead. */ - void setChannelMode(int channel, timer_mode mode) { - setMode(channel, mode); - } - - /** @brief Deprecated; use setMode(TIMER_CH1, mode) instead. */ - void setChannel1Mode(timer_mode mode) { setMode(TIMER_CH1, mode); } - - /** @brief Deprecated; use setMode(TIMER_CH2, mode) instead. */ - void setChannel2Mode(timer_mode mode) { setMode(TIMER_CH2, mode); } - - /** @brief Deprecated; use setMode(TIMER_CH3, mode) instead. */ - void setChannel3Mode(timer_mode mode) { setMode(TIMER_CH3, mode); } - - /** @brief Deprecated; use setMode(TIMER_CH4, mode) instead. */ - void setChannel4Mode(timer_mode mode) { setMode(TIMER_CH4, mode); } - - /** @brief Deprecated; use return getCompare(TIMER_CH1) instead. */ - uint16 getCompare1() { return getCompare(TIMER_CH1); } - - /** @brief Deprecated; use return getCompare(TIMER_CH2) instead. */ - uint16 getCompare2() { return getCompare(TIMER_CH2); } - - /** @brief Deprecated; use return getCompare(TIMER_CH3) instead. */ - uint16 getCompare3() { return getCompare(TIMER_CH3); } - - /** @brief Deprecated; use return getCompare(TIMER_CH4) instead. */ - uint16 getCompare4() { return getCompare(TIMER_CH4); } - - /** @brief Deprecated; use setCompare(TIMER_CH1, compare) instead. */ - void setCompare1(uint16 compare) { setCompare(TIMER_CH1, compare); } - - /** @brief Deprecated; use setCompare(TIMER_CH2, compare) instead. */ - void setCompare2(uint16 compare) { setCompare(TIMER_CH2, compare); } - - /** @brief Deprecated; use setCompare(TIMER_CH3, compare) instead. */ - void setCompare3(uint16 compare) { setCompare(TIMER_CH3, compare); } - - /** @brief Deprecated; use setCompare(TIMER_CH4, compare) instead. */ - void setCompare4(uint16 compare) { setCompare(TIMER_CH4, compare); } - - /** @brief Deprecated; use attachInterrupt(TIMER_CH1, handler) instead. */ - void attachCompare1Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH1, handler); - } - - /** @brief Deprecated; use attachInterrupt(TIMER_CH2, handler) instead. */ - void attachCompare2Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH2, handler); - } - - /** @brief Deprecated; use attachInterrupt(TIMER_CH3, handler) instead. */ - void attachCompare3Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH3, handler); - } - - /** @brief Deprecated; use attachInterrupt(TIMER_CH4, handler) instead. */ - void attachCompare4Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH4, handler); - } - - /** @brief Deprecated; use detachInterrupt(TIMER_CH1) instead. */ - void detachCompare1Interrupt(void) { detachInterrupt(TIMER_CH1); } - - /** @brief Deprecated; use detachInterrupt(TIMER_CH2) instead. */ - void detachCompare2Interrupt(void) { detachInterrupt(TIMER_CH2); } - - /** @brief Deprecated; use detachInterrupt(TIMER_CH3) instead. */ - void detachCompare3Interrupt(void) { detachInterrupt(TIMER_CH3); } - - /** @brief Deprecated; use detachInterrupt(TIMER_CH4) instead. */ - void detachCompare4Interrupt(void) { detachInterrupt(TIMER_CH4); } - - /** @brief Deprecated; use refresh() instead. */ - void generateUpdate(void) { refresh(); } -}; - -/** @brief Deprecated; use TIMER_OUTPUT_COMPARE instead. */ -#define TIMER_OUTPUTCOMPARE TIMER_OUTPUT_COMPARE - -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer1; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer2; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer3; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer4; -#if (STM32_MCU_SERIES == STM32_SERIES_F1) && defined(STM32_HIGH_DENSITY) -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer5; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer8; -#endif - -#endif diff --git a/STM32F3/cores/maple/wirish/Print.cpp b/STM32F3/cores/maple/wirish/Print.cpp deleted file mode 100644 index 9a8808dd3..000000000 --- a/STM32F3/cores/maple/wirish/Print.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Print.cpp - Base class that provides print() and println() - * Copyright (c) 2008 David A. Mellis. All right reserved. - * Copyright (c) 2011 LeafLabs, LLC. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - * Modified 23 November 2006 by David A. Mellis - * Modified 12 April 2011 by Marti Bolivar - */ - -#include - -#include -#include - -#ifndef LLONG_MAX -/* - * Note: - * - * At time of writing (12 April 2011), the limits.h that came with the - * newlib we distributed didn't include LLONG_MAX. Because we're - * staying away from using templates (see /notes/coding_standard.rst, - * "Language Features and Compiler Extensions"), this value was - * copy-pasted from a println() of the value - * - * std::numeric_limits::max(). - */ -#define LLONG_MAX 9223372036854775807LL -#endif - -/* - * Public methods - */ - -void Print::write(const char *str) { - while (*str) { - write(*str++); - } -} - -void Print::write(const void *buffer, uint32 size) { - uint8 *ch = (uint8*)buffer; - while (size--) { - write(*ch++); - } -} - -void Print::print(uint8 b, int base) { - print((uint64)b, base); -} - -void Print::print(char c) { - write(c); -} - -void Print::print(const char str[]) { - write(str); -} - -void Print::print(int n, int base) { - print((long long)n, base); -} - -void Print::print(unsigned int n, int base) { - print((unsigned long long)n, base); -} - -void Print::print(long n, int base) { - print((long long)n, base); -} - -void Print::print(unsigned long n, int base) { - print((unsigned long long)n, base); -} - -void Print::print(long long n, int base) { - if (n < 0) { - print('-'); - n = -n; - } - printNumber(n, base); -} - -void Print::print(unsigned long long n, int base) { - printNumber(n, base); -} - -void Print::print(double n, int digits) { - printFloat(n, digits); -} - -void Print::println(void) { - print('\r'); - print('\n'); -} - -void Print::println(char c) { - print(c); - println(); -} - -void Print::println(const char c[]) { - print(c); - println(); -} - -void Print::println(uint8 b, int base) { - print(b, base); - println(); -} - -void Print::println(int n, int base) { - print(n, base); - println(); -} - -void Print::println(unsigned int n, int base) { - print(n, base); - println(); -} - -void Print::println(long n, int base) { - print((long long)n, base); - println(); -} - -void Print::println(unsigned long n, int base) { - print((unsigned long long)n, base); - println(); -} - -void Print::println(long long n, int base) { - print(n, base); - println(); -} - -void Print::println(unsigned long long n, int base) { - print(n, base); - println(); -} - -void Print::println(double n, int digits) { - print(n, digits); - println(); -} - -/* - * Private methods - */ - -void Print::printNumber(unsigned long long n, uint8 base) { - unsigned char buf[CHAR_BIT * sizeof(long long)]; - unsigned long i = 0; - - if (n == 0) { - print('0'); - return; - } - - while (n > 0) { - buf[i++] = n % base; - n /= base; - } - - for (; i > 0; i--) { - print((char)(buf[i - 1] < 10 ? - '0' + buf[i - 1] : - 'A' + buf[i - 1] - 10)); - } -} - -/* According to snprintf(), - * - * nextafter((double)numeric_limits::max(), 0.0) ~= 9.22337e+18 - * - * This slightly smaller value was picked semi-arbitrarily. */ -#define LARGE_DOUBLE_TRESHOLD (9.1e18) - -/* THIS FUNCTION SHOULDN'T BE USED IF YOU NEED ACCURATE RESULTS. - * - * This implementation is meant to be simple and not occupy too much - * code size. However, printing floating point values accurately is a - * subtle task, best left to a well-tested library function. - * - * See Steele and White 2003 for more details: - * - * http://kurtstephens.com/files/p372-steele.pdf - */ -void Print::printFloat(double number, uint8 digits) { - // Hackish fail-fast behavior for large-magnitude doubles - if (abs(number) >= LARGE_DOUBLE_TRESHOLD) { - if (number < 0.0) { - print('-'); - } - print(""); - return; - } - - // Handle negative numbers - if (number < 0.0) { - print('-'); - number = -number; - } - - // Simplistic rounding strategy so that e.g. print(1.999, 2) - // prints as "2.00" - double rounding = 0.5; - for (uint8 i = 0; i < digits; i++) { - rounding /= 10.0; - } - number += rounding; - - // Extract the integer part of the number and print it - long long int_part = (long long)number; - double remainder = number - int_part; - print(int_part); - - // Print the decimal point, but only if there are digits beyond - if (digits > 0) { - print("."); - } - - // Extract digits from the remainder one at a time - while (digits-- > 0) { - remainder *= 10.0; - int to_print = (int)remainder; - print(to_print); - remainder -= to_print; - } -} diff --git a/STM32F3/cores/maple/wirish/Print.h b/STM32F3/cores/maple/wirish/Print.h deleted file mode 100644 index 52203eae0..000000000 --- a/STM32F3/cores/maple/wirish/Print.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Print.h - Base class that provides print() and println() - * Copyright (c) 2008 David A. Mellis. All right reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA. - * - * Modified 12 April 2011 by Marti Bolivar - */ - -#ifndef _WIRISH_PRINT_H_ -#define _WIRISH_PRINT_H_ - -#include - -enum { - BIN = 2, - OCT = 8, - DEC = 10, - HEX = 16 -}; - -class Print { -public: - virtual void write(uint8 ch) = 0; - virtual void write(const char *str); - virtual void write(const void *buf, uint32 len); - void print(char); - void print(const char[]); - void print(uint8, int=DEC); - void print(int, int=DEC); - void print(unsigned int, int=DEC); - void print(long, int=DEC); - void print(unsigned long, int=DEC); - void print(long long, int=DEC); - void print(unsigned long long, int=DEC); - void print(double, int=2); - void println(void); - void println(char); - void println(const char[]); - void println(uint8, int=DEC); - void println(int, int=DEC); - void println(unsigned int, int=DEC); - void println(long, int=DEC); - void println(unsigned long, int=DEC); - void println(long long, int=DEC); - void println(unsigned long long, int=DEC); - void println(double, int=2); -private: - void printNumber(unsigned long long, uint8); - void printFloat(double, uint8); -}; - -#endif diff --git a/STM32F3/cores/maple/wirish/bit_constants.h b/STM32F3/cores/maple/wirish/bit_constants.h deleted file mode 100644 index 4638f7635..000000000 --- a/STM32F3/cores/maple/wirish/bit_constants.h +++ /dev/null @@ -1,579 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief BIT[n] and binary literal defines, for Arduino - * compatibility. - */ - -#ifndef _WIRISH_BIT_CONSTANTS_H_ -#define _WIRISH_BIT_CONSTANTS_H_ - -#define BIT0 (1 << 0) -#define BIT1 (1 << 1) -#define BIT2 (1 << 2) -#define BIT3 (1 << 3) -#define BIT4 (1 << 4) -#define BIT5 (1 << 5) -#define BIT6 (1 << 6) -#define BIT7 (1 << 7) -#define BIT8 (1 << 8) -#define BIT9 (1 << 9) -#define BIT10 (1 << 10) -#define BIT11 (1 << 11) -#define BIT12 (1 << 12) -#define BIT13 (1 << 13) -#define BIT14 (1 << 14) -#define BIT15 (1 << 15) -#define BIT16 (1 << 16) -#define BIT17 (1 << 17) -#define BIT18 (1 << 18) -#define BIT19 (1 << 19) -#define BIT20 (1 << 20) -#define BIT21 (1 << 21) -#define BIT22 (1 << 22) -#define BIT23 (1 << 23) -#define BIT24 (1 << 24) -#define BIT25 (1 << 25) -#define BIT26 (1 << 26) -#define BIT27 (1 << 27) -#define BIT28 (1 << 28) -#define BIT29 (1 << 29) -#define BIT30 (1 << 30) -#define BIT31 (1 << 31) - -#define B0 0 -#define B00 0 -#define B000 0 -#define B0000 0 -#define B00000 0 -#define B000000 0 -#define B0000000 0 -#define B00000000 0 -#define B1 1 -#define B01 1 -#define B001 1 -#define B0001 1 -#define B00001 1 -#define B000001 1 -#define B0000001 1 -#define B00000001 1 -#define B10 2 -#define B010 2 -#define B0010 2 -#define B00010 2 -#define B000010 2 -#define B0000010 2 -#define B00000010 2 -#define B11 3 -#define B011 3 -#define B0011 3 -#define B00011 3 -#define B000011 3 -#define B0000011 3 -#define B00000011 3 -#define B100 4 -#define B0100 4 -#define B00100 4 -#define B000100 4 -#define B0000100 4 -#define B00000100 4 -#define B101 5 -#define B0101 5 -#define B00101 5 -#define B000101 5 -#define B0000101 5 -#define B00000101 5 -#define B110 6 -#define B0110 6 -#define B00110 6 -#define B000110 6 -#define B0000110 6 -#define B00000110 6 -#define B111 7 -#define B0111 7 -#define B00111 7 -#define B000111 7 -#define B0000111 7 -#define B00000111 7 -#define B1000 8 -#define B01000 8 -#define B001000 8 -#define B0001000 8 -#define B00001000 8 -#define B1001 9 -#define B01001 9 -#define B001001 9 -#define B0001001 9 -#define B00001001 9 -#define B1010 10 -#define B01010 10 -#define B001010 10 -#define B0001010 10 -#define B00001010 10 -#define B1011 11 -#define B01011 11 -#define B001011 11 -#define B0001011 11 -#define B00001011 11 -#define B1100 12 -#define B01100 12 -#define B001100 12 -#define B0001100 12 -#define B00001100 12 -#define B1101 13 -#define B01101 13 -#define B001101 13 -#define B0001101 13 -#define B00001101 13 -#define B1110 14 -#define B01110 14 -#define B001110 14 -#define B0001110 14 -#define B00001110 14 -#define B1111 15 -#define B01111 15 -#define B001111 15 -#define B0001111 15 -#define B00001111 15 -#define B10000 16 -#define B010000 16 -#define B0010000 16 -#define B00010000 16 -#define B10001 17 -#define B010001 17 -#define B0010001 17 -#define B00010001 17 -#define B10010 18 -#define B010010 18 -#define B0010010 18 -#define B00010010 18 -#define B10011 19 -#define B010011 19 -#define B0010011 19 -#define B00010011 19 -#define B10100 20 -#define B010100 20 -#define B0010100 20 -#define B00010100 20 -#define B10101 21 -#define B010101 21 -#define B0010101 21 -#define B00010101 21 -#define B10110 22 -#define B010110 22 -#define B0010110 22 -#define B00010110 22 -#define B10111 23 -#define B010111 23 -#define B0010111 23 -#define B00010111 23 -#define B11000 24 -#define B011000 24 -#define B0011000 24 -#define B00011000 24 -#define B11001 25 -#define B011001 25 -#define B0011001 25 -#define B00011001 25 -#define B11010 26 -#define B011010 26 -#define B0011010 26 -#define B00011010 26 -#define B11011 27 -#define B011011 27 -#define B0011011 27 -#define B00011011 27 -#define B11100 28 -#define B011100 28 -#define B0011100 28 -#define B00011100 28 -#define B11101 29 -#define B011101 29 -#define B0011101 29 -#define B00011101 29 -#define B11110 30 -#define B011110 30 -#define B0011110 30 -#define B00011110 30 -#define B11111 31 -#define B011111 31 -#define B0011111 31 -#define B00011111 31 -#define B100000 32 -#define B0100000 32 -#define B00100000 32 -#define B100001 33 -#define B0100001 33 -#define B00100001 33 -#define B100010 34 -#define B0100010 34 -#define B00100010 34 -#define B100011 35 -#define B0100011 35 -#define B00100011 35 -#define B100100 36 -#define B0100100 36 -#define B00100100 36 -#define B100101 37 -#define B0100101 37 -#define B00100101 37 -#define B100110 38 -#define B0100110 38 -#define B00100110 38 -#define B100111 39 -#define B0100111 39 -#define B00100111 39 -#define B101000 40 -#define B0101000 40 -#define B00101000 40 -#define B101001 41 -#define B0101001 41 -#define B00101001 41 -#define B101010 42 -#define B0101010 42 -#define B00101010 42 -#define B101011 43 -#define B0101011 43 -#define B00101011 43 -#define B101100 44 -#define B0101100 44 -#define B00101100 44 -#define B101101 45 -#define B0101101 45 -#define B00101101 45 -#define B101110 46 -#define B0101110 46 -#define B00101110 46 -#define B101111 47 -#define B0101111 47 -#define B00101111 47 -#define B110000 48 -#define B0110000 48 -#define B00110000 48 -#define B110001 49 -#define B0110001 49 -#define B00110001 49 -#define B110010 50 -#define B0110010 50 -#define B00110010 50 -#define B110011 51 -#define B0110011 51 -#define B00110011 51 -#define B110100 52 -#define B0110100 52 -#define B00110100 52 -#define B110101 53 -#define B0110101 53 -#define B00110101 53 -#define B110110 54 -#define B0110110 54 -#define B00110110 54 -#define B110111 55 -#define B0110111 55 -#define B00110111 55 -#define B111000 56 -#define B0111000 56 -#define B00111000 56 -#define B111001 57 -#define B0111001 57 -#define B00111001 57 -#define B111010 58 -#define B0111010 58 -#define B00111010 58 -#define B111011 59 -#define B0111011 59 -#define B00111011 59 -#define B111100 60 -#define B0111100 60 -#define B00111100 60 -#define B111101 61 -#define B0111101 61 -#define B00111101 61 -#define B111110 62 -#define B0111110 62 -#define B00111110 62 -#define B111111 63 -#define B0111111 63 -#define B00111111 63 -#define B1000000 64 -#define B01000000 64 -#define B1000001 65 -#define B01000001 65 -#define B1000010 66 -#define B01000010 66 -#define B1000011 67 -#define B01000011 67 -#define B1000100 68 -#define B01000100 68 -#define B1000101 69 -#define B01000101 69 -#define B1000110 70 -#define B01000110 70 -#define B1000111 71 -#define B01000111 71 -#define B1001000 72 -#define B01001000 72 -#define B1001001 73 -#define B01001001 73 -#define B1001010 74 -#define B01001010 74 -#define B1001011 75 -#define B01001011 75 -#define B1001100 76 -#define B01001100 76 -#define B1001101 77 -#define B01001101 77 -#define B1001110 78 -#define B01001110 78 -#define B1001111 79 -#define B01001111 79 -#define B1010000 80 -#define B01010000 80 -#define B1010001 81 -#define B01010001 81 -#define B1010010 82 -#define B01010010 82 -#define B1010011 83 -#define B01010011 83 -#define B1010100 84 -#define B01010100 84 -#define B1010101 85 -#define B01010101 85 -#define B1010110 86 -#define B01010110 86 -#define B1010111 87 -#define B01010111 87 -#define B1011000 88 -#define B01011000 88 -#define B1011001 89 -#define B01011001 89 -#define B1011010 90 -#define B01011010 90 -#define B1011011 91 -#define B01011011 91 -#define B1011100 92 -#define B01011100 92 -#define B1011101 93 -#define B01011101 93 -#define B1011110 94 -#define B01011110 94 -#define B1011111 95 -#define B01011111 95 -#define B1100000 96 -#define B01100000 96 -#define B1100001 97 -#define B01100001 97 -#define B1100010 98 -#define B01100010 98 -#define B1100011 99 -#define B01100011 99 -#define B1100100 100 -#define B01100100 100 -#define B1100101 101 -#define B01100101 101 -#define B1100110 102 -#define B01100110 102 -#define B1100111 103 -#define B01100111 103 -#define B1101000 104 -#define B01101000 104 -#define B1101001 105 -#define B01101001 105 -#define B1101010 106 -#define B01101010 106 -#define B1101011 107 -#define B01101011 107 -#define B1101100 108 -#define B01101100 108 -#define B1101101 109 -#define B01101101 109 -#define B1101110 110 -#define B01101110 110 -#define B1101111 111 -#define B01101111 111 -#define B1110000 112 -#define B01110000 112 -#define B1110001 113 -#define B01110001 113 -#define B1110010 114 -#define B01110010 114 -#define B1110011 115 -#define B01110011 115 -#define B1110100 116 -#define B01110100 116 -#define B1110101 117 -#define B01110101 117 -#define B1110110 118 -#define B01110110 118 -#define B1110111 119 -#define B01110111 119 -#define B1111000 120 -#define B01111000 120 -#define B1111001 121 -#define B01111001 121 -#define B1111010 122 -#define B01111010 122 -#define B1111011 123 -#define B01111011 123 -#define B1111100 124 -#define B01111100 124 -#define B1111101 125 -#define B01111101 125 -#define B1111110 126 -#define B01111110 126 -#define B1111111 127 -#define B01111111 127 -#define B10000000 128 -#define B10000001 129 -#define B10000010 130 -#define B10000011 131 -#define B10000100 132 -#define B10000101 133 -#define B10000110 134 -#define B10000111 135 -#define B10001000 136 -#define B10001001 137 -#define B10001010 138 -#define B10001011 139 -#define B10001100 140 -#define B10001101 141 -#define B10001110 142 -#define B10001111 143 -#define B10010000 144 -#define B10010001 145 -#define B10010010 146 -#define B10010011 147 -#define B10010100 148 -#define B10010101 149 -#define B10010110 150 -#define B10010111 151 -#define B10011000 152 -#define B10011001 153 -#define B10011010 154 -#define B10011011 155 -#define B10011100 156 -#define B10011101 157 -#define B10011110 158 -#define B10011111 159 -#define B10100000 160 -#define B10100001 161 -#define B10100010 162 -#define B10100011 163 -#define B10100100 164 -#define B10100101 165 -#define B10100110 166 -#define B10100111 167 -#define B10101000 168 -#define B10101001 169 -#define B10101010 170 -#define B10101011 171 -#define B10101100 172 -#define B10101101 173 -#define B10101110 174 -#define B10101111 175 -#define B10110000 176 -#define B10110001 177 -#define B10110010 178 -#define B10110011 179 -#define B10110100 180 -#define B10110101 181 -#define B10110110 182 -#define B10110111 183 -#define B10111000 184 -#define B10111001 185 -#define B10111010 186 -#define B10111011 187 -#define B10111100 188 -#define B10111101 189 -#define B10111110 190 -#define B10111111 191 -#define B11000000 192 -#define B11000001 193 -#define B11000010 194 -#define B11000011 195 -#define B11000100 196 -#define B11000101 197 -#define B11000110 198 -#define B11000111 199 -#define B11001000 200 -#define B11001001 201 -#define B11001010 202 -#define B11001011 203 -#define B11001100 204 -#define B11001101 205 -#define B11001110 206 -#define B11001111 207 -#define B11010000 208 -#define B11010001 209 -#define B11010010 210 -#define B11010011 211 -#define B11010100 212 -#define B11010101 213 -#define B11010110 214 -#define B11010111 215 -#define B11011000 216 -#define B11011001 217 -#define B11011010 218 -#define B11011011 219 -#define B11011100 220 -#define B11011101 221 -#define B11011110 222 -#define B11011111 223 -#define B11100000 224 -#define B11100001 225 -#define B11100010 226 -#define B11100011 227 -#define B11100100 228 -#define B11100101 229 -#define B11100110 230 -#define B11100111 231 -#define B11101000 232 -#define B11101001 233 -#define B11101010 234 -#define B11101011 235 -#define B11101100 236 -#define B11101101 237 -#define B11101110 238 -#define B11101111 239 -#define B11110000 240 -#define B11110001 241 -#define B11110010 242 -#define B11110011 243 -#define B11110100 244 -#define B11110101 245 -#define B11110110 246 -#define B11110111 247 -#define B11111000 248 -#define B11111001 249 -#define B11111010 250 -#define B11111011 251 -#define B11111100 252 -#define B11111101 253 -#define B11111110 254 -#define B11111111 255 - -#endif /* _BIT_CONSTANTS_H_ */ diff --git a/STM32F3/cores/maple/wirish/bits.h b/STM32F3/cores/maple/wirish/bits.h deleted file mode 100644 index 0a63c58c0..000000000 --- a/STM32F3/cores/maple/wirish/bits.h +++ /dev/null @@ -1,35 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* Note: Use of this header file is deprecated. Use bit_constants.h - instead. */ - -#ifndef _WIRISH_BITS_H_ -#define _WIRISH_BITS_H_ - -#include - -#endif diff --git a/STM32F3/cores/maple/wirish/boards.h b/STM32F3/cores/maple/wirish/boards.h deleted file mode 100644 index 6676a0272..000000000 --- a/STM32F3/cores/maple/wirish/boards.h +++ /dev/null @@ -1,173 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/include/wirish/boards.h - * @author Bryan Newbold , - * Marti Bolivar - * @brief init() and board-specific pin information. - */ - -#ifndef _WIRISH_BOARDS_H_ -#define _WIRISH_BOARDS_H_ - -#include -#include -#include - -/* Set of all possible pin names; not all boards have all these (note - * that we use the Dx convention since all of the Maple's pins are - * "digital" pins (e.g. can be used with digitalRead() and - * digitalWrite()), but not all of them are connected to ADCs. */ -enum { - D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, - D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31, - D32, D33, D34, D35, D36, D37, D38, D39, D40, D41, D42, D43, D44, D45, D46, - D47, D48, D49, D50, D51, D52, D53, D54, D55, D56, D57, D58, D59, D60, D61, - D62, D63, D64, D65, D66, D67, D68, D69, D70, D71, D72, D73, D74, D75, D76, - D77, D78, D79, D80, D81, D82, D83, D84, D85, D86, D87, D88, D89, D90, D91, - D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105, - D106, D107, D108, D109, D110, D111, }; - -/** - * @brief Maps each Maple pin to a corresponding stm32_pin_info. - * @see stm32_pin_info - */ -extern const stm32_pin_info PIN_MAP[]; - -/** - * @brief Pins capable of PWM output. - * - * Its length is BOARD_NR_PWM_PINS. - */ -extern const uint8 boardPWMPins[]; - -/** - * @brief Array of pins capable of analog input. - * - * Its length is BOARD_NR_ADC_PINS. - */ -extern const uint8 boardADCPins[]; - -/** - * @brief Pins which are connected to external hardware. - * - * For example, on Maple boards, it always at least includes - * BOARD_LED_PIN. Its length is BOARD_NR_USED_PINS. - */ -extern const uint8 boardUsedPins[]; - -/** - * @brief Generic board initialization function. - * - * This function is called before main(). It ensures that the clocks - * and peripherals are configured properly for use with wirish, then - * calls boardInit(). - * - * @see boardInit() - */ -void init(void); - -/** - * @brief Board-specific initialization function. - * - * This function is called from init() after all generic board - * initialization has been performed. Each board is required to - * define its own. - * - * @see init() - */ -extern void boardInit(void); - -/** - * @brief Test if a pin is used for a special purpose on your board. - * @param pin Pin to test - * @return true if the given pin is in boardUsedPins, and false otherwise. - * @see boardUsedPins - */ -bool boardUsesPin(uint8 pin); - -/* - * Derived and default board definitions - */ - -#define CLOCK_SPEED_MHZ CYCLES_PER_MICROSECOND -#define CLOCK_SPEED_HZ (CLOCK_SPEED_MHZ * 1000000UL) - -#ifndef SYSTICK_RELOAD_VAL -#define SYSTICK_RELOAD_VAL (1000 * CYCLES_PER_MICROSECOND - 1) -#endif - -#ifndef BOARD_BUTTON_PRESSED_LEVEL -#define BOARD_BUTTON_PRESSED_LEVEL HIGH -#endif - -/** - * @brief Does the board break out a USART/UART's RX and TX pins? - * - * BOARD_HAVE_USART(n) is nonzero iff USARTn is available (n must be - * an integer literal, 1 through 6). Also see BOARD_HAVE_USART1, ..., - * BOARD_HAVE_UART4 (sic), etc. - */ -#define BOARD_HAVE_USART(n) (defined(BOARD_USART##n##_TX_PIN) && \ - defined(BOARD_USART##n##_RX_PIN)) -/** Feature test: nonzero iff the board has USART1. */ -#define BOARD_HAVE_USART1 BOARD_HAVE_USART(1) -/** Feature test: nonzero iff the board has USART2, 0 otherwise. */ -#define BOARD_HAVE_USART2 BOARD_HAVE_USART(2) -/** Feature test: nonzero iff the board has USART3, 0 otherwise. */ -#define BOARD_HAVE_USART3 BOARD_HAVE_USART(3) -/** Feature test: nonzero iff the board has UART4, 0 otherwise. */ -#define BOARD_HAVE_UART4 BOARD_HAVE_USART(4) -/** Feature test: nonzero iff the board has UART5, 0 otherwise. */ -#define BOARD_HAVE_UART5 BOARD_HAVE_USART(5) -/** Feature test: nonzero iff the board has USART6, 0 otherwise. */ -#define BOARD_HAVE_USART6 BOARD_HAVE_USART(6) - -/** - * @brief Does the board break out a SPI peripheral's pins? - * - * BOARD_HAVE_SPI(n) is nonzero iff SPIn is available (n must be an - * integer literal: 1, 2, or 3). Also see BOARD_HAVE_SPI1, - * BOARD_HAVE_SPI2, BOARD_HAVE_SPI3. */ -#define BOARD_HAVE_SPI(n) (defined(BOARD_SPI##n##_NSS_PIN) && \ - defined(BOARD_SPI##n##_SCK_PIN) && \ - defined(BOARD_SPI##n##_MISO_PIN) && \ - defined(BOARD_SPI##n##_MOSI_PIN)) -/** Feature test: nonzero iff the board has SPI1. */ -#define BOARD_HAVE_SPI1 BOARD_HAVE_SPI(1) -/** Feature test: nonzero iff the board has SPI2. */ -#define BOARD_HAVE_SPI2 BOARD_HAVE_SPI(2) -/** Feature test: nonzero iff the board has SPI3. */ -#define BOARD_HAVE_SPI3 BOARD_HAVE_SPI(3) - -/** - * @brief Feature test: nonzero iff the board has SerialUSB. - */ -#define BOARD_HAVE_SERIALUSB (defined(BOARD_USB_DISC_DEV) && \ - defined(BOARD_USB_DISC_BIT)) - -#endif diff --git a/STM32F3/cores/maple/wirish/boards_private.h b/STM32F3/cores/maple/wirish/boards_private.h deleted file mode 100644 index 49867ca77..000000000 --- a/STM32F3/cores/maple/wirish/boards_private.h +++ /dev/null @@ -1,71 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/boards_private.h - * @author Marti Bolivar - * @brief Private board support header. - * - * This file declares chip-specific variables and functions which - * determine how init() behaves. It is not part of the public Wirish - * API, and can change without notice. - */ - -#ifndef _WIRISH_BOARDS_PRIVATE_H_ -#define _WIRISH_BOARDS_PRIVATE_H_ - -#include -#include - -/* Makes the PIN_MAP rows more human-readable. */ -#define PMAP_ROW(gpio_dev, gpio_bit, timer_dev, timer_ch, adc_dev, adc_ch) \ - { gpio_dev, timer_dev, adc_dev, gpio_bit, timer_ch, adc_ch } - -namespace wirish { - namespace priv { - - /* - * Chip-specific initialization data - */ - - extern rcc_pll_cfg w_board_pll_cfg; - extern adc_prescaler w_adc_pre; - extern adc_smp_rate w_adc_smp; - - /* - * Chip-specific initialization routines and helper functions. - */ - - void board_reset_pll(void); - void board_setup_clock_prescalers(void); - void board_setup_gpio(void); - void board_setup_usb(void); - void series_init(void); - - } -} - -#endif diff --git a/STM32F3/cores/maple/wirish/cxxabi-compat.cpp b/STM32F3/cores/maple/wirish/cxxabi-compat.cpp deleted file mode 100644 index 516b112ac..000000000 --- a/STM32F3/cores/maple/wirish/cxxabi-compat.cpp +++ /dev/null @@ -1,6 +0,0 @@ -/* We compile with nodefaultlibs, so we need to provide an error - * handler for an empty pure virtual function */ -extern "C" void __cxa_pure_virtual(void) { - while(1) - ; -} diff --git a/STM32F3/cores/maple/wirish/ext_interrupts.cpp b/STM32F3/cores/maple/wirish/ext_interrupts.cpp deleted file mode 100644 index 1195ea9cc..000000000 --- a/STM32F3/cores/maple/wirish/ext_interrupts.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/ext_interrupts.cpp - * @brief Wiring-like interface for external interrupts - */ - -#include - -#include -#include - -#include - -static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode); - -void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) { - if (pin >= BOARD_NR_GPIO_PINS || !handler) { - return; - } - - exti_trigger_mode outMode = exti_out_mode(mode); - - exti_attach_interrupt((exti_num)(PIN_MAP[pin].gpio_bit), - gpio_exti_port(PIN_MAP[pin].gpio_device), - handler, - outMode); -} - -void attachInterrupt(uint8 pin, voidArgumentFuncPtr handler, void *arg, - ExtIntTriggerMode mode) { - if (pin >= BOARD_NR_GPIO_PINS || !handler) { - return; - } - - exti_trigger_mode outMode = exti_out_mode(mode); - - exti_attach_callback((exti_num)(PIN_MAP[pin].gpio_bit), - gpio_exti_port(PIN_MAP[pin].gpio_device), - handler, - arg, - outMode); -} - -void detachInterrupt(uint8 pin) { - if (pin >= BOARD_NR_GPIO_PINS) { - return; - } - - exti_detach_interrupt((exti_num)(PIN_MAP[pin].gpio_bit)); -} - -static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode) { - switch (mode) { - case RISING: - return EXTI_RISING; - case FALLING: - return EXTI_FALLING; - case CHANGE: - return EXTI_RISING_FALLING; - } - // Can't happen - ASSERT(0); - return (exti_trigger_mode)0; -} diff --git a/STM32F3/cores/maple/wirish/ext_interrupts.h b/STM32F3/cores/maple/wirish/ext_interrupts.h deleted file mode 100644 index ce1ca0346..000000000 --- a/STM32F3/cores/maple/wirish/ext_interrupts.h +++ /dev/null @@ -1,128 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/include/wirish/ext_interrupts.h - * @brief Wiring-like external interrupt prototypes and types. - */ - -#ifndef _WIRISH_EXT_INTERRUPTS_H_ -#define _WIRISH_EXT_INTERRUPTS_H_ - -#include -#include - -/** - * The kind of transition on an external pin which should trigger an - * interrupt. - */ -typedef enum ExtIntTriggerMode { - RISING, /**< To trigger an interrupt when the pin transitions LOW - to HIGH */ - FALLING, /**< To trigger an interrupt when the pin transitions - HIGH to LOW */ - CHANGE /**< To trigger an interrupt when the pin transitions from - LOW to HIGH or HIGH to LOW (i.e., when the pin - changes). */ -} ExtIntTriggerMode; - -/** - * @brief Registers an interrupt handler on a pin. - * - * The interrupt will be triggered on a given transition on the pin, - * as specified by the mode parameter. The handler runs in interrupt - * context. The new handler will replace whatever handler is - * currently registered for the pin, if any. - * - * @param pin Pin number - * @param handler Function to run upon external interrupt trigger. - * The handler should take no arguments, and have void - * return type. - * @param mode Type of transition to trigger on, e.g. falling, rising, etc. - * - * @sideeffect Registers a handler - * @see detachInterrupt() - */ -void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode); - -/** - * @brief Registers an interrupt handler on a pin. - * - * The interrupt will be triggered on a given transition on the pin, - * as specified by the mode parameter. The handler runs in interrupt - * context. The new handler will replace whatever handler is - * currently registered for the pin, if any. - * - * @param pin Pin number - * @param handler Static class member function to run upon external interrupt - * trigger. The handler should take 1 argument and return void - * @param arg Argument that the handler will be passed when it's called. One - * use of this is to pass the specific instance of the class that - * will handle the interrupt. - * @param mode Type of transition to trigger on, e.g. falling, rising, etc. - * - * @sideeffect Registers a handler - * @see detachInterrupt() - */ -void attachInterrupt(uint8 pin, voidArgumentFuncPtr handler, void *arg, - ExtIntTriggerMode mode); - -/** - * @brief Disable any registered external interrupt. - * @param pin Maple pin number - * @sideeffect unregisters external interrupt handler - * @see attachInterrupt() - */ -void detachInterrupt(uint8 pin); - -/** - * Re-enable interrupts. - * - * Call this after noInterrupts() to re-enable interrupt handling, - * after you have finished with a timing-critical section of code. - * - * @see noInterrupts() - */ -static __always_inline void interrupts() { - nvic_globalirq_enable(); -} - -/** - * Disable interrupts. - * - * After calling this function, all user-programmable interrupts will - * be disabled. You can call this function before a timing-critical - * section of code, then call interrupts() to re-enable interrupt - * handling. - * - * @see interrupts() - */ -static __always_inline void noInterrupts() { - nvic_globalirq_disable(); -} - -#endif - diff --git a/STM32F3/cores/maple/wirish/io.h b/STM32F3/cores/maple/wirish/io.h deleted file mode 100644 index 08bbc061d..000000000 --- a/STM32F3/cores/maple/wirish/io.h +++ /dev/null @@ -1,222 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/include/wirish/io.h - * @brief Wiring-style pin I/O interface. - */ - -#ifndef _WIRISH_IO_H_ -#define _WIRISH_IO_H_ - -#include -#include - -/** - * Specifies a GPIO pin behavior. - * @see pinMode() - */ -typedef enum WiringPinMode { - OUTPUT, /**< Basic digital output: when the pin is HIGH, the - voltage is held at +3.3v (Vcc) and when it is LOW, it - is pulled down to ground. */ - - OUTPUT_OPEN_DRAIN, /**< In open drain mode, the pin indicates - "low" by accepting current flow to ground - and "high" by providing increased - impedance. An example use would be to - connect a pin to a bus line (which is pulled - up to a positive voltage by a separate - supply through a large resistor). When the - pin is high, not much current flows through - to ground and the line stays at positive - voltage; when the pin is low, the bus - "drains" to ground with a small amount of - current constantly flowing through the large - resistor from the external supply. In this - mode, no current is ever actually sourced - from the pin. */ - - INPUT, /**< Basic digital input. The pin voltage is sampled; when - it is closer to 3.3v (Vcc) the pin status is high, and - when it is closer to 0v (ground) it is low. If no - external circuit is pulling the pin voltage to high or - low, it will tend to randomly oscillate and be very - sensitive to noise (e.g., a breath of air across the pin - might cause the state to flip). */ - - INPUT_ANALOG, /**< This is a special mode for when the pin will be - used for analog (not digital) reads. Enables ADC - conversion to be performed on the voltage at the - pin. */ - - INPUT_PULLUP, /**< The state of the pin in this mode is reported - the same way as with INPUT, but the pin voltage - is gently "pulled up" towards +3.3v. This means - the state will be high unless an external device - is specifically pulling the pin down to ground, - in which case the "gentle" pull up will not - affect the state of the input. */ - - INPUT_PULLDOWN, /**< The state of the pin in this mode is reported - the same way as with INPUT, but the pin voltage - is gently "pulled down" towards 0v. This means - the state will be low unless an external device - is specifically pulling the pin up to 3.3v, in - which case the "gentle" pull down will not - affect the state of the input. */ - - INPUT_FLOATING, /**< Synonym for INPUT. */ - - PWM, /**< This is a special mode for when the pin will be used for - PWM output (a special case of digital output). */ - - PWM_OPEN_DRAIN, /**< Like PWM, except that instead of alternating - cycles of LOW and HIGH, the voltage on the pin - consists of alternating cycles of LOW and - floating (disconnected). */ -} WiringPinMode; - -/** - * Configure behavior of a GPIO pin. - * - * @param pin Number of pin to configure. - * @param mode Mode corresponding to desired pin behavior. - * @see WiringPinMode - */ -void pinMode(uint8 pin, WiringPinMode mode); - -#define HIGH 0x1 -#define LOW 0x0 - -/** - * Writes a (digital) value to a pin. The pin must have its - * mode set to OUTPUT or OUTPUT_OPEN_DRAIN. - * - * @param pin Pin to write to. - * @param value Either LOW (write a 0) or HIGH (write a 1). - * @see pinMode() - */ -void digitalWrite(uint8 pin, uint8 value); - -/** - * Read a digital value from a pin. The pin must have its mode set to - * one of INPUT, INPUT_PULLUP, and INPUT_PULLDOWN. - * - * @param pin Pin to read from. - * @return LOW or HIGH. - * @see pinMode() - */ -uint32 digitalRead(uint8 pin); - -/** - * Read an analog value from pin. This function blocks during ADC - * conversion, and has 12 bits of resolution. The pin must have its - * mode set to INPUT_ANALOG. - * - * @param pin Pin to read from. - * @return Converted voltage, in the range 0--4095, (i.e. a 12-bit ADC - * conversion). - * @see pinMode() - */ -uint16 analogRead(uint8 pin); - -/** - * Toggles the digital value at the given pin. - * - * The pin must have its mode set to OUTPUT. - * - * @param pin the pin to toggle. If the pin is HIGH, set it LOW. If - * it is LOW, set it HIGH. - * - * @see pinMode() - */ -void togglePin(uint8 pin); - -/** - * Toggle the LED. - * - * If the LED is on, turn it off. If it is off, turn it on. - * - * The LED must its mode set to OUTPUT. This can be accomplished - * portably over all LeafLabs boards by calling pinMode(BOARD_LED_PIN, - * OUTPUT) before calling this function. - * - * @see pinMode() - */ -static inline void toggleLED() { - togglePin(BOARD_LED_PIN); -} - -/** - * If the button is currently pressed, waits until the button is no - * longer being pressed, and returns true. Otherwise, returns false. - * - * The button pin must have its mode set to INPUT. This can be - * accomplished portably over all LeafLabs boards by calling - * pinMode(BOARD_BUTTON_PIN, INPUT). - * - * @see pinMode() - */ -uint8 isButtonPressed(uint8 pin=BOARD_BUTTON_PIN, - uint32 pressedLevel=BOARD_BUTTON_PRESSED_LEVEL); - -/** - * Wait until the button is pressed and released, timing out if no - * press occurs. - * - * The button pin must have its mode set to INPUT. This can be - * accomplished portably over all LeafLabs boards by calling - * pinMode(BOARD_BUTTON_PIN, INPUT). - * - * @param timeout_millis Number of milliseconds to wait until the - * button is pressed. If timeout_millis is left out (or 0), wait - * forever. - * - * @return true, if the button was pressed; false, if the timeout was - * reached. - * - * @see pinMode() - */ -uint8 waitForButtonPress(uint32 timeout_millis=0); - -/** - * Shift out a byte of data, one bit at a time. - * - * This function starts at either the most significant or least - * significant bit in a byte value, and shifts out each byte in order - * onto a data pin. After each bit is written to the data pin, a - * separate clock pin is pulsed to indicate that the new bit is - * available. - * - * @param dataPin Pin to shift data out on - * @param clockPin Pin to pulse after each bit is shifted out - * @param bitOrder Either MSBFIRST (big-endian) or LSBFIRST (little-endian). - * @param value Value to shift out - */ -void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 value); - -#endif diff --git a/STM32F3/cores/maple/wirish/main.cxx b/STM32F3/cores/maple/wirish/main.cxx deleted file mode 100644 index 9c0b9cc08..000000000 --- a/STM32F3/cores/maple/wirish/main.cxx +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. - __attribute__(( constructor )) void premain() { - init(); -} - -int main(void) { - setup(); - - while (1) { - loop(); - } - return 0; -} diff --git a/STM32F3/cores/maple/wirish/pwm.cpp b/STM32F3/cores/maple/wirish/pwm.cpp deleted file mode 100644 index 44884cd12..000000000 --- a/STM32F3/cores/maple/wirish/pwm.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/pwm.cpp - * @brief Wiring-style pwmWrite(). - */ - -#include - -#include -#include - -#include - -void pwmWrite(uint8 pin, uint16 duty_cycle) { - if (pin >= BOARD_NR_GPIO_PINS) { - return; - } - timer_dev *dev = PIN_MAP[pin].timer_device; - uint8 cc_channel = PIN_MAP[pin].timer_channel; - ASSERT(dev && cc_channel); - timer_set_compare(dev, cc_channel, duty_cycle); -} diff --git a/STM32F3/cores/maple/wirish/pwm.h b/STM32F3/cores/maple/wirish/pwm.h deleted file mode 100644 index 6631d4232..000000000 --- a/STM32F3/cores/maple/wirish/pwm.h +++ /dev/null @@ -1,56 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/include/wirish/pwm.h - * @brief Wiring-style PWM interface. - */ - -#ifndef _WIRISH_PWM_H_ -#define _WIRISH_PWM_H_ - -#include - -/** - * As a convenience, analogWrite is an alias of pwmWrite to ease - * porting Arduino code. However, period and duty will have to be - * recalibrated. - */ -#define analogWrite pwmWrite - -/** - * Set the PWM duty on the given pin. - * - * User code is expected to determine and honor the maximum value - * (based on the configured period). - * - * @param pin PWM output pin - * @param duty_cycle Duty cycle to set. - */ -void pwmWrite(uint8 pin, uint16 duty_cycle); - -#endif - diff --git a/STM32F3/cores/maple/wirish/rules.mk b/STM32F3/cores/maple/wirish/rules.mk deleted file mode 100644 index 539e96661..000000000 --- a/STM32F3/cores/maple/wirish/rules.mk +++ /dev/null @@ -1,66 +0,0 @@ -# Standard things -sp := $(sp).x -dirstack_$(sp) := $(d) -d := $(dir) -BUILDDIRS += $(BUILD_PATH)/$(d) - -# Add board directory and MCU-specific directory to BUILDDIRS. These -# are in subdirectories, but they're logically part of the Wirish -# submodule. -ifeq ($(MCU_SERIES), stm32f3) -WIRISH_BOARD_PATH := boards/$(MCU_F3_LINE) -else -WIRISH_BOARD_PATH := boards/$(BOARD) -endif -BUILDDIRS += $(BUILD_PATH)/$(d)/$(WIRISH_BOARD_PATH) -BUILDDIRS += $(BUILD_PATH)/$(d)/$(MCU_SERIES) - -# Safe includes for Wirish. -WIRISH_INCLUDES := -I$(d)/include -I$(d)/$(WIRISH_BOARD_PATH)/include - -# Local flags. Add -I$(d) to allow for private includes. -CFLAGS_$(d) := $(LIBMAPLE_INCLUDES) $(WIRISH_INCLUDES) -I$(d) - -# Local rules and targets -sSRCS_$(d) := start.S -cSRCS_$(d) := start_c.c -cSRCS_$(d) += syscalls.c -cSRCS_$(d) += $(MCU_SERIES)/util_hooks.c -cppSRCS_$(d) := boards.cpp -cppSRCS_$(d) += cxxabi-compat.cpp -cppSRCS_$(d) += ext_interrupts.cpp -cppSRCS_$(d) += HardwareSerial.cpp -cppSRCS_$(d) += HardwareTimer.cpp -cppSRCS_$(d) += Print.cpp -cppSRCS_$(d) += pwm.cpp -ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),stm32f1 stm32f3)) # TODO port USB serial to F2 -cppSRCS_$(d) += usb_serial.cpp -cppSRCS_$(d) += HardwareSPI.cpp -endif -cppSRCS_$(d) += wirish_analog.cpp -cppSRCS_$(d) += wirish_digital.cpp -cppSRCS_$(d) += wirish_math.cpp -cppSRCS_$(d) += wirish_shift.cpp -cppSRCS_$(d) += wirish_time.cpp -cppSRCS_$(d) += $(MCU_SERIES)/boards_setup.cpp -cppSRCS_$(d) += $(MCU_SERIES)/wirish_digital.cpp -cppSRCS_$(d) += $(MCU_SERIES)/wirish_debug.cpp -cppSRCS_$(d) += $(WIRISH_BOARD_PATH)/board.cpp - -sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%) -cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) -cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) - -OBJS_$(d) := $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) \ - $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ - $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) -DEPS_$(d) := $(OBJS_$(d):%.o=%.d) - -$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) - -TGT_BIN += $(OBJS_$(d)) - -# Standard things --include $(DEPS_$(d)) -d := $(dirstack_$(sp)) -sp := $(basename $(sp)) diff --git a/STM32F3/cores/maple/wirish/stm32f3/f3_wirish_digital.cpp b/STM32F3/cores/maple/wirish/stm32f3/f3_wirish_digital.cpp deleted file mode 100644 index 50cda6019..000000000 --- a/STM32F3/cores/maple/wirish/stm32f3/f3_wirish_digital.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* - * STM32F3 implementations for basic GPIO functionality. - */ - -#include - -#include -#include - -#include - -void pinMode(uint8 pin, WiringPinMode w_mode) { - if (pin >= BOARD_NR_GPIO_PINS) { - return; - } - - gpio_pin_mode mode; - // People always do the silly pin-toggle speed benchmark, so let's - // accomodate them: - unsigned flags = GPIO_MODEF_SPEED_HIGH; - bool pwm = false; - switch(w_mode) { - case OUTPUT: - mode = GPIO_MODE_OUTPUT; - break; - case OUTPUT_OPEN_DRAIN: - mode = GPIO_MODE_OUTPUT; - flags |= GPIO_MODEF_TYPE_OD; - break; - case INPUT: - case INPUT_FLOATING: - mode = GPIO_MODE_INPUT; - break; - case INPUT_ANALOG: - mode = GPIO_MODE_ANALOG; - break; - case INPUT_PULLUP: - mode = GPIO_MODE_INPUT; - flags |= GPIO_MODEF_PUPD_PU; - break; - case INPUT_PULLDOWN: - mode = GPIO_MODE_INPUT; - flags |= GPIO_MODEF_PUPD_PD; - break; - case PWM: - mode = GPIO_MODE_AF; - pwm = true; - break; - case PWM_OPEN_DRAIN: - mode = GPIO_MODE_AF; - flags |= GPIO_MODEF_TYPE_OD; - pwm = true; - break; - default: - ASSERT(0); // Can't happen - return; - } - - const stm32_pin_info *info = &PIN_MAP[pin]; - - if (pwm) { - /* If enabling PWM, tell the timer to do PWM, and tell the pin - * to listen to the right timer. */ - ASSERT(info->timer_device != NULL); - if (info->timer_device == NULL) { - return; - } - gpio_af timer_af = timer_get_af(info->timer_device); - timer_set_mode(info->timer_device, info->timer_channel, TIMER_PWM); - gpio_set_af(info->gpio_device, info->gpio_bit, timer_af); - } - gpio_set_modef(info->gpio_device, info->gpio_bit, mode, flags); -} diff --git a/STM32F3/cores/maple/wirish/stm32f3/util_hooks.c b/STM32F3/cores/maple/wirish/stm32f3/util_hooks.c deleted file mode 100644 index 2387cf7ae..000000000 --- a/STM32F3/cores/maple/wirish/stm32f3/util_hooks.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* - * STM32F3 implementations for libmaple util.c hooks - * FIXME these are just minimal stubs - */ - -#include - -/* - * Disables all peripheral interrupts. Called by __error() with global - * interrupts disabled. - */ -void __lm_error(void) { - nvic_irq_disable_all(); -} - -/* - * Enable the error USART for writing. - */ -/* usart_dev* __lm_enable_error_usart(void) { (TODO) } */ diff --git a/STM32F3/cores/maple/wirish/stm32f3/wirish_debug.cpp b/STM32F3/cores/maple/wirish/stm32f3/wirish_debug.cpp deleted file mode 100644 index 6a6e1c180..000000000 --- a/STM32F3/cores/maple/wirish/stm32f3/wirish_debug.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/stm32f3/wirish_debug.cpp - * @brief High level debug port configuration - */ - -#include -#include -#include - -void disableDebugPorts(void) { - // BOARD_JTMS_SWDIO_PIN-BOARD_JTDI_PIN and BOARD_JTDO_PIN-BOARD_NJTRST_PIN are in system alternate function mode on - // reset, to support JTAG. Just put them in input mode to release - // them. - gpio_set_modef(PIN_MAP[BOARD_JTMS_SWDIO_PIN].gpio_device, PIN_MAP[BOARD_JTMS_SWDIO_PIN].gpio_bit, - GPIO_MODE_INPUT, GPIO_MODEF_PUPD_NONE); - gpio_set_modef(PIN_MAP[BOARD_JTCK_SWCLK_PIN].gpio_device, PIN_MAP[BOARD_JTCK_SWCLK_PIN].gpio_bit, - GPIO_MODE_INPUT, GPIO_MODEF_PUPD_NONE); - gpio_set_modef(PIN_MAP[BOARD_JTDI_PIN].gpio_device, PIN_MAP[BOARD_JTDI_PIN].gpio_bit, - GPIO_MODE_INPUT, GPIO_MODEF_PUPD_NONE); - gpio_set_modef(PIN_MAP[BOARD_JTDO_PIN].gpio_device, PIN_MAP[BOARD_JTDO_PIN].gpio_bit, - GPIO_MODE_INPUT, GPIO_MODEF_PUPD_NONE); - gpio_set_modef(PIN_MAP[BOARD_NJTRST_PIN].gpio_device, PIN_MAP[BOARD_NJTRST_PIN].gpio_bit, - GPIO_MODE_INPUT, GPIO_MODEF_PUPD_NONE); -} - -void enableDebugPorts(void) { - // Put BOARD_JTMS_SWDIO_PIN-BOARD_JTDI_PIN and BOARD_JTDO_PIN-BOARD_NJTRST_PIN back in system AF mode. - gpio_set_modef(PIN_MAP[BOARD_JTMS_SWDIO_PIN].gpio_device, PIN_MAP[BOARD_JTMS_SWDIO_PIN].gpio_bit, - GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - gpio_set_modef(PIN_MAP[BOARD_JTCK_SWCLK_PIN].gpio_device, PIN_MAP[BOARD_JTCK_SWCLK_PIN].gpio_bit, - GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - gpio_set_modef(PIN_MAP[BOARD_JTDI_PIN].gpio_device, PIN_MAP[BOARD_JTDI_PIN].gpio_bit, - GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - gpio_set_modef(PIN_MAP[BOARD_JTDO_PIN].gpio_device, PIN_MAP[BOARD_JTDO_PIN].gpio_bit, - GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - gpio_set_modef(PIN_MAP[BOARD_NJTRST_PIN].gpio_device, PIN_MAP[BOARD_NJTRST_PIN].gpio_bit, - GPIO_MODE_AF, GPIO_MODEF_TYPE_PP); - - gpio_set_af(PIN_MAP[BOARD_JTMS_SWDIO_PIN].gpio_device, PIN_MAP[BOARD_JTMS_SWDIO_PIN].gpio_bit, GPIO_AF_0); - gpio_set_af(PIN_MAP[BOARD_JTCK_SWCLK_PIN].gpio_device, PIN_MAP[BOARD_JTCK_SWCLK_PIN].gpio_bit, GPIO_AF_0); - gpio_set_af(PIN_MAP[BOARD_JTDI_PIN].gpio_device, PIN_MAP[BOARD_JTDI_PIN].gpio_bit, GPIO_AF_0); - gpio_set_af(PIN_MAP[BOARD_JTDO_PIN].gpio_device, PIN_MAP[BOARD_JTDO_PIN].gpio_bit, GPIO_AF_0); - gpio_set_af(PIN_MAP[BOARD_NJTRST_PIN].gpio_device, PIN_MAP[BOARD_NJTRST_PIN].gpio_bit, GPIO_AF_0); -} diff --git a/STM32F3/cores/maple/wirish/usb_serial.cpp b/STM32F3/cores/maple/wirish/usb_serial.cpp deleted file mode 100644 index d21766f50..000000000 --- a/STM32F3/cores/maple/wirish/usb_serial.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief USB virtual serial terminal - */ - -#include - -#include -#include - -#include -#include -#include - -#include - -/* - * Hooks used for bootloader reset signalling - */ - -#if BOARD_HAVE_SERIALUSB -static void rxHook(unsigned, void*); -static void ifaceSetupHook(unsigned, void*); -#endif - -/* - * USBSerial interface - */ - -#define USB_TIMEOUT 50 - -USBSerial::USBSerial(void) { -#if !BOARD_HAVE_SERIALUSB - ASSERT(0); -#endif -} - -void USBSerial::begin(void) { -#if BOARD_HAVE_SERIALUSB - usb_cdcacm_enable(BOARD_USB_DISC_DEV, BOARD_USB_DISC_BIT); - usb_cdcacm_set_hooks(USB_CDCACM_HOOK_RX, rxHook); - usb_cdcacm_set_hooks(USB_CDCACM_HOOK_IFACE_SETUP, ifaceSetupHook); -#endif -} - -void USBSerial::end(void) { -#if BOARD_HAVE_SERIALUSB - usb_cdcacm_disable(BOARD_USB_DISC_DEV, BOARD_USB_DISC_BIT); - usb_cdcacm_remove_hooks(USB_CDCACM_HOOK_RX | USB_CDCACM_HOOK_IFACE_SETUP); -#endif -} - -void USBSerial::write(uint8 ch) { - this->write(&ch, 1); -} - -void USBSerial::write(const char *str) { - this->write(str, strlen(str)); -} - -void USBSerial::write(const void *buf, uint32 len) { - if (!this->isConnected() || !buf) { - return; - } - - uint32 txed = 0; - uint32 old_txed = 0; - uint32 start = millis(); - - uint32 sent = 0; - - while (txed < len && (millis() - start < USB_TIMEOUT)) { - sent = usb_cdcacm_tx((const uint8*)buf + txed, len - txed); - txed += sent; - if (old_txed != txed) { - start = millis(); - } - old_txed = txed; - } - - - if (sent == USB_CDCACM_TX_EPSIZE) { - while (usb_cdcacm_is_transmitting() != 0) { - } - /* flush out to avoid having the pc wait for more data */ - usb_cdcacm_tx(NULL, 0); - } -} - -uint32 USBSerial::available(void) { - return usb_cdcacm_data_available(); -} - -uint32 USBSerial::read(void *buf, uint32 len) { - if (!buf) { - return 0; - } - - uint32 rxed = 0; - while (rxed < len) { - rxed += usb_cdcacm_rx((uint8*)buf + rxed, len - rxed); - } - - return rxed; -} - -/* Blocks forever until 1 byte is received */ -uint8 USBSerial::read(void) { - uint8 b; - this->read(&b, 1); - return b; -} - -uint8 USBSerial::pending(void) { - return usb_cdcacm_get_pending(); -} - -uint8 USBSerial::isConnected(void) { - return usb_is_connected(USBLIB) && usb_is_configured(USBLIB); -} - -uint8 USBSerial::getDTR(void) { - return usb_cdcacm_get_dtr(); -} - -uint8 USBSerial::getRTS(void) { - return usb_cdcacm_get_rts(); -} - -#if BOARD_HAVE_SERIALUSB -USBSerial SerialUSB; -#endif - -/* - * Bootloader hook implementations - */ - -#if BOARD_HAVE_SERIALUSB - -enum reset_state_t { - DTR_UNSET, - DTR_HIGH, - DTR_NEGEDGE, - DTR_LOW -}; - -static reset_state_t reset_state = DTR_UNSET; - -static void ifaceSetupHook(unsigned hook, void *requestvp) { - uint8 request = *(uint8*)requestvp; - - // Ignore requests we're not interested in. - if (request != USB_CDCACM_SET_CONTROL_LINE_STATE) { - return; - } - - // We need to see a negative edge on DTR before we start looking - // for the in-band magic reset byte sequence. - uint8 dtr = usb_cdcacm_get_dtr(); - switch (reset_state) { - case DTR_UNSET: - reset_state = dtr ? DTR_HIGH : DTR_LOW; - break; - case DTR_HIGH: - reset_state = dtr ? DTR_HIGH : DTR_NEGEDGE; - break; - case DTR_NEGEDGE: - reset_state = dtr ? DTR_HIGH : DTR_LOW; - break; - case DTR_LOW: - reset_state = dtr ? DTR_HIGH : DTR_LOW; - break; - } -} - -#define RESET_DELAY 100000 -static void wait_reset(void) { - delay_us(RESET_DELAY); - nvic_sys_reset(); -} - -#define STACK_TOP 0x20000800 -#define EXC_RETURN 0xFFFFFFF9 -#define DEFAULT_CPSR 0x61000000 -static void rxHook(unsigned hook, void *ignored) { - /* FIXME this is mad buggy; we need a new reset sequence. E.g. NAK - * after each RX means you can't reset if any bytes are waiting. */ - if (reset_state == DTR_NEGEDGE) { - reset_state = DTR_LOW; - - if (usb_cdcacm_data_available() >= 4) { - // The magic reset sequence is "1EAF". - static const uint8 magic[4] = {'1', 'E', 'A', 'F'}; - uint8 chkBuf[4]; - - // Peek at the waiting bytes, looking for reset sequence, - // bailing on mismatch. - usb_cdcacm_peek(chkBuf, 4); - for (unsigned i = 0; i < sizeof(magic); i++) { - if (chkBuf[i] != magic[i]) { - return; - } - } - - // Got the magic sequence -> reset, presumably into the bootloader. - // Return address is wait_reset, but we must set the thumb bit. - uintptr_t target = (uintptr_t)wait_reset | 0x1; - asm volatile("mov r0, %[stack_top] \n\t" // Reset stack - "mov sp, r0 \n\t" - "mov r0, #1 \n\t" - "mov r1, %[target_addr] \n\t" - "mov r2, %[cpsr] \n\t" - "push {r2} \n\t" // Fake xPSR - "push {r1} \n\t" // PC target addr - "push {r0} \n\t" // Fake LR - "push {r0} \n\t" // Fake R12 - "push {r0} \n\t" // Fake R3 - "push {r0} \n\t" // Fake R2 - "push {r0} \n\t" // Fake R1 - "push {r0} \n\t" // Fake R0 - "mov lr, %[exc_return] \n\t" - "bx lr" - : - : [stack_top] "r" (STACK_TOP), - [target_addr] "r" (target), - [exc_return] "r" (EXC_RETURN), - [cpsr] "r" (DEFAULT_CPSR) - : "r0", "r1", "r2"); - /* Can't happen. */ - ASSERT_FAULT(0); - } - } -} - -#endif // BOARD_HAVE_SERIALUSB diff --git a/STM32F3/cores/maple/wirish/wirish.h b/STM32F3/cores/maple/wirish/wirish.h deleted file mode 100644 index f1884b537..000000000 --- a/STM32F3/cores/maple/wirish/wirish.h +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief Main include file for the Wirish core. - * - * Includes most of Wirish, and (transitively or otherwise) - * substantial pieces of libmaple proper. - */ - -#ifndef _WIRISH_WIRISH_H_ -#define _WIRISH_WIRISH_H_ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#if (STM32_MCU_SERIES == STM32_SERIES_F1) || (STM32_MCU_SERIES == STM32_SERIES_F3) /* FIXME [0.0.13?] port to F2 */ -#include -#endif -#include -#include -#include -#include - -#include - -#include - -/* Wiring macros and bit defines */ - -#define true 0x1 -#define false 0x0 - -#define LSBFIRST 0 -#define MSBFIRST 1 - -#define lowByte(w) ((w) & 0xFF) -#define highByte(w) (((w) >> 8) & 0xFF) -#define bitRead(value, bit) (((value) >> (bit)) & 0x01) -#define bitSet(value, bit) ((value) |= (1UL << (bit))) -#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) -#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : \ - bitClear(value, bit)) -#define bit(b) (1UL << (b)) - -#endif - diff --git a/STM32F3/cores/maple/wirish/wirish_analog.cpp b/STM32F3/cores/maple/wirish/wirish_analog.cpp deleted file mode 100644 index 91ca0e28e..000000000 --- a/STM32F3/cores/maple/wirish/wirish_analog.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/wirish_analog.cpp - * @brief Wiring-style analogRead() implementation. - */ - -#include -#include -#include - -/* Unlike Wiring and Arduino, this assumes that the pin's mode is set - * to INPUT_ANALOG. That's faster, but it does require some extra work - * on the user's part. Not too much, we think ;). */ -uint16 analogRead(uint8 pin) { - const adc_dev *dev = PIN_MAP[pin].adc_device; - if (dev == NULL) { - return 0; - } - - return adc_read(dev, PIN_MAP[pin].adc_channel); -} diff --git a/STM32F3/cores/maple/wirish/wirish_digital.cpp b/STM32F3/cores/maple/wirish/wirish_digital.cpp deleted file mode 100644 index 2711a33ee..000000000 --- a/STM32F3/cores/maple/wirish/wirish_digital.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* - * Arduino-compatible digital I/O implementation. - */ - -#include - -#include -#include - -#include -#include - -uint32 digitalRead(uint8 pin) { - if (pin >= BOARD_NR_GPIO_PINS) { - return 0; - } - - return gpio_read_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit) ? - HIGH : LOW; -} - -void digitalWrite(uint8 pin, uint8 val) { - if (pin >= BOARD_NR_GPIO_PINS) { - return; - } - - gpio_write_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, val); -} - -void togglePin(uint8 pin) { - if (pin >= BOARD_NR_GPIO_PINS) { - return; - } - - gpio_toggle_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit); -} - -#define BUTTON_DEBOUNCE_DELAY 1 - -uint8 isButtonPressed(uint8 pin, uint32 pressedLevel) { - if (digitalRead(pin) == pressedLevel) { - delay(BUTTON_DEBOUNCE_DELAY); - while (digitalRead(pin) == pressedLevel) - ; - return true; - } - return false; -} - -uint8 waitForButtonPress(uint32 timeout) { - uint32 start = millis(); - uint32 time; - if (timeout == 0) { - while (!isButtonPressed()) - ; - return true; - } - do { - time = millis(); - /* properly handle wrap-around */ - if ((start > time && time + (0xffffffffU - start) > timeout) || - time - start > timeout) { - return false; - } - } while (!isButtonPressed()); - return true; -} diff --git a/STM32F3/cores/maple/wirish/wirish_math.cpp b/STM32F3/cores/maple/wirish/wirish_math.cpp deleted file mode 100644 index 1443b3c7f..000000000 --- a/STM32F3/cores/maple/wirish/wirish_math.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Modified by LeafLabs, LLC. - * - * Part of the Wiring project - http://wiring.org.co Copyright (c) - * 2004-06 Hernando Barragan Modified 13 August 2006, David A. Mellis - * for Arduino - http://www.arduino.cc/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include -#include - -void randomSeed(unsigned int seed) { - if (seed != 0) { - srand(seed); - } -} - -long random(long howbig) { - if (howbig == 0) { - return 0; - } - - return rand() % howbig; -} - -long random(long howsmall, long howbig) { - if (howsmall >= howbig) { - return howsmall; - } - - long diff = howbig - howsmall; - return random(diff) + howsmall; -} - diff --git a/STM32F3/cores/maple/wirish/wirish_math.h b/STM32F3/cores/maple/wirish/wirish_math.h deleted file mode 100644 index 39f16a055..000000000 --- a/STM32F3/cores/maple/wirish/wirish_math.h +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/include/wirish/wirish_math.h - * @brief Includes ; provides Wiring-compatible math routines. - */ - -#ifndef _WIRISH_WIRISH_MATH_H_ -#define _WIRISH_WIRISH_MATH_H_ - -#include - -/** - * @brief Initialize the pseudo-random number generator. - * @param seed the number used to initialize the seed; cannot be zero. - */ -void randomSeed(unsigned int seed); - -/** - * @brief Generate a pseudo-random number with upper bound. - * @param max An upper bound on the returned value, exclusive. - * @return A pseudo-random number in the range [0,max). - * @see randomSeed() - */ -long random(long max); - -/** - * @brief Generate a pseudo-random number with lower and upper bounds. - * @param min Lower bound on the returned value, inclusive. - * @param max Upper bound on the returned value, exclusive. - * @return A pseudo-random number in the range [min, max). - * @see randomSeed() - */ -long random(long min, long max); - -/** - * @brief Remap a number from one range to another. - * - * That is, a value equal to fromStart gets mapped to toStart, a value - * of fromEnd to toEnd, and other values are mapped proportionately. - * - * Does not constrain value to lie within [fromStart, fromEnd]. - * - * If a "start" value is larger than its corresponding "end", the - * ranges are reversed, so map(n, 1, 10, 10, 1) would reverse the - * range [1,10]. - * - * Negative numbers may appear as any argument. - * - * @param value the value to map. - * @param fromStart the beginning of the value's current range. - * @param fromEnd the end of the value's current range. - * @param toStart the beginning of the value's mapped range. - * @param toEnd the end of the value's mapped range. - * @return the mapped value. - */ -static inline long map(long value, long fromStart, long fromEnd, - long toStart, long toEnd) { - return (value - fromStart) * (toEnd - toStart) / (fromEnd - fromStart) + - toStart; -} - -#define PI 3.1415926535897932384626433832795 -#define HALF_PI 1.5707963267948966192313216916398 -#define TWO_PI 6.283185307179586476925286766559 -#define DEG_TO_RAD 0.017453292519943295769236907684886 -#define RAD_TO_DEG 57.295779513082320876798154814105 - -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) -#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) -#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) -#define radians(deg) ((deg)*DEG_TO_RAD) -#define degrees(rad) ((rad)*RAD_TO_DEG) -#define sq(x) ((x)*(x)) - -/* undefine stdlib's abs if encountered */ -#ifdef abs -#undef abs -#endif -#define abs(x) (((x) > 0) ? (x) : -(x)) - -/* Following are duplicate declarations (with Doxygen comments) for - * some of the math.h functions; this is for the convenience of the - * Sphinx docs. - */ - -/** - * Compute the cosine of an angle, in radians. - * @param x The radian measure of the angle. - * @return The cosine of x. This value will be between -1 and 1. - */ -double cos(double x); - -/** - * Compute the sine of an angle, in radians. - * @param x The radian measure of the angle. - * @return The sine of x. This value will be between -1 and 1. - */ -double sin(double x); - -/** - * Compute the tangent of an angle, in radians. - * @param x The radian measure of the angle. - * @return The tangent of x. There are no limits on the return value - * of this function. - */ -double tan(double x); - -/** - * Compute the square root of a number. - * @param x The number whose square root to find. This value cannot - * be negative. - * @return The square root of x. The return value is never negative. - */ -double sqrt(double x); - -/** - * Compute an exponentiation. - * @param x the base. This value cannot be zero if y <= 0. This value - * cannot be negative if y is not an integral value. - * @param y the exponent. - * @return x raised to the power y. - */ -double pow(double x, double y); - -#endif diff --git a/STM32F3/cores/maple/wirish/wirish_shift.cpp b/STM32F3/cores/maple/wirish/wirish_shift.cpp deleted file mode 100644 index a032d50f2..000000000 --- a/STM32F3/cores/maple/wirish/wirish_shift.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include - -void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 value) { - digitalWrite(clockPin, LOW); - for (int i = 0; i < 8; i++) { - int bit = bitOrder == LSBFIRST ? i : (7 - i); - digitalWrite(dataPin, (value >> bit) & 0x1); - togglePin(clockPin); - togglePin(clockPin); - } -} diff --git a/STM32F3/cores/maple/wirish/wirish_time.h b/STM32F3/cores/maple/wirish/wirish_time.h deleted file mode 100644 index eb6c68fd2..000000000 --- a/STM32F3/cores/maple/wirish/wirish_time.h +++ /dev/null @@ -1,95 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/include/wirish/wirish_time.h - * @brief Timing and delay functions. - */ - -#ifndef _WIRISH_WIRISH_TIME_H_ -#define _WIRISH_WIRISH_TIME_H_ - -#include -#include - -#include - -/** - * Returns time (in milliseconds) since the beginning of program - * execution. On overflow, restarts at 0. - * @see micros() - */ -static inline uint32 millis(void) { - return systick_uptime(); -} - -/** - * Returns time (in microseconds) since the beginning of program - * execution. On overflow, restarts at 0. - * @see millis() - */ -static inline uint32 micros(void) { - uint32 ms; - uint32 cycle_cnt; - - do { - ms = millis(); - cycle_cnt = systick_get_count(); - } while (ms != millis()); - -#define US_PER_MS 1000 - /* SYSTICK_RELOAD_VAL is 1 less than the number of cycles it - * actually takes to complete a SysTick reload */ - return ((ms * US_PER_MS) + - (SYSTICK_RELOAD_VAL + 1 - cycle_cnt) / CYCLES_PER_MICROSECOND); -#undef US_PER_MS -} - -/** - * Delay for at least the given number of milliseconds. - * - * Interrupts, etc. may cause the actual number of milliseconds to - * exceed ms. However, this function will return no less than ms - * milliseconds from the time it is called. - * - * @param ms the number of milliseconds to delay. - * @see delayMicroseconds() - */ -void delay(unsigned long ms); - -/** - * Delay for at least the given number of microseconds. - * - * Interrupts, etc. may cause the actual number of microseconds to - * exceed us. However, this function will return no less than us - * microseconds from the time it is called. - * - * @param us the number of microseconds to delay. - * @see delay() - */ -void delayMicroseconds(uint32 us); - -#endif diff --git a/STM32F3/cores/maple/wirish/wirish_types.h b/STM32F3/cores/maple/wirish/wirish_types.h deleted file mode 100644 index fce895ef0..000000000 --- a/STM32F3/cores/maple/wirish/wirish_types.h +++ /dev/null @@ -1,68 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/include/wirish/wirish_types.h - * @author Marti Bolivar - * @brief Wirish library type definitions. - */ - -#ifndef _WIRISH_WIRISH_TYPES_H_ -#define _WIRISH_WIRISH_TYPES_H_ - -#include -#include -#include -#include - -/** - * Invalid stm32_pin_info adc_channel value. - * @see stm32_pin_info - */ -#define ADCx 0xFF - -/** - * @brief Stores STM32-specific information related to a given Maple pin. - * @see PIN_MAP - */ -typedef struct stm32_pin_info { - gpio_dev *gpio_device; /**< Maple pin's GPIO device */ - timer_dev *timer_device; /**< Pin's timer device, if any. */ - const adc_dev *adc_device; /**< ADC device, if any. */ - uint8 gpio_bit; /**< Pin's GPIO port bit. */ - uint8 timer_channel; /**< Timer channel, or 0 if none. */ - uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ -} stm32_pin_info; - -/** - * Variable attribute, instructs the linker to place the marked - * variable in Flash instead of RAM. */ -#define __FLASH__ __attr_flash - -typedef uint8 boolean; -typedef uint8 byte; - -#endif diff --git a/STM32F3/examples/Blinkf3/Blinkf3.ino b/STM32F3/examples/Blinkf3/Blinkf3.ino deleted file mode 100644 index 2bcb9290a..000000000 --- a/STM32F3/examples/Blinkf3/Blinkf3.ino +++ /dev/null @@ -1,38 +0,0 @@ -/* - Blink - Turns on an LED on for one second, then off for one second, repeatedly. - - Most Arduinos have an on-board LED you can control. On the Uno and - Leonardo, it is attached to digital pin 13. If you're unsure what - pin the on-board LED is connected to on your Arduino model, check - the documentation at http://arduino.cc - - This example code is in the public domain. - - modified 8 May 2014 - by Scott Fitzgerald - - modified for stm32f3discovery - 2015/02 by Frank-Michael Krause - */ - - -// the setup function runs once when you press reset or power the board -void setup() { - // initialize pins PE8, PE9 as an output. - pinMode(PE8, OUTPUT); - pinMode(PE9, OUTPUT); - Serial2.begin(9600); - Serial2.println("Hello world"); - -} - -// the loop function runs over and over again forever -void loop() { - digitalWrite(PE8, HIGH); // turn the LED on (HIGH is the voltage level) - digitalWrite(PE9, LOW); // turn the LED off by making the voltage LOW - delay(100); // wait for a second - digitalWrite(PE8, LOW); // turn the LED off by making the voltage LOW - digitalWrite(PE9, HIGH); // turn the LED on (HIGH is the voltage level) - delay(300); // wait for a second -} diff --git a/STM32F3/examples/f3_buttondemo/f3_buttondemo.ino b/STM32F3/examples/f3_buttondemo/f3_buttondemo.ino deleted file mode 100644 index c6a9c0d78..000000000 --- a/STM32F3/examples/f3_buttondemo/f3_buttondemo.ino +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - - -/* - * This demo shows how to handle the blue button of the stm32f3discovery board - * - * Dieses Beispiel zeigt, wie die blaue Taste des Boards abgefragt werden kann. - * Es wird eine LED ein- bzw. ausgeschaltet. - */ - - -void setup() // Init-Funktion -{ - // BOARD_LED_PIN ist PE10 - pinMode(BOARD_LED_PIN, OUTPUT); - - // BOARD_BUTTTON_PIN ist PA0 - pinMode(BOARD_BUTTON_PIN, INPUT); - -} - - -void loop() -{ - if (isButtonPressed()) - togglePin(BOARD_LED_PIN); -} - - - diff --git a/STM32F3/examples/f3_functionTimer/f3_functionTimer.ino b/STM32F3/examples/f3_functionTimer/f3_functionTimer.ino deleted file mode 100644 index ca8fce9a1..000000000 --- a/STM32F3/examples/f3_functionTimer/f3_functionTimer.ino +++ /dev/null @@ -1,144 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - - -#include -#include - -/* - * Demo program function timer - * - * You can define functions register those functions at the timer system - * to be called after the time in ms given at timer start - * - * - there are 10 timers with id from 0 to 9 - * - the id has to be given at timer start - * - there can only be running one instance of a timer id at one time - * - at each timer start another function can be registered - * - time resolution is 5ms - * - * The registered function will be executed in interrupt context. - * Therefore the timer funtion shall be execute very fast. - * - * If using functtion timer and ultrasonic sensors in parallel the measurement results of - * the sensors can be slightly wrong. - * - * This demo controls three LEDs with different blinking rythms - */ - - -/* - * Demoprogramm fuer Funktions-Timer - * - * Es koennen Funktionen definiert und dem Timersystem-uebergeben werden, - * die nach einer uebergebenen Zeit aufgerufen werden. - * - * - Jeder Timer hat eine id zwischen 0 und 9, die beim Start angegeben werden muss. - * - Es kann nur ein Timer pro Id zu gleichen Zeit laufen - * - Es kann bei jedem Start eines Timers eine andere Funktion uebergeben werden. - * - * Die uebergebene Funktion wird im Interrupt-Kontext ausgefuehrt und unterbricht das - * normal in setup/loop ausgefuehrte Programm an beliebiger Stelle. - * Es ist darauf zu achten, dass die Timerfuntion moeglichst kurz, d.h. schnell ausfuehrbar, ist. - * - * Die parallele Ausfuehrung von Funktionstimern kann die Messergebnisse von Ultraschallsensoren - * leicht verfaelschen! - * - * Das Demoprogramm steuert drei LEDs mit unterschiedlichen Blink-Zeiten an. - * - */ - - - -// 500ms Bink mit Steuerung ueber Timer-Id 0 -#define LED PE9 -int LEDState = 0; -void TimerFunction(int arg) -{ - if (LEDState) - LEDState = 0; - else - LEDState = 1; - digitalWrite(LED, LEDState); - timerStart(0, 500, TimerFunction, 0 ); // restart Timer -} - - -// 900ms Bink mit Steuerung ueber Timer-Id 1 -#define LED1 PE10 -int LED1State = 0; -void Timer1Function(int arg) -{ - if (LED1State) - LED1State = 0; - else - LED1State = 1; - digitalWrite(LED1, LED1State); - timerStart(1, 900, Timer1Function, 0 ); // restart Timer -} - - -// 1300ms Bink mit Steuerung ueber Timer-Id 2 -#define LED2 PE11 -int LED2State = 0; -void Timer2Function(int arg) -{ - if (LED2State) - LED2State = 0; - else - LED2State = 1; - digitalWrite(LED2, LED2State); - timerStart(2, 1300, Timer2Function, 0 ); // restart Timer -} - - - - -void setup() -{ - pinMode(LED, OUTPUT); - pinMode(LED1, OUTPUT); - pinMode(LED2, OUTPUT); - - // Timer-System initialisieren - timerInit(); - - // Timer starten - timerStart(0, 500, TimerFunction, 0 ); - timerStart(1, 900, Timer1Function, 0 ); - timerStart(2, 1300, Timer2Function, 0 ); -} - -void loop() -{ - // Die Programmabarbeitung erfolgt komplett im Interrupt, - // daher muss in loop nichts getan werden - while (1) - ; -} - - - diff --git a/STM32F3/examples/f3_gyrodemo/f3_gyrodemo.ino b/STM32F3/examples/f3_gyrodemo/f3_gyrodemo.ino deleted file mode 100644 index 8e3ca2b33..000000000 --- a/STM32F3/examples/f3_gyrodemo/f3_gyrodemo.ino +++ /dev/null @@ -1,100 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include - -#include -#include - - - -/** - * Dieses Beispiel benutzt die Z-Achse des Gyro-Sensors, um eine Drehung des Boards - * zu messen und anzuzeigen. - * Wenn das Board um seine Z-Achse gedreht wird, so zeigt die jeweils aktive LED - * immer in die gleiche Richtung. - * Mit der Zeit ändert sich die angezeigte Richtung, da die Messwerte kleine - * Fehler haben, die sich mit der Zeit aufsummieren und das Programm keine - * Kalibrierung und Fehlerkorrektur enthält. Die Größe des Fehlers ist von - * Board zu Board unterschiedlich. - * - */ - -// Array mit den LED-Pins -int leds[] = { PE9, PE10, PE11, PE12, PE13, PE14, PE15, PE8 }; - - -void setup() // Init-Funktion -{ - // Die 8 LED-Pins auf Ausgang setzen - pinMode (leds[0], OUTPUT); - pinMode (leds[1], OUTPUT); - pinMode (leds[2], OUTPUT); - pinMode (leds[3], OUTPUT); - pinMode (leds[4], OUTPUT); - pinMode (leds[5], OUTPUT); - pinMode (leds[6], OUTPUT); - pinMode (leds[7], OUTPUT); - - // SPI1-Interface initialisieren - gyroSpiInit(); - - // den Gyrochip initialisieren - gyroInit(); - - // Gyro aktivieren - gyroStart(); -} - - -int led_idx; - -void loop() -{ - // Auslesen der Gyro-Messwerte und Berechnen des aktuellen Drehwinkels - gyroUpdate(); - - // Wenn der Winkel 360° überschreitet oder 0° unterschreitet - // werden 360° abgezogen bzw. addiert - if (winkelz>360) - winkelz -= 360; - else if (winkelz<0) - winkelz += 360; - - // aktuell aktive LED abschalten - digitalWrite(leds[led_idx], LOW); - - // anhand des Winkels die neue Aktive LED bestimmen. - // Dazu wird mit Dreisatz der Winkel (0..360) auf die LED (0..7) abgebildet - led_idx = (winkelz*8)/360; - - // aktive LED anschalten - digitalWrite(leds[led_idx], HIGH); - - delay(50); -} - - - diff --git a/STM32F3/examples/f3_lsm303demo/f3_lsm303demo.ino b/STM32F3/examples/f3_lsm303demo/f3_lsm303demo.ino deleted file mode 100644 index 63251aa1f..000000000 --- a/STM32F3/examples/f3_lsm303demo/f3_lsm303demo.ino +++ /dev/null @@ -1,111 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include -#include -#include - -#include -#include - - -/** - * Dieses Beispiel wertet die x und y Werte des Beschleunigungssensors aus - * und zeigt über die 8 LEDs an, in welche Richtung das Board gekippt wurde. - * Die z-Komponente wird nicht ausgewertet. - */ - - -// Array mit den LED-Pins -int leds[] = { PE9, PE10, PE11, PE12, PE13, PE14, PE15, PE8 }; - - -void setup() // Init-Funktion -{ - // Die 8 LED-Pins auf Ausgang setzen - pinMode (leds[0], OUTPUT); - pinMode (leds[1], OUTPUT); - pinMode (leds[2], OUTPUT); - pinMode (leds[3], OUTPUT); - pinMode (leds[4], OUTPUT); - pinMode (leds[5], OUTPUT); - pinMode (leds[6], OUTPUT); - pinMode (leds[7], OUTPUT); - - // I2C-Interface initialisieren, mit dem der - // Beschleunigungssensor verbunden ist - i2c_master_enable(I2C1, 0); - - // Beschleunigungssensor initialisieren - lsm303Init(); - -} - -// Speicher für die aktuell aktive LED -int led_idx; - -void loop() -{ - float winkel; - - // Beschleunigungssensor lesen - readAccValues(); - - // Winkel entsprechend der gemessenen x und y Komponente - // berechnen - // atan2 gibt den Winkel im Bogenmass zurueck, 2*Pi entsprechen 360° - winkel = atan2(accy*-1.0,accx*1.0); - - // Umrechnung des Winkels auf die 8 LEDs, aus denen der Vollkreis (2*Pi) - // besteht (Dreisatz, Umrechnung mit 4 und Pi) - winkel = (winkel*4)/3.14; - - // Falls der Winkel negativ ist, eine Vollkreis-Wert hinzurechnen - // für unser Beispiel 8 - if (winkel<0) - winkel += 8; - - // alte aktive LED ausschalten - digitalWrite(leds[led_idx], LOW); - - // der Ganzzahl-Anteil des Winkels ist der Index der neuen LED - // Das (int) vor winkel führt die Umwandlung der Kommanzahl in einen Integer-Wert - // durch. Das nennt man einen Type-Cast. Der ist hier nötig, da eine - // float Variable nicht direkt einer Integervariable zugewiesen werden kann - led_idx = (int)winkel; - - // nochmal prüfen, ob der neue Led-Index nicht zu groß ist - // wenn ja auf maximalwert setzen - if (led_idx>7) - led_idx=7; - - // neue LED anschalten - digitalWrite(leds[led_idx], HIGH); - - delay(50); -} - - - diff --git a/STM32F3/examples/f3_ultrasonic/f3_ultrasonic.ino b/STM32F3/examples/f3_ultrasonic/f3_ultrasonic.ino deleted file mode 100644 index aa8bc5c56..000000000 --- a/STM32F3/examples/f3_ultrasonic/f3_ultrasonic.ino +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include -#include -#include - -/* - * Demoprogramm für den Betrieb von Ultraschallsensoren über Interrupts. - * - * Diese Betriebsart hat den Vorteil, dass während der Messung (die einige 10ms dauern kann) - * andere Dinge erledigt werden können. - * - * Es kann ständig im Hintergrund gemessen werden und der letzte gültige oder der aktuelle - * Messwert per Funktion abgefragt werden. - * - * Außerdem kann eine Callbackfunktion pro Sensor registriert werden, die nach einer erfolgten - * Messung aufgerufen wird. ZU beachten ist, dass diese Funktion im Interrupt-Kontext aufgerufen wird - * und daher möglichst kurz (d.h. schnell abarbeitbar) sein. - * Bei Debug-Ausgaben in der Handler-Funktion können sich die Ausgaben in Ausgaben aus loop() heraus "hineindrängeln" - * - */ - - -//----------------- Ultraschall ----------------------- -// 3x HC-SR04 - -#define US1_ECHO PD4 -#define US1_TRIGGER PB4 - -#define US2_ECHO PD5 -#define US2_TRIGGER PB5 - -#define US3_ECHO PD6 -#define US3_TRIGGER PB8 - - - -void UsHandler(int id, int entfernung) -{ - Print2Number("Sensor", id, entfernung); -} - - -void setup() -{ - delay(150); - debugInit(); - debugSetTimeStamp(DDEBUG_TIME_STAMP_ON); - - // Ultraschallsensoren definieren - addUSSensor(0, US1_TRIGGER, US1_ECHO, 220); - addUSSensor(1, US2_TRIGGER, US2_ECHO, 220); - addUSSensor(2, US3_TRIGGER, US3_ECHO); - - UsAttachHandler(0, UsHandler); - UsSetMessPause(100); // Pause von 100 ms nach jeder Messung - // damit die Ausgabe im Terminal nicht zu schnell wird - // Im Normalfall würde keine so lange Pause programmiert werden. - // Die Pause ist nur nötig, wenn festgestellt wird, dass sich - // die Sensoren gegenseitig durch nachfolgende mehrfache Echos beeinflussen. - // Das ist Umgebungsabhängig. - - debugPrint("activate Sensor 0 ---------------"); - aktiviereUSSensor(0); - PrintUsSensorList(); - debugPrint("activate Sensor 1 ---------------"); - aktiviereUSSensor(1); - PrintUsSensorList(); - - debugPrint("activate Sensor 2 ---------------"); - aktiviereUSSensor(2); - PrintUsSensorList(); - - // ab jetzt wird im Hintergrund gemessen - - delay(1000); - debugPrint("deactivate Sensor 2 ---------------"); - deaktiviereUSSensor(2); - PrintUsSensorList(); - - delay(1000); - debugPrint("deactivate Sensor 1 ---------------"); - deaktiviereUSSensor(1); - PrintUsSensorList(); - - delay(1000); - debugPrint("deactivate Sensor 0 ---------------"); - deaktiviereUSSensor(0); - PrintUsSensorList(); - - delay(1000); - debugPrint("activate Sensor 0 ---------------"); - aktiviereUSSensor(0); - PrintUsSensorList(); - - delay(1000); - debugPrint("activate Sensor 1 ---------------"); - aktiviereUSSensor(1); - PrintUsSensorList(); - - - debugPrint("Programm gestartet"); -} - -void loop() -{ - Print2Number("Sensor 1", UsLetzterGueltigerMesswert(1), UsLetzterGueltigerMesswertAlter(1)); - delay(300); -} - - - - diff --git a/STM32F3/libraries/gyro/gyro.cpp b/STM32F3/libraries/gyro/gyro.cpp deleted file mode 100644 index ef3722c6c..000000000 --- a/STM32F3/libraries/gyro/gyro.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief functions for accessing l3g20 gyro on stm32f3discovery board - * - * SPI1 is set up to be a master - * at 9 MHz (SPI_1_125MHZ), - * 8 Bit - * MSB first in/out (MSBFIRST) - * MODE 0 // following the datasheet it should be MODE 3 but 0 is working too - * - * Pin PE3 is used as slave select, as defined for SPI1 in board.h - * - * There is no interrupt support because I was not able to get out any int2-output of the chip - * - */ - -#include -#include "l3gd20.h" -#include "../ringbuffer/ringbuffer.h" -#include "gyro.h" - - -#define NSS PE3 -#define GYRO_FIFO_WATERMARK 10 - -HardwareSPI spi1(1); -static uint8 gyroValuesSingle[6]; - -static int GYRO_BIAS_X = -75; -static int GYRO_BIAS_Y = 94; -static int GYRO_BIAS_Z = 0; - -float winkelx, winkely, winkelz; -int gyroxRaw, gyroyRaw, gyrozRaw; // bei jedem Update wird ein Datensatz der gelesenen - // Werte in den Raw-Variablen gespeichert um den Bias pr�fen zu - // k�nnen - -#define RB_SIZE 256 -#define GYRO_AVERAGE_X 120 -#define GYRO_AVERAGE_Y 120 -#define GYRO_AVERAGE_Z 120 - -static int rbvx[RB_SIZE]; -static int rbvy[RB_SIZE]; -static int rbvz[RB_SIZE]; -static RingBufferAverage rbx(RB_SIZE, rbvx, NULL, GYRO_AVERAGE_X); -static RingBufferAverage rby(RB_SIZE, rbvy, NULL, GYRO_AVERAGE_Y); -static RingBufferAverage rbz(RB_SIZE, rbvz, NULL, GYRO_AVERAGE_Z); - -static int averageActiveX = 0; -static int averageActiveY = 0; -static int averageActiveZ = 0; - -void readGyroValues() -{ - int j; - digitalWrite(NSS, LOW); - spi1.transfer(0xA8|0x40); - - for (j=0; j<6; j++) - gyroValuesSingle[j] = spi1.transfer(0); - - digitalWrite(NSS, HIGH); -} - -uint8 gyroReadRegister(uint8 reg) -{ - digitalWrite(NSS, LOW); - spi1.transfer(reg|0x80); - - uint8 val = spi1.transfer(0); - - digitalWrite(NSS, HIGH); - return val; -} - -void gyroWriteRegister(uint8 reg, uint8 val) -{ - digitalWrite(NSS, LOW); - spi1.transfer(reg); - spi1.transfer(val); - digitalWrite(NSS, HIGH); -} - -/** - * Initialisiert das spi1 interface des stm32f3discovery - */ -void gyroSpiInit() -{ - spi1.begin(SPI_9MHZ, MSBFIRST, 0); - /* NSS is usually active LOW, so initialize it HIGH */ - pinMode(NSS, OUTPUT); - digitalWrite(NSS, HIGH); -} - -#define GYRO_OP_PARAMS (GYRO_ODR_190|GYRO_LP_BW1|GYRO_ENABLE) - -/** - * konfiguriert den Gyro. - * der Gyro ist nach dem Aufruf der Funktion aktiv. Wird er nicht mehr benötigt, kann er - * mir gyroStop() wieder deaktiviert werden. Für eine Reaktivierung kann die Funktion - * gyroStart() verwendet werden. - * - * Im aktiven Zustand muss im Abstand von höchstens 120ms die Funktion gyroUpdate() - * aufgerufen werden. - * - * Die globalen Variablen winkelx, winkely und winkelz enthalten den jeweils aktuellen winkel. - * Die Funktion gyroResetWinkel setzt die globalen Variablen wieder auf 0. - */ -void gyroInit() -{ - /* Initialize SPI */ - // gyroSpiInit(); --> called aus dem Anwendungsmodul, - // da an SPI1 noch weitere Ger�te betrieben werden - - // Initialize GyroChip - // 190Hz data Rate, 50Hz Bandwidth - gyroWriteRegister(GYRO_REG_CTRL_REG1, GYRO_OP_PARAMS); - - // CTRL_REG2 --> no High Pass --> nothing to change - - // enable Watermark interrupt on INT2 --> not working no int pulse - // gyroWriteRegister(GYRO_REG_CTRL_REG3, GYRO_I2_EN|GYRO_I2_WTM); - - // set resolution to 500 dps - gyroWriteRegister(GYRO_REG_CTRL_REG4, GYRO_FULL_SCALE_500); - - // enable FIFO, Output after second LP-Filter, no HP - gyroWriteRegister(GYRO_REG_CTRL_REG5, GYRO_FIFO_ENABLE|GYRO_OUT_SELECT2); - //gyroWriteRegister(GYRO_REG_CTRL_REG5, GYRO_OUT_SELECT2); - - //Fifomode and watermark - gyroWriteRegister(GYRO_REG_FIFO_CTRL, GYRO_FIFO_MODE_STREAM|GYRO_FIFO_WATERMARK); -} - -/** - * Es werden 1000 Werte eingelesen (ca. 5,5s) und aus den Werten die Drift-Kompensations- - * werte gemittelt. Der Gyro darf während der Zeit nicht bewegt werden. - */ -void gyroCalibrate() { - int count = 0; - int sumx=0,sumy=0,sumz=0; - - #ifdef DEBUG_GYRO - SerialUSB.print("Biaswerte ermitteln "); - #endif - while (count < 1000) - { - delay(100); - uint8 anz = gyroReadRegister(GYRO_REG_FIFO_SRC) & 0x1F; - for (int i=0; i -#include -#include "lsm303reg.h" -#include "../ringbuffer/ringbuffer.h" -#include "lsm303.h" - -#define ACC_FIFO_WATERMARK 10 - -static int ACC_BIAS_X; -static int ACC_BIAS_Y; -static int ACC_BIAS_Z; - - -int accx, accy, accz; - -#define RB_SIZE 64 -#define ACC_AVERAGE_X 60 -#define ACC_AVERAGE_Y 60 -#define ACC_AVERAGE_Z 60 - -static int rbvx[RB_SIZE]; -static long unsigned int rbtx[RB_SIZE]; -static int rbvy[RB_SIZE]; -static long unsigned int rbty[RB_SIZE]; -static int rbvz[RB_SIZE]; -static long unsigned int rbtz[RB_SIZE]; -static RingBuffer rbx(RB_SIZE, rbvx, rbtx); -static RingBuffer rby(RB_SIZE, rbvy, rbty); -static RingBuffer rbz(RB_SIZE, rbvz, rbtz); - -//static int averageActiveX = 0; -//static int averageActiveY = 0; -//static int averageActiveZ = 0; - - -static uint8 write_msg_data[3]; -static i2c_msg write_msg; - -static uint8 read_msg_data[7]; -static i2c_msg read_msg; - - -void readAccValues() -{ - int16 *p; - write_msg_data[0] = LSM303_REG_OUT_X_L_A|LSM303_READ_MULTI_BYTES; // 0x80 -> AutoIncrement address on read - write_msg.length = 1; - i2c_master_xfer(I2C1, &write_msg, 1, 0); - - read_msg.length = 6; - i2c_master_xfer(I2C1, &read_msg, 1, 2); - - p = (int16*)read_msg_data; - accx = *p++ - ACC_BIAS_X; - accy = *p++ - ACC_BIAS_Y; - accz = *p++ - ACC_BIAS_Z; -} - -uint8 accReadRegister(uint8 reg) -{ - write_msg_data[0] = reg; - write_msg.length = 1; - i2c_master_xfer(I2C1, &write_msg, 1, 0); - - read_msg.length = 1; - i2c_master_xfer(I2C1, &read_msg, 1, 2); - - return read_msg_data[0]; -} - -void accWriteRegister(uint8 reg, uint8 val) -{ - write_msg_data[0] = reg; - write_msg_data[1] = val; - write_msg.length = 2; - i2c_master_xfer(I2C1, &write_msg, 1, 0); -} - - -void lsm303I2CInit() -{ - //i2c_master_enable(I2C1, 0); - // Aktivierung des I2C-Busses muss im Hauptprogramm erfolgen, - // da mehrere Komponenten das I2C-Interface benutzen k�nnen - // und eine mehrfache Initialisierung nicht funktioniert - - write_msg.addr = LSM303_ADDR_A; - write_msg.flags = 0; // write, 7 bit address - write_msg.length = sizeof(write_msg_data); - write_msg.xferred = 0; - write_msg.data = write_msg_data; - - read_msg.addr = LSM303_ADDR_A; - read_msg.flags = I2C_MSG_READ; - read_msg.length = sizeof(read_msg_data); - read_msg.xferred = 0; - read_msg.data = read_msg_data; - -} - -/** - * Initialisiert und aktiviert den Beschleunigungssensor - * Aktivierung des I2C-Busses muss im Hauptprogramm erfolgen, - * da mehrere Komponenten das I2C-Interface benutzen k�nnen - * und eine mehrfache Initialisierung nicht funktioniert - */ -void lsm303Init() -{ - /* Initialize I2C Transfer-Strukturen f�r den lsm303*/ - lsm303I2CInit(); - - // Initialize ACC-Chip - // 50Hz data Rate - accWriteRegister(LSM303_REG_CTRL_REG1_A, LSM303_A_ODR_50HZ|LSM303_A_ALL_AXIS_EN); - - // CTRL_REG2 --> no High Pass --> nothing to change - - // enable Watermark interrupt on INT2 --> not working no int pulse - // gyroWriteRegister(GYRO_REG_CTRL_REG3, GYRO_I2_EN|GYRO_I2_WTM); - - // sensitivity 2G is default - - // enable FIFO ? - - //Fifomode and watermark -} - - -void accCalibrate() { - int count = 0; - int sumx=0,sumy=0,sumz=0; - - #ifdef DEBUG_ACC - SerialUSB.print("Biaswerte ermitteln "); - #endif - while (count < 100) - { - delay(3); - readAccValues(); - sumx += accx; - sumy += accy; - sumz += accz; - #ifdef DEBUG_ACC - SerialUSB.print("*"); - #endif - count += 1; - } - ACC_BIAS_X = sumx/count; - ACC_BIAS_Y = sumy/count; - ACC_BIAS_Z = sumz/count; - - #ifdef DEBUG_ACC - SerialUSB.println(""); - SerialUSB.print("ACC-BIAS "); - SerialUSB.print(ACC_BIAS_X); SerialUSB.print(" "); - SerialUSB.print(ACC_BIAS_Y); SerialUSB.print(" "); - SerialUSB.println(ACC_BIAS_Z); - #endif -} - - - -void accUpdate() -{ - //uint8 gyroFifoStatus = gyroReadRegister(GYRO_REG_FIFO_SRC); - //uint8 anz = gyroFifoStatus & 0x1F; - - #ifdef DEBUG_ACC -// SerialUSB.print("fifo anz = "); -// SerialUSB.print(anz); -// SerialUSB.print(" "); - #endif - - readAccValues(); - - rbx.addValue(accx); - rby.addValue(accy); - rbz.addValue(accz); - - #ifdef DEBUG_ACC - SerialUSB.print(accx); SerialUSB.print(" "); - SerialUSB.print(accy); SerialUSB.print(" "); - SerialUSB.print(accz); SerialUSB.print(" "); - SerialUSB.println(""); - #endif -} - -void accStart() -{ - rbx.reset(); - rby.reset(); - rbz.reset(); -} - -void accStop() -{ -} - diff --git a/STM32F3/libraries/lsm303/lsm303.h b/STM32F3/libraries/lsm303/lsm303.h deleted file mode 100644 index 78a9d161a..000000000 --- a/STM32F3/libraries/lsm303/lsm303.h +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#ifndef LSM303_H -#define LSM303_H - - -#define ACC_AXIS_X 1 -#define ACC_AXIS_Y 2 -#define ACC_AXIS_Z 3 - - -/** - * Initialisiert das spi1 interface des stm32f3discovery und konfiguriert den Gyro. - * der Gyro ist nach dem Aufruf der Funktion aktiv. Wird er nicht mehr benötigt, kann er - * mir gyroStop() wieder deaktiviert werden. Für eine Reaktivierung kann die Funktion - * gyroStart() verwendet werden. - * - * Im aktiven Zustand muss im Abstand von höchstens 120ms die Funktion gyroUpdate() - * aufgerufen werden. - * - * Die globalen Variablen winkelx, winkely und winkelz enthalten den jeweils aktuellen winkel. - * Die Funktion gyroResetWinkel setzt die globalen Variablen wieder auf 0. - */ -extern void lsm303Init(); - - -/** - */ -extern void lsm303Calibrate(); - - -/** - */ -extern void accUpdate(); - -/** - */ -extern void accStart(); - -/** - * Versetzt den Beschleunigungssensor in den Power Down mode - */ -extern void accStop(); - - -//---------------------------------------------------------------------------------- -// gobale Variablen - -extern int accx, accy, accz; - - -extern void readAccValues(); - -#endif diff --git a/STM32F3/libraries/lsm303/lsm303reg.h b/STM32F3/libraries/lsm303/lsm303reg.h deleted file mode 100644 index 7bf3f80b5..000000000 --- a/STM32F3/libraries/lsm303/lsm303reg.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef __LSM303REG_H_ -#define __LSM303REG_H_ - -#define LSM303_ADDR_A (0x32>>1) -#define LSM303_ADDR_M (0x3C>>1) - -#define LSM303_REG_CTRL_REG1_A 0x20 -#define LSM303_REG_CTRL_REG2_A 0x21 -#define LSM303_REG_CTRL_REG3_A 0x22 -#define LSM303_REG_CTRL_REG4_A 0x23 -#define LSM303_REG_CTRL_REG5_A 0x24 -#define LSM303_REG_CTRL_REG6_A 0x25 -#define LSM303_REG_REFERENCE_A 0x26 -#define LSM303_REG_STATUS_A 0x27 -#define LSM303_REG_OUT_X_L_A 0x28 -#define LSM303_REG_OUT_X_H_A 0x29 -#define LSM303_REG_OUT_Y_L_A 0x2A -#define LSM303_REG_OUT_Y_H_A 0x2B -#define LSM303_REG_OUT_Z_L_A 0x2C -#define LSM303_REG_OUT_Z_H_A 0x2D -#define LSM303_REG_FIFO_CTRL_A 0x2E -#define LSM303_REG_FIFO_SRC_A 0x2F -#define LSM303_REG_INT1_CFG_A 0x30 -#define LSM303_REG_INT1_SRC_A 0x31 -#define LSM303_REG_INT1_THS_A 0x32 -#define LSM303_REG_INT1_DUARATION_A 0x33 -#define LSM303_REG_INT2_CFG_A 0x34 -#define LSM303_REG_INT2_SRC_A 0x35 -#define LSM303_REG_INT2_THS_A 0x36 -#define LSM303_REG_INT2_DURATION_A 0x37 -#define LSM303_REG_CLICK_CFG_A 0x38 -#define LSM303_REG_CLICK_SRC_A 0x39 -#define LSM303_REG_CLICK_THS_A 0x3A -#define LSM303_REG_TIME_LIMIT_A 0x3B -#define LSM303_REG_TIME_LATENCY_A 0x3C -#define LSM303_REG_TIME_WINDOW_A 0x3D - -#define LSM303_READ_MULTI_BYTES 0x80 - - -//================================================================== -// CTRL_REG1 - -#define LSM303_A_ODR_1HZ 0x10 -#define LSM303_A_ODR_10HZ 0x20 -#define LSM303_A_ODR_25HZ 0x30 -#define LSM303_A_ODR_50HZ 0x40 -#define LSM303_A_ODR_100HZ 0x50 -#define LSM303_A_ODR_200HZ 0x60 -#define LSM303_A_ODR_400HZ 0x70 -#define LSM303_A_ODR_1620HZ 0x80 -#define LSM303_A_ODR_1344Hz 0x90 - -#define LSM303_A_LOWPOWER_EN 0x08 -#define LSM303_A_X_EN 0x01 -#define LSM303_A_Y_EN 0x02 -#define LSM303_A_Z_EN 0x04 -#define LSM303_A_ALL_AXIS_EN 0x07 - - -//================================================================== -// CTRL_REG2 - HP-Filter config - -//================================================================== -// CTRL_REG3 - Int1 config - -#define LSM303_A_I1_CLICK 0x80 -#define LSM303_A_I1_AOI1 0x40 -#define LSM303_A_I1_AOI2 0x20 -#define LSM303_A_I1_DRDY1 0x10 -#define LSM303_A_I1_DRDY2 0x08 -#define LSM303_A_I1_WTM 0x04 -#define LSM303_A_I1_OVERRUN 0x02 - - -//================================================================== -// CTRL_REG4 - Sensitivity, Endianess and SPI config - -#define LSM303_A_FS_2G 0x00 // default -#define LSM303_A_FS_4G 0x10 -#define LSM303_A_FS_8G 0x20 -#define LSM303_A_FS_16G 0x30 - - - -//================================================================== -// CTRL_REG5 - Fifo and other - -#define LSM303_A_FIFO_EN 0x40 - -//================================================================== -// CTRL_REG6 - INT2 config - -//================================================================== -// FIFO_CTRL - -#define LSM303_A_FIFO_MODE_BYPASS 0b00000000 -#define LSM303_A_FIFO_MODE_FIFO 0b01000000 -#define LSM303_A_FIFO_MODE_STREAM 0b10000000 -#define LSM303_A_FIFO_MODE_TRIGGER 0b11000000 - -#define LSM303_A_FIFO_TR 0b00100000 - - -//================================================================== -//================================================================== -//================================================================== -// Magnetometer register -//================================================================== -//================================================================== -//================================================================== - -#define LSM303_REG_CRA_M 0x00 -#define LSM303_REG_CRB_M 0x01 -#define LSM303_REG_MR_M 0x02 -#define LSM303_REG_OUTX_H_M 0x03 -#define LSM303_REG_OUTX_L_M 0x04 -#define LSM303_REG_OUTY_H_M 0x05 -#define LSM303_REG_OUTY_L_M 0x06 -#define LSM303_REG_OUTZ_H_M 0x07 -#define LSM303_REG_OUTZ_L_M 0x08 -#define LSM303_REG_Mg_M 0x09 -#define LSM303_REG_IRA_M 0x0A -#define LSM303_REG_IRB_M 0x0B -#define LSM303_REG_IRC_M 0x0C -#define LSM303_REG_TEMP_H_M 0x31 -#define LSM303_REG_TEMP_L_M 0x32 - - -#endif - diff --git a/STM32F3/libraries/ringbuffer/ringbuffer.cpp b/STM32F3/libraries/ringbuffer/ringbuffer.cpp deleted file mode 100644 index 852b2de7b..000000000 --- a/STM32F3/libraries/ringbuffer/ringbuffer.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include "ringbuffer.h" - -#ifdef WIN32 - -int tmcnt=10; - -unsigned long millis() { return tmcnt++; } -#define NULL 0 - -#else -#include -#endif - - -RingBuffer::RingBuffer(int _size, int *_values, unsigned long *_timeStamps) -{ - size = _size; // muss ZweierPotenz sein - values = _values; // Pointer auf Speicher f�r Werte - timeStamps = _timeStamps; // optional Pointer auf Speicher f�r ms timestamps - mask = 0; - int t = size/2; - while (t) - { - mask = (mask<<1)|1; - t = t/2; - } - reset(); -} - - -void RingBuffer::addValue(int value) -{ - values[wrIdx] = value; - - if (timeStamps != NULL) - timeStamps[wrIdx] = millis(); - - if (anz < size) - anz++; - - wrIdx++; - wrIdx &= mask; -} - - -void RingBuffer::reset() -{ - anz = 0; - wrIdx = 0; - rdIdx = 0; - - for (int i=0; i anz) - return 0; - - rdIdx = (wrIdx - distance) & mask; - - lastRead = 0; - - return 1; -} - - -/* - * Setzt rdIdx auf den ersten Wert, f�r den der zugeh�rige timeStamp mindestens zur�ckliegt, - * Es wird das Alter des betreffenden Wertes in ms zur�ckgegeben - * = wird zur�ckgegeben, wenn kein Wert mindestens so alt wie gefordert ist oder keine timestamps vorhanden sind - */ -int RingBuffer::setReadIdxDt(int ms) -{ - if (timeStamps == NULL) // keine timeStamps vorhanden - return 0; - - unsigned long aktTime = millis(); - unsigned long dt=0; - int count = 0; - rdIdx = (wrIdx - 1)&mask; // auf letzten eingetragenen Wert setzen - - lastRead = 0; - - while (count ms) - return dt; - count++; - - rdIdx = (rdIdx-1)&mask; - } - - return 0; -} - - -/* - * gibt Wert f�r rdIdx zur�ck und incrementiert rdIdx, solange rdIdx < (wrIdx-1) - * ACHTUNG: wird wrPtr erreicht, so wird immer wieder der letzte Wert zur�ckgegeben! - */ -int RingBuffer::getValue() -{ - int ret = values[rdIdx]; - - if (((rdIdx+1)&mask) == wrIdx) - lastRead = 1; - else - rdIdx = (rdIdx+1)&mask; - - return ret; -} - -/* - * gibt Wert f�r rdIdx zur�ck, tr�gt den zugeh�rigen timestamp - * in time ein und incrementiert rdIdx, solange rdIdx < wrIdx - * ACHTUNG: wird wrPtr erreicht, so wird immer wieder der letzte Wert zur�ckgegeben! - */ -int RingBuffer::getValue(unsigned long *time) -{ - int ret = values[rdIdx]; - if ((time != NULL) && (timeStamps!=NULL)) - *time = timeStamps[rdIdx]; - - if (((rdIdx+1)&mask) == wrIdx) - lastRead = 1; - else - rdIdx = (rdIdx+1)&mask; - - return ret; -} - - -/* - * gibt den Wert von rdIdx-1 zur�ck und decrementiert rdIdx wenn rdIdx-1 != wrIdx - * - */ -int RingBuffer::getPreviousValue() -{ - int idx = (rdIdx-1)&mask; - int ret = values[idx]; - if (idx != wrIdx) // rdIdx darf nicht kleiner als wrIdx werden - rdIdx = idx; - else - lastRead = 1; - return ret; -} - - -/* -`* decrementiert rdPtr und gibt den zugeh�rigen Wert zur�ck - */ -int RingBuffer::getPreviousValue(unsigned long *time) -{ - int idx = (rdIdx-1)&mask; - int ret = values[idx]; - rdIdx = (rdIdx-1)&mask; - if ((time != NULL) && (timeStamps!=NULL)) - *time = timeStamps[idx]; - if (idx != wrIdx) // rdIdx darf nicht kleiner als wrIdx werden - rdIdx = idx; - else - lastRead = 1; - return ret; -} - - -int RingBuffer::getPreviousValueDt(unsigned long *dt) -{ - int idx = (rdIdx-1)&mask; - int ret = values[idx]; - if ((dt != NULL) && (timeStamps!=NULL)) - { - unsigned long aktTime = millis(); - *dt = aktTime - timeStamps[idx]; - } - if (idx != wrIdx) // rdIdx darf nicht kleiner als wrIdx werden - rdIdx = idx; - else - lastRead = 1; - return ret; -} - - -/* - * gibt eins zur�ck, sobald der �lteste Wert mit einer PreviousValue-Funktion - * gelesen wurde - * wird durch jeden Aufruf einer SetReadIdx-Funktion zur�ckgesetzt - */ -int RingBuffer::lastValueRead() -{ - return lastRead; -} - - -/* - * gibt 1 zur�ck, wenn rdPtr != wrPtr - * gibt 0 zur�ck, wenn rdPtr == wrPtr - * - * --> funktioniert nur, wenn zuvor SetReadIdx() aufgerufen wurde - */ -int RingBuffer::valueAvailable() -{ - return !lastRead; -} - - -int RingBuffer::getValueAt(int idx) -{ - return values[(wrIdx+idx)&mask]; -} - - -int RingBuffer::getValueAt(int idx, unsigned long *time) -{ - int valueIdx = (wrIdx+idx)&mask; - if ((time != NULL) && (timeStamps!=NULL)) - *time = timeStamps[valueIdx]; - return values[valueIdx]; -} - - -int RingBuffer::getPreviousValueAt(int idx) -{ - return values[(wrIdx-1-idx)&mask]; -} - - -int RingBuffer::getPreviousValueAt(int idx, unsigned long *time) -{ - int valueIdx = (wrIdx-1-idx)&mask; - if ((time != NULL) && (timeStamps!=NULL)) - *time = timeStamps[valueIdx]; - return values[valueIdx]; -} - -//***************************************************************** - - -RingBufferAverage::RingBufferAverage(int _size, int *_values, unsigned long *_timeStamps, int _averageSize):RingBuffer(_size, _values, _timeStamps) -{ - averageSize = _averageSize; - averageSum = 0; -} - -void RingBufferAverage::addValue(int val) -{ - RingBuffer::addValue(val); - averageSum += val; - if (anz > averageSize) - averageSum -= getPreviousValueAt(averageSize); -} - - -void RingBufferAverage::reset() -{ - RingBuffer::reset(); - averageSum = 0; -} - - -void RingBufferAverage::setAverageLen(int len) -{ - averageSize = len; - reset(); -} - -int RingBufferAverage::getAverage() -{ - if (anz>averageSize) - return averageSum/averageSize; - return averageSum/anz; -} - - -int RingBufferAverage::getAverageSum() -{ - return averageSum; -} - - diff --git a/STM32F3/libraries/ringbuffer/ringbuffer.h b/STM32F3/libraries/ringbuffer/ringbuffer.h deleted file mode 100644 index 3fce4c200..000000000 --- a/STM32F3/libraries/ringbuffer/ringbuffer.h +++ /dev/null @@ -1,155 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#ifndef RINGBUFFER_H_ -#define RINGBUFFER_H_ - -class RingBuffer { -public: - int size; // muss ZweierPotenz sein - int *values; // Pointer auf Speicher f�r Werte - unsigned long *timeStamps; // optional Pointer auf Speicher f�r ms timestamps - int rdIdx; // Leseindex - Benutzung optional - int wrIdx; // Schreibindex - int mask; - - int anz; // Aktuelle Anzahl an Werten im Puffer - int lastRead; // wird auf eins gesetz, wenn letzter vorhandener Wert gelesen wurde - - - RingBuffer(int _size, int *_values, unsigned long *_timeStamps); - - /* - * f�gt einen Wert zum Ringpuffer hinzu und erzeugt einen zugeh�rigen Timestamp - * wenn timeStamps != NULL ist - */ - void addValue(int val); - - /* - * setzt rdIdx auf distance Werte vor den letzten Wert (wrPtr-1) - * Mit getValue k�nnen die letzten Werte bis zum letzten wert abgefragt werden - * - * gibt 1 zur�ck, wenn gen�gend Werte im Puffer sind - * gibt 0 zur�ck, wenn noch nicht gen�gend Werte im Puffer sind oder distance - * gr��er als die Pufferl�nge ist - */ - int setReadIdx(int distance); - - /* - * Setzt rdIdx auf den ersten Wert, f�r den der zugeh�rige timeStamp mindestens zur�ckliegt, - * Es wird das Alter des betreffenden Wertes in ms zur�ckgegeben - * = wird zur�ckgegeben, wenn kein Wert mindestens so alt wie gefordert ist oder keine timestamps vorhanden sind - */ - int setReadIdxDt(int ms); - - /* - * gibt Wert f�r rdIdx zur�ck und incrementiert rdIdx, solange rdIdx < wrIdx - * ACHTUNG: wird wrPtr erreicht, so wird immer wieder der letzte Wert zur�ckgegeben! - */ - int getValue(); - - /* - * gibt Wert f�r rdIdx zur�ck, tr�gt den zugeh�rigen timestamp - * in time ein und incrementiert rdIdx, solange rdIdx < wrIdx - * ACHTUNG: wird wrPtr erreicht, so wird immer wieder der letzte Wert zur�ckgegeben! - */ - int getValue(unsigned long *time); - - /* - * gibt 1 zur�ck, wenn rdPtr != wrPtr - * gibt 0 zur�ck, wenn rdPtr == wrPtr - * - * --> funktioniert nur, wenn zuvor SetReadIdx() aufgerufen wurde - */ - int valueAvailable(); - - /* - * Setzt den Ringbuffer zur�ck - */ - void reset(); - - /* - `* decrementiert rdPtr und gibt den zugeh�rigen Wert zur�ck - */ - int getPreviousValue(); - int getPreviousValue(unsigned long *time); - - /* - `* decrementiert rdPtr und gibt den zugeh�rigen Wert zur�ck - * schreibt Zeiitdifferenz zur aktuellen Zeit in dt - */ - int getPreviousValueDt(unsigned long *dt); - - - /* - * gibt eins zur�ck, sobald der �lteste Wert mit einer PreviousValue-Funktion - * gelesen wurde - * wird durch jeden Aufruf einer SetReadIdx-Funktion zur�ckgesetzt - */ - int lastValueRead(); - - /* - * Diese Funktion erlaubt den Zugriff auf den Ringbuffer wie auf ein Array. - * Der �lteste Wert hat immer den Index 0, der aktuellste Wert den Index size-1 - * Der rdIdx des Puffers wird nicht ver�ndert. - */ - int getValueAt(int idx); - int getValueAt(int idx, unsigned long *time); - - /* - * Diese Funktion erlaubt den Zugriff auf den Ringbuffer wie auf ein Array. - * Der neueste Wert hat immer den Index 0, der �lteste Wert den Index size-1 - * Der rdIdx des Puffers wird nicht ver�ndert. - */ - int getPreviousValueAt(int idx); - int getPreviousValueAt(int idx, unsigned long *time); - - -}; - - - -class RingBufferAverage : public RingBuffer -{ -public: - int averageSize; - int averageSum; - - RingBufferAverage(int _size, int *_values, unsigned long *_timeStamps, int _averageSize); - - void setAverageLen(int len); - - void addValue(int val); - void reset(); - - int getAverage(); - int getAverageSum(); - - -}; - - -#endif /* RINGBUFFER_H_ */ diff --git a/STM32F3/libraries/roboter/debug.cpp b/STM32F3/libraries/roboter/debug.cpp deleted file mode 100644 index fa0a3e768..000000000 --- a/STM32F3/libraries/roboter/debug.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include -#include "debug.h" - -#define DEBUG - -#ifndef DEBUGPORTID -#define DEBUGPORTID 2 -// TX-PIN ist PA2 -#endif - -#ifndef DEBUGPORT -#if DEBUGPORTID == 0 - #define DEBUGPORT SerialUSB -#endif -#if DEBUGPORTID == 1 - #define DEBUGPORT Serial1 -#endif -#if DEBUGPORTID == 2 - #define DEBUGPORT Serial2 -#endif -#if DEBUGPORTID == 3 - #define DEBUGPORT Serial3 -#endif -#endif - - -void debugInit() -{ -#ifdef DEBUG -#if (DEBUGPORTID != 0) - DEBUGPORT.begin(57600); -#endif - DEBUGPORT.println("Debug Init"); -#endif -} - - -static int printTimeStamp = 0; - -void debugSetTimeStamp(int OnOff) { - printTimeStamp = OnOff; -} - -static inline void addTimeStamp() { - if (printTimeStamp) { - DEBUGPORT.print(millis()); - DEBUGPORT.print(" "); - } -} - -void debugPrint(const char *s) -{ -#ifdef DEBUG - addTimeStamp(); - DEBUGPORT.println(s); -#endif -} - -void PrintNumber(const char *name, int num) -{ -#ifdef DEBUG - addTimeStamp(); - DEBUGPORT.print(name); - DEBUGPORT.print(" "); - DEBUGPORT.println(num); -#endif -} - -void PrintNumber(const char *name, byte num) -{ -#ifdef DEBUG - addTimeStamp(); - DEBUGPORT.print(name); - DEBUGPORT.print(" "); - DEBUGPORT.println(num); -#endif -} - -void PrintNumber(const char *name, float num) -{ -#ifdef DEBUG - addTimeStamp(); - DEBUGPORT.print(name); - DEBUGPORT.print(" "); - DEBUGPORT.println(num); -#endif -} - - - -void Print2Number(const char *name, int num1, int num2) -{ -#ifdef DEBUG - addTimeStamp(); - DEBUGPORT.print(name); - DEBUGPORT.print(" "); - DEBUGPORT.print(num1); - DEBUGPORT.print("\t"); - DEBUGPORT.println(num2); -#endif -} - -void Print2Number(const char *name, byte num1, byte num2) -{ -#ifdef DEBUG - addTimeStamp(); - DEBUGPORT.print(name); - DEBUGPORT.print(" "); - DEBUGPORT.print(num1); - DEBUGPORT.print("\t"); - DEBUGPORT.println(num2); -#endif -} - -void Print2Number(const char *name, float num1, float num2) -{ -#ifdef DEBUG - addTimeStamp(); - DEBUGPORT.print(name); - DEBUGPORT.print(" "); - DEBUGPORT.print(num1); - DEBUGPORT.print("\t"); - DEBUGPORT.println(num2); -#endif -} - -void PrintArray(const char *name, int len, int *arr) -{ -#ifdef DEBUG - int i; - addTimeStamp(); - DEBUGPORT.print(name); - for (i=0; i -#include -#include -#include "eeprom.h" -#include "debug.h" - - -/* - Source Code fuer 24C128 EEPROM (16Kbyte) -* - __ __ - A0 -| |- VCC - A1 -| |- WP --> unconnected low: write enabled - A2 -| |- SCL - VSS -|_____|- SDA - - -*/ - -#define EEPROM_I2C_BASE_ADDR (0xA0>>1) -#define EEPROM_I2C_ADDR(mem_addr) EEPROM_I2C_BASE_ADDR -#define EEPROM_I2C_CHANNEL I2C1 - -#define EEPROM_MAX_BUF 3 - -static uint8 msg_wr_data[EEPROM_MAX_BUF]; -static i2c_msg msg[2]; -static uint8 msg_rd_data[EEPROM_MAX_BUF]; - - -static void writeDataByte(int device_address, byte memory_address, byte data) -// write one byte of data 'data' to eeprom memory address 'memory_address' to chip with I2C address 'device_address' -{ -/* Arduino Code - Wire.beginTransmission(device_address); // device address - Wire.write(memory_address ); // memory address - Wire.write(data); // data to send - Wire.endTransmission(); // end - delay(10); -*/ - msg[0].addr = device_address; - msg[0].flags = 0; // write, 7 bit address - msg[0].xferred = 0; - msg[0].length = 3; - msg[0].data = msg_wr_data; - - msg_wr_data[0] = (memory_address>>8)&0xFF; - msg_wr_data[1] = memory_address&0xFF; - msg_wr_data[2] = data; - - i2c_master_xfer(EEPROM_I2C_CHANNEL, msg, 1, 10); - - delay(10); -} - - -static byte readDataByte(int device_address, byte memory_address) -// reads one byte of data from memory location 'memory_address' in chip at I2C address 'device_address' -{ - -/* Arduino Code - byte result; // return value - Wire.beginTransmission(device_address); // device address - Wire.write(memory_address); // memory address - Wire.endTransmission(); // end - Wire.requestFrom(device_address,1); // get one byte of data from device - if (Wire.available()) - result = Wire.read(); - return result; // return the read data byte - delay(10); -*/ - msg[0].addr = device_address; - msg[0].flags = 0; // write, 7 bit address - msg[0].xferred = 0; - msg[0].length = 2; - msg[0].data = msg_wr_data; - - msg_wr_data[0] = (memory_address>>8)&0xFF; - msg_wr_data[1] = memory_address&0xFF; - - msg[1].addr = device_address; - msg[1].flags = I2C_MSG_READ; - msg[1].xferred = 0; - msg[1].length = 1; - msg[1].data = msg_rd_data; - - i2c_master_xfer(EEPROM_I2C_CHANNEL, msg, 2, 10); - return msg_rd_data[0]; -} - -//--------------------------------------------------------------------------------- -int eepromWriteBytes(int addr, int len, unsigned char *pData) -{ - for (int i = 0; i -#include "functiontimer.h" -#include "debug.h" - - -//#define TMR_DEBUG - -typedef void (*tmrFuncPtr)(int arg); - - -typedef struct timerDaten { - struct timerDaten *pNext; - struct timerDaten *pPrev; - int time; - int state; - int arg; - int id; - tmrFuncPtr handler; -}TimerData_t; - - -TimerData_t timerArray[TIMER_ANZAHL]; -TimerData_t *pNextTimer = NULL; - - - -#define TIMEOUT_RATE 5000 // in microseconds - -HardwareTimer timer(2); - - -static void timeoutHandler() { - if (pNextTimer) { - pNextTimer->time -= 5; - if (pNextTimer->time <= 0) { -#ifdef TMR_DEBUG - PrintNumber("to", pNextTimer->id); -#endif - TimerData_t *p = pNextTimer; - pNextTimer = pNextTimer->pNext; - if (pNextTimer) - pNextTimer->pPrev = NULL; - p->state = 0; - //p->pNext = NULL; - //p->pPrev = NULL; - p->handler(p->arg); - } - } -} - -static bool timerInitialized = false; - -void timerInit() { - if (timerInitialized == false) { - for (int i=0; i= TIMER_ANZAHL) - return; - if (timerArray[id].state) // is already running? - return; - - TimerData_t *pNew = timerArray + id; - pNew->time = ms+5; - pNew->state = 1; - pNew->handler = handler; - pNew->pNext = NULL; - pNew->pPrev = NULL; - pNew->arg = arg; - if (pNextTimer == NULL) { - pNextTimer = pNew; -#ifdef TMR_DEBUG - PrintNumber("st", id); -#endif - } - else { -#ifdef TMR_DEBUG - Print2Number("sta", id, ms); -#endif - noInterrupts(); - TimerData_t *p = pNextTimer; - TimerData_t *last = NULL; - while (p) { - if (pNew->time < p->time) // vorher einhaengen - break; - else - pNew->time -= p->time; - last = p; - p = p->pNext; - } - - if (p==NULL) { - // hinter Last mit Restzeit einh�ngen - last->pNext = pNew; - pNew->pPrev = last; -#ifdef TMR_DEBUG - debugPrint("at end"); -#endif - } - else { // vor p einh�ngen und p->time um pNew->time verkleinern - p->time -= pNew->time; - pNew->pNext = p; - - if (p==pNextTimer) { - pNextTimer = pNew; - p->pPrev = pNew; -#ifdef TMR_DEBUG - PrintNumber("at begin", p->id); -#endif - } - else { - pNew->pPrev = p->pPrev; - p->pPrev = pNew; - if (pNew->pPrev) - pNew->pPrev->pNext = pNew; -#ifdef TMR_DEBUG - Print2Number("between", pNew->pPrev->id, pNew->pNext->id); -#endif - } - } - interrupts(); - } -#ifdef TMR_DEBUG - PrintTimerList(); -#endif -} - - -void timerStop(int id) { - if (id < 0) - return; - if (id>= TIMER_ANZAHL) - return; - if (timerArray[id].state==0) // is timer running? - return; - - TimerData_t *pTimer = timerArray + id; - noInterrupts(); - if (pTimer->pNext == NULL) { - // ist letzter in der queue - if (pTimer->pPrev == NULL) { - // ist einziger Timer - pTimer->state = 0; - pNextTimer = NULL; - } - else { - pTimer->pPrev->pNext = NULL; - pTimer->pPrev = NULL; - pTimer->state = 0; - } - } - else { - // Restzeit des zu l�schenden Timers auf den n�chsten in der Queue addieren - pTimer->pNext->time += pTimer->time; - if (pTimer == pNextTimer) {// erster Timer in der queue - pNextTimer = pTimer->pNext; - pTimer->pNext->pPrev = NULL; - pTimer->pNext = NULL; - } - else { - TimerData_t *pPrev = pTimer->pPrev; - pPrev->pNext = pTimer->pNext; - pTimer->pNext->pPrev = pPrev; - pTimer->pNext = NULL; - pTimer->pPrev = NULL; - } - } - interrupts(); - -} - - -void PrintTimerList() { - TimerData_t *p = pNextTimer; - - while (p) { - Print2Number("tmr",p->id, p->time); - if (p->pNext) - PrintNumber(" nxt", p->pNext->id); - if (p->pPrev) - PrintNumber(" prv", p->pPrev->id); - p = p->pNext; - } -} diff --git a/STM32F3/libraries/roboter/functiontimer.h b/STM32F3/libraries/roboter/functiontimer.h deleted file mode 100644 index 1a31f886c..000000000 --- a/STM32F3/libraries/roboter/functiontimer.h +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - /* - * Das Timer-Modul stellt Funktionen bereit, mit denen andere Funktionen - * sp�ter aufgerufen werden k�nnen. Diese Funktionen sollten eine - * kurze Laufzeit haben, da sie im Interrupt aufgerufen werden. - * - * - Die Timer arbeiten mit einer Aufl�sung von 5 ms. - * - Es k�nnen maximal 10 Timer gleichzeitig aktiv sein. - * - Stoppen eines Timers ist m�glich - * - */ - -#ifndef FUNCTION_TIMER_H_ -#define FUNCTION_TIMER_H_ - -#define TIMER_ANZAHL 10 - -typedef void (*tmrFuncPtr)(int arg); - -extern void timerInit(); -extern void timerStart(int id, int ms, tmrFuncPtr handler, int arg); -extern void timerStop(int id); - - - - -#endif /* TIMER_H_ */ diff --git a/STM32F3/libraries/roboter/motor.cpp b/STM32F3/libraries/roboter/motor.cpp deleted file mode 100644 index 57b6171c5..000000000 --- a/STM32F3/libraries/roboter/motor.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include -#include "motor.h" -#include "../gyro/gyro.h" -#include "debug.h" - - -#define TB6612 - -#define MOTOR_ANZ 3 - - -typedef struct { - int dir; - int pwm; - int sensor; - int led; -} MotorPins_t; - -static MotorPins_t mpins[MOTOR_ANZ]; - -#define IDX_A 0 -#define IDX_B 1 -#define IDX_C 2 - -// Umwandlung MotorIds to Index, wenn nur ein Motor addressiert ist -#define MIDX(id) ((id&OUT_A)?IDX_A:(id&OUT_B)?IDX_B:IDX_C) - - -static volatile int RadCount0; -void CountRad0() -{ - RadCount0++; -} - -static volatile int RadCount1; -void CountRad1() -{ - RadCount1++; -} - -static volatile int RadCount2; -void CountRad2() -{ - RadCount2++; -} - - -void InitMotor(int id, int PinDir, int PinPWM, int PinSensor, int PinLED) -{ - MotorPins_t *p = mpins+MIDX(id); - p->dir = PinDir; - p->pwm = PinPWM; - p->sensor = PinSensor; - p->led = PinLED; - - pinMode (p->pwm, PWM); - pinMode (p->dir, OUTPUT); - analogWrite(p->pwm, 0); - - if (p->sensor != -1) - { - if (p->led != -1) - pinMode(p->led, OUTPUT); - - pinMode(p->sensor, INPUT); - } -} - - -static inline void RadSensorAn(int motor) -{ - MotorPins_t *p = mpins; - - for (int idx=0; idxled != -1) - digitalWrite(p->led, HIGH); - if (p->sensor != -1) { - if (idx == 0) - attachInterrupt(p->sensor, CountRad0, CHANGE); - else if (idx == 1) - attachInterrupt(p->sensor, CountRad1, CHANGE); - else - attachInterrupt(p->sensor, CountRad2, CHANGE); - } - } - p++; - } - delayMicroseconds(50); // Damit ggf. ein Interrupt beim Einschalten ausgef�hrt wird -} - - -static inline void RadSensoren(int motor) -{ - MotorPins_t *p = mpins; - - for (int idx=0; idxled != -1) - digitalWrite(p->led, LOW); - if (p->sensor != -1) { - detachInterrupt(p->sensor); - } - } - p++; - } -} - - -void OnFwd(int Motor, int Geschwindigkeit) -{ - if(Geschwindigkeit>0) - Geschwindigkeit+=13; - else if(Geschwindigkeit<0) - Geschwindigkeit-=13; - - MotorPins_t *p = mpins; - Geschwindigkeit = constrain(Geschwindigkeit,-100, 100); // Geschwindigkeit auf Bereich -100 ... +100 begrenzen - Geschwindigkeit = (65535*Geschwindigkeit)/100; - PrintNumber("v ",Geschwindigkeit ); - - for (int i=0; i0) - { - digitalWrite(p->dir, HIGH); - v = Geschwindigkeit; - } - else - { - digitalWrite(p->dir, LOW); - v = -Geschwindigkeit; - } - analogWrite(p->pwm, v); - #endif - } - p++; - } -} - - -void OnRev(int m, int v) -{ - OnFwd(m, -v); -} - -void Off(int Motor) -{ - MotorPins_t *p = mpins; - for (int i=0; ipwm, 0); -#endif - } - p++; - } -} - - - -#if 0 - -// gyro-Funktionen nicht in diesem Modul - -void DreheRechts(int v, int Winkel) -{ - gyroResetWinkel(); - OnFwd(OUT_A, v); - OnFwd(OUT_B, -v); - while (winkelz>=-Winkel) - gyroUpdate(); - Off (OUT_AB); - -} - - -void DreheLinks(int v, int Winkel) -{ - gyroResetWinkel(); - OnFwd(OUT_A, -v); - OnFwd(OUT_B, v); - while (winkelz<=Winkel) - gyroUpdate(); - Off (OUT_AB); - -} - - -void FahreVor(int v, int Strecke) -{ - RadSensorenAn(); - RadCountR = 0; // 0 Setzen erst NACH Einschalten des Sensors, eventuell kommt schon ein Interrupt -// RadCountL = 0; - OnFwd(OUT_AB, v); - while (Strecke>RadCountR) - { -// PrintNumber("RC", RadCountR); -// delay (1); - } - Off(OUT_AB); - RadSensorenAus(); -} - -#endif - - -#if 0 -void TestRadSensoren() -{ - RadSensorenAn(); - RadCountR = 0; - RadCountL = 0; - OnFwd(OUT_AB,10); - while(1) - { - lcd.clear(); - lcd.setCursor(0,0); - lcd.print(RadCountL); - lcd.setCursor(4,0); - lcd.print(RadCountR); - delay(300); - } -} - -#endif diff --git a/STM32F3/libraries/roboter/motor.h b/STM32F3/libraries/roboter/motor.h deleted file mode 100644 index c63470e05..000000000 --- a/STM32F3/libraries/roboter/motor.h +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - /* - * Das Modul Motor stellt Funktionen und Makros zur Steuerung der - * Fahrmotoren zur verf�gung sowie Funktionen zur Steuerung und - * Abfrage der Wegsensoren. - */ - -#ifndef MOTOR_H_ -#define MOTOR_H_ - -#define OUT_A 1 -#define OUT_B 2 -#define OUT_C 4 -#define OUT_AB (OUT_A|OUT_B) -#define OUT_BC (OUT_B|OUT_C) -#define OUT_AC (OUT_A|OUT_C) -#define OUT_ABC (OUT_A|OUT_B|OUT_C) - - -extern void InitMotor(int id, int PinDir, int PinPWM, int PinSensor, int PinLED); - -extern void OnFwd(int Motor, int Geschwindigkeit); -extern void OnRev(int Motor, int Geschwindigkeit); -extern void Off (int Motor); - -#if 0 -extern void DreheRechts(int v, int Winkel); -extern void DreheLinks(int v, int Winkel); - -extern void FahreVor(int v, int Strecke); -#endif - - -#endif /* MOTOR_H_ */ diff --git a/STM32F3/libraries/roboter/sound.cpp b/STM32F3/libraries/roboter/sound.cpp deleted file mode 100644 index 09ca89489..000000000 --- a/STM32F3/libraries/roboter/sound.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include -#include "sound.h" - - -/* todo */ \ No newline at end of file diff --git a/STM32F3/libraries/roboter/sound.h b/STM32F3/libraries/roboter/sound.h deleted file mode 100644 index 54c572391..000000000 --- a/STM32F3/libraries/roboter/sound.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#ifndef SOUND_H_ -#define SOUND_H_ - - - - -#endif /* SOUND_H_ */ diff --git a/STM32F3/libraries/roboter/ultraschall.cpp b/STM32F3/libraries/roboter/ultraschall.cpp deleted file mode 100644 index 871c6acdb..000000000 --- a/STM32F3/libraries/roboter/ultraschall.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include -#include "ultraschall.h" -#include "debug.h" - -/* - * F�r jeden Ultraschallsensor gibt es eine Struktur USSensor, die im Array USSensoren - * angelegt wird. - * F�r jeden Sensor muss einmal die Funktion addUSSensor() mit den richtigen Anschluss - * Pins aufgerufen werden. - * - * Zum Messen muss ein Sensor aktiviert werden. Es k�nnen alle Sensoren aktiv sein. - * Sie werden dann abwechselnd f�r Messungen getriggert. Nicht mehr ben�tigte Sensoren - * sollten deaktiviert werden. - * Im aktiven Zustand wird durch die Funktion UltraschallMessen() die Messung - * jeweils eines aktiven Sensors gestartet, wenn keine Messung aktiv ist. - * UltraschallMessen() koordiniert nur die Messungen (es darf immer nur ein - * Ultraschallsensor aktiv sein) und wartet nicht, bis die Messung erfolgt ist. - * UltraschallMessen sollte alle 25ms oder k�rzer aufgerufen werden, - * wenn Ultraschallmesswerte ben�tigt werden. - * --> ggf. Aktivieren der n�chsten Messung im Interrupt? --> testen - * - * Das Messen selbst erfolgt asynchron zur Programmausf�hrung. Eine spezielle - * Messroutine wird aufgerufen, wenn der Echo-Pin des Sensors seinen Zustand �ndert. - * Diese Routine tr�gt die gemessene Entfernung und einen Zeitstempel in die Sensor- - * struktur ein und setzt ein Flag in der Struktur, dass ein neuer Messwert zur - * Verf�gung steht. - * - * Mit der Funktion UltraschallMessenFertig(id) kann abgefragt werden, ob ein neuer - * Messwert vorliegt. Dieser kann mit UltraschallMesswert(id) abgefragt werden. - * Mit UltraschallMesswertAlter(id) kann abgefragt werden, wie alt der ausgelesene - * Messwert ist. Alternativ zu den Funktionsaufrufen k�nnen die Werte auch direkt aus - * den Sensorstrukturen ausgelesen werden. - * - * Alternativ zum automatischen Messen im Hintergrund kann statt UltraschallMessen() - * die Funktion UltraschallMessenEinzel(id) aufgerufen werden. Diese Funktion blockiert - * solange bis ein Messwert vorliegt (max. 50ms falls kein Wert ermittelt werden kann) - * und gibt diesen zur�ck. Eine Aktivierung des Sensors ist nicht erforderlich. - * Eventuell laufende Messungen werden abgebrochen. Eine noch laufende Messung wird - * jedoch zu Ende gef�hrt. - * - * Zeit�berwachung: - * Es kann eine maximale Laufzeit f�r das zu erwartende Echo gesetzt werden (z.B. 30ms). - * F�r diese Laufzeit wird ein Timer mit eigenem Interrupt gestartet. - * Gestoppt wird der Timer, wenn die Echo-Interrupt-Funktion vor Ablauf des Timers ausgef�hrt wird - * (der Echo-Puls ist in diesem Fall innerhalb des zul�ssigen Zeitfensters gekommen. - * L�uft der Timer ab, ist die aktuelle Messung ung�ltig und es wird versucht eine neue Messung - * mit dem n�chsten Sensor zu starten. - * Eine Messung kann nur gestartet werden, wenn der Echo-Pin auf LOW ist. - * Gibt es keinen Sensor, der bei Startanforderung echo==LOW hat, so wird nichts unternommen und - * auf die n�chste fallende Flanke einer Echo-Leitung (Interrupt) gewartet. Die fallende Flanke startet - * dann eine neue Messung per Interrupt. - * Gibt es einen Sensor, der bereit f�r eine neue Messung ist, so wird bei diesem die Messung - * gestartet. - * Damit das funktioniert, muss f�r jeden Echo-Pin eine eigene Interrupt-Funktion attached werden. - * - * Wenn auf die Zeit�berwachung verzeichtet wird blockiert eine ung�ltige Messung weitere Messungen - * anderer Sensoren um die Zeit bis zum HIGH-LOW-�bergang des Echopins - * --> bei nur einem Sensor ist eine Zeit�berwachung nicht n�tig, da kein Neustart einer Messung - * stattfinden kann bevor der Echo-Pin wieder Low ist. - * - * HC-SR04: Wenn kein Echo kommt, wird das ECHO-Signal nach ca. 235ms (entspricht ca. 4m) wieder nach - * LOW gezogen. - * - * Um das Suchen nach einem messbereiten Sensor zu vereinfachen werden die aktiven Sensorstrukturen in einer - * doppelt verketteten Liste verwaltet. - * - * Der Aufruf von micros() im Interrupt funktioniert nicht sicher, deshalb muss die Timing-Information auf anderm Wege - * beschafft werden: - * Eigener Hardwaretimer f�r Ultraschallsensoren (ist auch schneller bei der Vewaltung) - * - */ - - -#define IDLE_CHECK_TMO 25 // ms - -// global state -#define US_GLOBAL_IDLE 0 -#define US_GLOBAL_MESSUNG_AKTIV 1 - -static int state = US_GLOBAL_IDLE; - -// Prototypen -static void TimerIntRangeTimeout(); -static void TimerIntWaitIdle(); -static inline void startMessung(); -static void USInt(); - -// globale Variablen -USSensor USSensoren[MAX_US_SENSOR]; - -// static Variablen -static USSensor *pAktiverSensor = NULL; -static int SensorAktivAnzahl=0; -static int MessPause = 0; - - -//-------------------------------------------------------------------------- -// Timer-Funktionen -//-------------------------------------------------------------------------- - -static HardwareTimer usTimer(15); -static int usTimerCount; // Beim Starten wird sofort ein Interrupt ausgel�st, - // der ausgeblendet werden muss - - -static void startUsTimer(int ms, voidFuncPtr handler) -{ - usTimer.pause(); - - // Set up period - usTimer.setPeriod(ms*1000); // in microseconds - - usTimerCount = 1; - - // Set up an interrupt on channel 1S - usTimer.setChannel1Mode(TIMER_OUTPUT_COMPARE); - usTimer.setCompare(TIMER_CH1, 1); // Interrupt 1 count after each update - usTimer.attachCompare1Interrupt(handler); - - // Refresh the timer's count, prescale, and overflow - usTimer.refresh(); - - // Start the timer counting - usTimer.resume(); -} - - -static void stopUsTimer() { - usTimer.pause(); -} - -//-------------------------------------------------------------------------- - - - -/** - * Startet die Messung beim n�chsten IDLE-Sensor. - * Wenn keine Messung aktiv ist (US_GLOBAL_IDLE) und kein Sensor gefunden wird, - * wird der IDLE-Wait-Timer gestartet - */ -static inline void startMessung() -{ - if (state != US_GLOBAL_IDLE) - return; // Es kann keine Messung gestartet werden - - int anz = SensorAktivAnzahl; - - while (anz) { - pAktiverSensor = pAktiverSensor->pNext; // erstmal auf den n�chsten Sensor stellen - if (pAktiverSensor->state==US_IDLE) - { - //PrintNumber(" nis", pAktiverSensor->id); - // nur wenn EchoPin Low ist, kann die n�chste Messung erfolgen - if (digitalRead(pAktiverSensor->echoPin) == LOW) { - state = US_GLOBAL_MESSUNG_AKTIV; // globalen Zustand setzen - pAktiverSensor->state = US_ACTIVE; - //PrintNumber("sel", pAktiverSensor->id); - digitalWrite(pAktiverSensor->triggerPin, HIGH); - delayMicroseconds(10); // FIXME: funktioniert das im Interrupt ??? - // sollte gehen, ist eine Assemblerschleife - // muss aber mal gemessen werden!! - digitalWrite(pAktiverSensor->triggerPin, LOW); - attachInterrupt(pAktiverSensor->echoPin, USInt, CHANGE); - return; - } - //else - //PrintNumber("ns2", pAktiverSensor->id); - } - //else - // PrintNumber("ns1", pAktiverSensor->id); - - anz--; - } - startUsTimer(IDLE_CHECK_TMO, TimerIntWaitIdle); -} - -// Interrupt-Routinen - -/** - * Interrupt-Routine f�r Echo-Pin - */ -static void USInt() -{ - int time = usTimer.getCount(); - int pin = digitalRead(pAktiverSensor->echoPin); - if (pin==HIGH) - { - if (pAktiverSensor->state == US_ACTIVE) { - startUsTimer(pAktiverSensor->maxTime, TimerIntRangeTimeout); - //PrintNumber(" eh",pSensor->id); - } - } - else - { - stopUsTimer(); - detachInterrupt(pAktiverSensor->echoPin); - pAktiverSensor->entfernung = time/pAktiverSensor->timerTicksPerCm; - //Print2Number("usi", pAktiverSensor->id, pAktiverSensor->entfernung); - pAktiverSensor->messZeit = millis(); - pAktiverSensor->lastValidRange = pAktiverSensor->entfernung; - pAktiverSensor->lastValidTime = pAktiverSensor->messZeit; - pAktiverSensor->neuerMesswert = 1; - pAktiverSensor->state = US_IDLE; - state = US_GLOBAL_IDLE; - if (pAktiverSensor->handler) - pAktiverSensor->handler(pAktiverSensor->id, pAktiverSensor->entfernung); - if (MessPause) - startUsTimer(MessPause, TimerIntWaitIdle); - else - startMessung(); - } -} - -static void TimerIntWaitIdle() { - if (usTimerCount) - usTimerCount--; - else { - //debugPrint("twi"); - stopUsTimer(); - startMessung(); - } -} - -static void TimerIntRangeTimeout() { - if (usTimerCount) - usTimerCount--; - else { - stopUsTimer(); - if (pAktiverSensor) { - detachInterrupt(pAktiverSensor->echoPin); - //debugPrint(" tmo"); - if (pAktiverSensor->state == US_ACTIVE) { - pAktiverSensor->state = US_IDLE; - state = US_GLOBAL_IDLE; // Es kann eine Messung mit einem anderen Sensor gestartet werden - pAktiverSensor->entfernung = ENTFERNUNG_INVALID; - pAktiverSensor->messZeit = millis(); - if (pAktiverSensor->handler) - pAktiverSensor->handler(pAktiverSensor->id, pAktiverSensor->entfernung); - startMessung(); - } - else - { - if (state == US_GLOBAL_IDLE) - startMessung(); - } - } - } -} - - -//----------------------------------------------------------------- -// extern aufrufbare Funktionen -//----------------------------------------------------------------- - -/** - * Definiert und initialisiert einen Ultraschallsensor - * maxRange in cm - */ -void addUSSensor(int id, int trigger, int echo, int maxRange) -{ - if ((id < 0) || (id >= MAX_US_SENSOR)) - return; - USSensor *pSensor = &USSensoren[id]; - pSensor->triggerPin = trigger; - pSensor->echoPin = echo; - pSensor->enabled = 0; - pSensor->state = US_IDLE; - pSensor->id = id; - pSensor->maxTime = (maxRange*US_ROUNDTRIP_CM)/1000; - - // Timer-Wertebereich f�r maxRange ermitteln - usTimer.setPeriod(pSensor->maxTime*1000); // in microseconds - pSensor->timerTicksPerCm = usTimer.getOverflow()/maxRange; - - // pins initialisieren - pinMode(trigger, OUTPUT); - pinMode(echo, INPUT); -} - -/** - * aktiviert einen Sensor zum Messen im Hintergrund - */ -void aktiviereUSSensor(int id) -{ - if (USSensoren[id].enabled) // ist bereits enabled - return; - - USSensoren[id].enabled = 1; - - if (pAktiverSensor == NULL) { // ist der erste Sensor - pAktiverSensor = USSensoren + id; - pAktiverSensor->pNext = pAktiverSensor; // zeigt auf sich selbst! - pAktiverSensor->pPrev = pAktiverSensor; - SensorAktivAnzahl = 1; - // �ber den Timer wird erreicht, dass die Messung gestartet wird. - startUsTimer(IDLE_CHECK_TMO, TimerIntWaitIdle); - } - else { - noInterrupts(); - USSensor *pSensor = USSensoren + id; - pSensor->state = US_IDLE; - - pSensor->pNext = pAktiverSensor->pNext; - pSensor->pPrev = pAktiverSensor; - pAktiverSensor->pNext->pPrev = pSensor; - pAktiverSensor->pNext = pSensor; - - SensorAktivAnzahl++; - interrupts(); - } -} - - -void UsAttachHandler(int id, usFuncPtr fkt){ - USSensoren[id].handler = fkt; -} - - -void UsSetMessPause(int ms) { - MessPause = ms; -} - - -/** - * deaktiviert einen Sensor - */ -void deaktiviereUSSensor(int id) -{ - /* - * Problem: - * f�r den aktuellen Sensor k�nnte aktuell eine Messung laufen! - */ - if (!USSensoren[id].enabled) - return; - - noInterrupts(); - USSensor *pSensor = USSensoren + id; - pSensor->enabled = 0; - pSensor->neuerMesswert = 0; - - if (SensorAktivAnzahl>1) { - pSensor->pPrev->pNext = pSensor->pNext; - pSensor->pNext->pPrev = pSensor->pPrev; - if (pAktiverSensor == pSensor) - pAktiverSensor = pSensor->pNext; - } - else - pAktiverSensor = NULL; - - SensorAktivAnzahl--; - - if (pSensor->state == US_ACTIVE) { - detachInterrupt(pSensor->echoPin); - pSensor->state = US_IDLE; - state = US_GLOBAL_IDLE; - - if (SensorAktivAnzahl) - // �ber den Timer wird erreicht, dass eine neue Messung gestartet wird. - startUsTimer(IDLE_CHECK_TMO, TimerIntWaitIdle); - } - interrupts(); -} - -/** - * gibt 1 zur�ck, wenn ein neuer Messwert vorliegt. - * Es wird nur einmal eine 1 zur�ckgegeben, das Flag wird beim Auslesen zur�ckgesetzt - */ -int UltraschallMessenFertig(int id) -{ - if (USSensoren[id].neuerMesswert) - { - USSensoren[id].neuerMesswert = 0; - return 1; - } - return 0; -} - - -/** - * gibt aktuellstes Messergebnis zur�ck - */ -int16 UsAktuellerMesswert(int id) -{ - return USSensoren[id].entfernung; -} - -/** - * Gibt das Alter der aktuellsten Messung in ms zur�ck - */ -int UsAktuellerMesswertAlter(int id) -{ - return (millis() - USSensoren[id].messZeit); -} - -/** - * gibt den letzten gueltigen Wert zur�ck - */ -int16 UsLetzterGueltigerMesswert(int id) -{ - return USSensoren[id].lastValidRange; -} - -/** - * Gibt das Alter der letzten Messung in ms zur�ck - */ -int UsLetzterGueltigerMesswertAlter(int id) -{ - return (millis() - USSensoren[id].lastValidTime); -} - - -/** - * ----------------------------------------------------------- - * blockierende Messung - * ----------------------------------------------------------- - */ -int16 UltraschallMessenEinzel(int id) -{ - uint32 t1; - uint32 t2=0; - if ((id<0) || (id >= MAX_US_SENSOR)) - return ENTFERNUNG_INVALID; - - // alle Sensoren deaktivieren - for (int i=0; iechoPin) == HIGH ) - { - t2 = micros(); - if (t2-t1 > 100000) // Wenn 100ms lang kein LOW am Echo-Pin Fehler zur�ckgeben - return ERROR_SENSOR_BUSY; - } - - // trigger-Impuls generieren - digitalWrite(pSensor->triggerPin, HIGH); - delayMicroseconds(10); - digitalWrite(pSensor->triggerPin, LOW); - - // auf HIGH am Echo-Pin warten - t1 = micros(); - - while (digitalRead(pSensor->echoPin) == LOW ) - { - t2 = micros(); - if (t2-t1 > 1000) - return ERROR_NO_SENSOR; // kein LOW-HIGH-�bergang innerhalb 1ms detektiert -> Fehler - } - t1 = micros(); - - // auf LOW am Echo-Pin warten - while (digitalRead(pSensor->echoPin) == HIGH ) - { - t2 = micros(); - if ((t2-t1) > (uint32)(pSensor->maxTime*1000)) - return ENTFERNUNG_INVALID; // Messentfernung gr��er maxRange - } - - return (t2-t1)/US_ROUNDTRIP_CM; -} - - -//------------------------------------------------------------------------ -void PrintUsSensorList() { - USSensor *pSensor = pAktiverSensor; - - for (int i = 0; i < SensorAktivAnzahl; i++){ - if (pSensor == NULL) - return; - PrintNumber("Sensor", pSensor->id); - if (pSensor->pNext == NULL) - debugPrint(" next NULL"); - else - PrintNumber(" next", pSensor->pNext->id); - if (pSensor->pPrev == NULL) - debugPrint(" prev NULL"); - else - PrintNumber(" prev", pSensor->pPrev->id); - pSensor = pSensor->pNext; - } -} - -#if 0 -// Timer Test-Funktionen - -static void testHandler() { - debugPrint("usi"); - - if (usTimerCount) - usTimerCount--; - else { - stopUsTimer(); - debugPrint("---"); - startUsTimer(300, testHandler); - } -} - -void TestUsTimer() { - startUsTimer(100, testHandler); -} - -int GetUsTimerCount() { - return usTimer.getCount(); -} -#endif - diff --git a/STM32F3/libraries/roboter/ultraschall.h b/STM32F3/libraries/roboter/ultraschall.h deleted file mode 100644 index a03af40ab..000000000 --- a/STM32F3/libraries/roboter/ultraschall.h +++ /dev/null @@ -1,156 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2015 Frank-Michael Krause - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#ifndef ULTRASCHALL_H_ -#define ULTRASCHALL_H_ - -#define US_IDLE 0 -#define US_ACTIVE 1 - - -#define US_ROUNDTRIP_CM 57 // Microseconds (uS) it takes sound to travel round-trip 1cm (2cm total), uses integer to save compiled code space. - -typedef void (*usFuncPtr)(int id, int entfernung); - -typedef struct USSensor_s { - int8 id; - int triggerPin; - int echoPin; - int8 enabled; - int8 state; // IDLE, ACTIVE - int8 neuerMesswert; - int16 maxTime; //Zeit f�r maximal zu messende Entfernung in ms - int timerTicksPerCm; - int16 entfernung; // in cm - uint32 messZeit; // Systemzeit der Messung in ms - int16 lastValidRange; - uint32 lastValidTime; -// uint32 startZeit; // Startzeit der aktuellen Messung - usFuncPtr handler; - struct USSensor_s *pNext; - struct USSensor_s *pPrev; -} USSensor; - -#define MAX_US_SENSOR 4 - -#define ENTFERNUNG_INVALID -1 -#define ERROR_NO_SENSOR -2 -#define ERROR_SENSOR_BUSY -3 - -extern USSensor USSensoren[MAX_US_SENSOR]; - - -/***************************************************** - * Funktionen zur Initialisierung - ****************************************************/ - -/** - * id: Index zwischen 0 und MAX_US_SENSOR-1 - * trigger: IO-Pin, der mit dem Trigger-Eingang des Sensors verbunden ist - * echo: IO-Pin, der mit dem Echo-Ausgang des Sensors verbunden ist. - * !!! der Echo-IO-Pin muss 5V tolerant sein oder mit einem - * Spannungsteiler versehen werden. - * maxRange: Maximal zu messende Entfernung in cm; optional - */ -extern void addUSSensor(int id, int trigger, int echo, int maxRange=150); - -/** - * setzt die Zeit der Pause, die nach erfolgreicher Messung vor der n�chsten - * Messung eingef�gt wird. - * Default ist 0, d.h. keine Pause - */ -extern void UsSetMessPause(int ms); - - - -/***************************************************** - * Funktionen f�r blockierende Messung - * Bei Aufruf der blockierenden Einzelmessfunktion werden - * alle �ber Interrupt akktivierten Sensoren deaktiviert - * - * gibt Entfernung in cm zur�ck - * bzw. die Fehlerwerte - * ENTFERNUNG_INVALID -1 - * ERROR_NO_SENSOR -2 - * ERROR_SENSOR_BUSY -3 - *****************************************************/ -extern int16 UltraschallMessenEinzel(int id); - - - - -/***************************************************** - * Funktionen f�r nicht blockierende, interrupt-basierte Messung - * - * Durch Zustandsvariablen gesteuert werden auf allen aktiven Sensoren - * immer wieder abwechselnd Messungen angestossen. - * Die Messergebnisse werden in Variablen der Sensorstruktur abgelegt - * und k�nnen �ber Funktionen aus dem Hauptptogramm abgefragt werden. - * - * Es kann pro Sensor eine Handler-Funktion registriert werden, - * die aufgerufen wird, sobald ein neuer Messwert vorliegt. - *****************************************************/ - - -extern void aktiviereUSSensor(int id); -extern void deaktiviereUSSensor(int id); - -extern void UsAttachHandler(int id, usFuncPtr fkt); - - -/** - * gibt das Ergebnis der letzten Messung zur�ck. - * Kann ENTFERNUNG_INVALID sein. - */ -extern int16 UsAktuellerMesswert(int id); - -/** - * gibt das Alter des letzen Messergebnisses in ms an. - */ -extern int UsAktuellerMesswertAlter(int id); - -/** - * gibt den letzten Messwert des Sensors zur�ck, der nicht - * ENTFERNUNG_INVALID ist. - */ -extern int16 UsLetzterGueltigerMesswert(int id); - - -/** - * gibt das Alter des letzen g�ltigen Messergebnisses in ms an. - */ -extern int UsLetzterGueltigerMesswertAlter(int id); - - - -/***************************************************** - * Debug-Funktionen - ****************************************************/ - -extern void PrintUsSensorList(); - - -#endif /* ULTRASCHALL_H_ */ diff --git a/STM32F3/platform.txt b/STM32F3/platform.txt deleted file mode 100644 index 94f787c81..000000000 --- a/STM32F3/platform.txt +++ /dev/null @@ -1,144 +0,0 @@ -# -# -# For more info: -# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification - -name=STM32F3 boards -version=0.1.0 - -# compiler variables -# ---------------------- -#build.gcc_ver=gcc-arm-none-eabi-4.8.3-2014q1 - -compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/ -compiler.c.cmd=arm-none-eabi-gcc -compiler.c.flags=-c -g {build.flags.optimize} -w -MMD -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -DBOARD_{build.variant} -D{build.vect} -DERROR_LED_PORT={build.error_led_port} -DERROR_LED_PIN={build.error_led_pin} -compiler.c.elf.cmd=arm-none-eabi-g++ -compiler.c.elf.flags={build.flags.optimize} -Wl,--gc-sections {build.flags.ldspecs} -compiler.S.cmd=arm-none-eabi-gcc -compiler.S.flags=-c -g -x assembler-with-cpp -MMD -compiler.cpp.cmd=arm-none-eabi-g++ -compiler.cpp.flags=-c -g {build.flags.optimize} -w -MMD -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -DBOARD_{build.variant} -D{build.vect} -DERROR_LED_PORT={build.error_led_port} -DERROR_LED_PIN={build.error_led_pin} -compiler.ar.cmd=arm-none-eabi-ar -compiler.ar.flags=rcs -compiler.objcopy.cmd=arm-none-eabi-objcopy -compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 -compiler.elf2hex.flags=-O binary -compiler.elf2hex.cmd=arm-none-eabi-objcopy -compiler.ldflags={build.flags.ldspecs} -compiler.size.cmd=arm-none-eabi-size -compiler.define=-DARDUINO= - -# this can be overriden in boards.txt -build.cpu_flags= -build.hs_flag= -build.common_flags= -build.extra_flags= {build.cpu_flags} {build.hs_flag} {build.common_flags} - -# These can be overridden in platform.local.txt -compiler.c.extra_flags= -compiler.c.elf.extra_flags="-L{build.variant.path}/ld" -compiler.cpp.extra_flags= -compiler.S.extra_flags= -compiler.ar.extra_flags= -compiler.elf2hex.extra_flags= - - - -compiler.libs.c.flags="-I{build.core.path}/libmaple" "-I{build.core.path}/libmaple/include" "-I{build.core.path}/libmaple/stm32f3/include" "-I{build.core.path}/libmaple/usb" "-I{build.core.path}/libmaple/usb/usb_lib" "-I{build.core.path}/wirish/include" "-I{build.core.path}/wirish" -#compiler.libs.c.flags="-I{build.system.path}/libmaple" "-I{build.system.path}/libmaple/include" "-I{build.system.path}/libmaple/stm32f1/include" "-I{build.system.path}/libmaple/usb/stm32f1" "-I{build.system.path}/libmaple/usb/usb_lib" "-I{build.system.path}/wirish/include" - - -#compiler.libs.c.flags="-I{build.core.path}/libmaple" -I{build.core.path}/libmaple/usbF4 -I{build.core.path}/libmaple/usbF4/STM32_USB_Device_Library/Core/inc -I{build.core.path}/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc -I{build.core.path}/libmaple/usbF4/STM32_USB_OTG_Driver/inc -I{build.core.path}/libmaple/usbF4/VCP - - - -# USB Flags -# --------- -## build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' - -# Default usb manufacturer will be replaced at compile time using -# numeric vendor ID if available or by board's specific value. -## build.usb_manufacturer="Unknown" - - -# build patterns -# --------------------- - -## Compile c files -recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}" - -## Compile c++ files -recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.cpu_flags} {build.hs_flag} {build.common_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}" - -## Compile S files -recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.cpu_flags} {build.hs_flag} {build.common_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}" -#recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" "{source_file}" -o "{object_file}" - -## Create archives -recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" - -## Combine gc-sections, archives, and objects -##recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group "{build.path}/syscalls_sam3.c.o" {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group -#-Wl,--entry=__start__ -#recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} -Wl,--whole-archive "{build.path}/{archive_file}" -Wl,--no-whole-archive -Wl,--end-group - -## Create eeprom -recipe.objcopy.eep.pattern= - -## Create hex -recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" - -## Compute size -recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" -#recipe.size.regex=\.text\s+([0-9]+).* -recipe.size.regex=^(?:\.text|\.rodata|\.ARM.exidx)\s+([0-9]+).* -recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* - -# Uploader tools -# ------------------- - -# Upload using Maple bootloader over DFU -tools.maple_upload.cmd=maple_upload -tools.maple_upload.cmd.windows=maple_upload.bat -#tools.maple_upload.cmd.linux= -tools.maple_upload.path={runtime.hardware.path}/tools/win -tools.maple_upload.path.macosx={runtime.hardware.path}/tools/macosx - -tools.maple_upload.upload.params.verbose=-d -tools.maple_upload.upload.params.quiet= -tools.maple_upload.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}.bin" - -# Generic STM32 upload via serial to Serial Port 1 (pins PA9 and PA10) - note. Boot0 line needs to high on board reset to enable upload via serial -# at the end of the upload the program is automatically run, without the board being reset - -tools.serial_upload.cmd=serial_upload -tools.serial_upload.cmd.windows=serial_upload.bat -#tools.serial_upload.cmd.linux= -tools.serial_upload.path={runtime.hardware.path}/tools/win - -tools.serial_upload.upload.params.verbose=-d -tools.serial_upload.upload.params.quiet= -tools.serial_upload.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}.bin" - -# -tools.upload_router.cmd=upload_router -tools.upload_router.cmd.windows=upload_router.bat -#tools.upload_router.cmd.linux= -tools.upload_router.path={runtime.hardware.path}/tools/win - -tools.upload_router.upload.params.verbose=-d -tools.upload_router.upload.params.quiet= -tools.upload_router.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}" {upload.protocol} {build.debuggingMode} "{runtime.ide.path}/hardware/tools/{build.gcc_ver}/bin/" - -# STLINK/V2 - -tools.stlink.cmd=stlink -tools.stlink.cmd.windows=stlink_upload.bat -#tools.stlink.cmd.linux= -tools.stlink.path={runtime.hardware.path}/tools/win -tools.stlink.upload.params.verbose=-d -tools.stlink.upload.params.quiet= -tools.stlink.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}.bin" - diff --git a/STM32F3/variants/discovery_f3/board/board.h b/STM32F3/variants/discovery_f3/board/board.h deleted file mode 100644 index 6b04a8be1..000000000 --- a/STM32F3/variants/discovery_f3/board/board.h +++ /dev/null @@ -1,138 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/boards/48F3/include/board/board.h - * @author F3-port: Hanspeter Portner - * @brief F303xx board header (F303CB, F303CC, F303RB, F303RC, F303VB, F303VC). - * - * See wirish/boards/maple/include/board/board.h for more information - * on these definitions. - */ - -#ifndef _BOARD_F303xx_H_ -#define _BOARD_F303xx_H_ - -#include - -#define CYCLES_PER_MICROSECOND (F_CPU / 1000000U) -#define SYSTICK_RELOAD_VAL (F_CPU/1000) - 1 /* takes a cycle to reload */ - -enum { - PC13, PC14, PC15, - PF0, PF1, - PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, - PB0, PB1, PB2, - PB10, PB11, PB12, PB13, PB14, PB15, - PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, - PB3, PB4, PB5, PB6, PB7, PB8, PB9, -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - PC0, PC1, PC2, PC3, - PF4, - PC4, PC5, PC6, PC7, PC8, PC9, PC10, PC11, PC12, - PD2, -# if defined(STM32_XL_DENSITY) - PE2, PE3, PE4, PE5, PE6, - PF9, PF10, - PF2, - PE7, PE8, PE9, PE10, PE11, PE12, PE13, PE14, PE15, - PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15, - PF6, - PD0, PD1, - PD3, PD4, PD5, PD6, PD7, - PE0, PE1, -# endif -#endif -}; - -#define BOARD_USART1_TX_PIN PA9 /* also PB6 */ -#define BOARD_USART1_RX_PIN PA10 /* also PB7 */ - -#define BOARD_USART2_TX_PIN PA2 /* also PA14, PB3 */ -#define BOARD_USART2_RX_PIN PA3 /* also PA15, PB4 */ - -#define BOARD_USART3_TX_PIN PB10 -#define BOARD_USART3_RX_PIN PB11 - -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) -# define BOARD_UART4_TX_PIN PC10 -# define BOARD_UART4_RX_PIN PC11 - -# define BOARD_UART5_TX_PIN PC12 -# define BOARD_UART5_RX_PIN PD2 -#endif - -#define BOARD_NR_SPI 3 - -#define BOARD_SPI1_NSS_PIN PA4 -#define BOARD_SPI1_SCK_PIN PA5 -#define BOARD_SPI1_MISO_PIN PA6 -#define BOARD_SPI1_MOSI_PIN PA7 - -#define BOARD_SPI2_NSS_PIN PB12 -#define BOARD_SPI2_SCK_PIN PB13 -#define BOARD_SPI2_MISO_PIN PB14 -#define BOARD_SPI2_MOSI_PIN PB15 - -#define BOARD_SPI3_NSS_PIN PA15 -#define BOARD_SPI3_SCK_PIN PB3 -#define BOARD_SPI3_MISO_PIN PB4 -#define BOARD_SPI3_MOSI_PIN PB5 - -#define BOARD_JTMS_SWDIO_PIN PA13 -#define BOARD_JTCK_SWCLK_PIN PA14 -#define BOARD_JTDI_PIN PA15 -#define BOARD_JTDO_PIN PB3 -#define BOARD_NJTRST_PIN PB4 - -#if defined(STM32_MEDIUM_DENSITY) -# define BOARD_NR_USARTS 3 -# define BOARD_NR_GPIO_PINS 37 -# define BOARD_NR_PWM_PINS 28 -# define BOARD_NR_ADC_PINS 15 -# define BOARD_NR_USED_PINS 4 -#elif defined(STM32_HIGH_DENSITY) -# define BOARD_NR_USARTS 5 -# define BOARD_NR_GPIO_PINS 52 -# define BOARD_NR_PWM_PINS 32 -# define BOARD_NR_ADC_PINS 22 -# define BOARD_NR_USED_PINS 4 -#elif defined(STM32_XL_DENSITY) -# define BOARD_NR_USARTS 5 -# define BOARD_NR_GPIO_PINS 87 -# define BOARD_NR_PWM_PINS 53 -# define BOARD_NR_ADC_PINS 39 -# define BOARD_NR_USED_PINS 7 -#endif - -/* redefine the following ones to match your hardware design */ -#define BOARD_BUTTON_PIN PA0 -#define BOARD_LED_PIN PE10 - -#define BOARD_USB_DISC_DEV GPIOA -#define BOARD_USB_DISC_BIT 13 - -#endif diff --git a/STM32F3/variants/discovery_f3/discovery_f3.cpp b/STM32F3/variants/discovery_f3/discovery_f3.cpp deleted file mode 100644 index c3c254263..000000000 --- a/STM32F3/variants/discovery_f3/discovery_f3.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2013 OpenMusicKontrollers. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish/boards/48F3/board.c - * @author F3-port: Hanspeter Portner - * @brief F303xx board file (F303CB, F303CC, F303RB, F303RC, F303VB, F303VC). - */ - -#include "board/board.h" - -#include "libmaple/gpio.h" -#include "libmaple/timer.h" - -#include "wirish/wirish_debug.h" -#include "wirish/wirish_types.h" - -/* Since we want the Serial Wire/JTAG pins as GPIOs, disable both SW - * and JTAG debug support on the packages with low pin-count (e.g. MEDIUM_DENSITY), - * unless configured otherwise. */ -void boardInit(void) { -#if defined(STM32_MEDIUM_DENSITY) - //disableDebugPorts(); -#endif - enableDebugPorts(); - -} - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - [PC13]= {GPIOC, NULL, NULL, 13, 0, ADCx}, /* PC13 */ - [PC14]= {GPIOC, NULL, NULL, 14, 0, ADCx}, /* PC14 */ /* OSC32_IN */ - [PC15]= {GPIOC, NULL, NULL, 15, 0, ADCx}, /* PC15 */ /* OSC32_OUT */ - - [PF0] = {GPIOF, NULL, NULL, 0, 0, ADCx}, /* PF0 */ /* OSC_IN */ - [PF1] = {GPIOF, NULL, NULL, 1, 0, ADCx}, /* PF1 */ /* OSC_OUT */ - - [PA0] = {GPIOA, TIMER2, ADC1, 0, 1, 1}, /* PA0 */ - [PA1] = {GPIOA, TIMER2, ADC1, 1, 2, 2}, /* PA1 */ - [PA2] = {GPIOA, TIMER2, ADC1, 2, 3, 3}, /* PA2 */ /* also TIMER15 CH1 */ - [PA3] = {GPIOA, TIMER2, ADC1, 3, 4, 4}, /* PA3 */ /* also TIMER15 CH2 */ - [PA4] = {GPIOA, TIMER3, ADC2, 4, 2, 1}, /* PA4 */ - [PA5] = {GPIOA, NULL, ADC2, 5, 0, 2}, /* PA5 */ - [PA6] = {GPIOA, TIMER3, ADC2, 6, 1, 3}, /* PA6 */ /* also TIMER16 CH1 */ - [PA7] = {GPIOA, TIMER3, ADC2, 7, 2, 4}, /* PA7 */ /* also TIMER17 CH1 */ - - [PB0] = {GPIOB, TIMER3, ADC3, 0, 3, 12}, /* PB0 */ - [PB1] = {GPIOB, TIMER3, ADC3, 1, 4, 1}, /* PB1 */ - [PB2] = {GPIOB, NULL, ADC2, 2, 0, 12}, /* PB2 */ - - [PB10]= {GPIOB, TIMER2, NULL, 10, 3, ADCx}, /* PB10 */ - [PB11]= {GPIOB, TIMER2, NULL, 11, 4, ADCx}, /* PB11 */ - [PB12]= {GPIOB, NULL, ADC4, 12, 0, 3}, /* PB12 */ - [PB13]= {GPIOB, NULL, ADC3, 13, 0, 5}, /* PB13 */ - [PB14]= {GPIOB, TIMER15,ADC4, 14, 1, 4}, /* PB14 */ - [PB15]= {GPIOB, TIMER15,ADC4, 15, 2, 5}, /* PB15 */ - - [PA8] = {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* PA8 */ - [PA9] = {GPIOA, TIMER1, NULL, 9, 2, ADCx}, /* PA9 */ /* also TIMER2_CH3 */ - [PA10]= {GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* PA10 */ /* also TIMER2 CH4 */ - [PA11]= {GPIOA, TIMER4, NULL, 11, 1, ADCx}, /* PA11 */ /* also TIMER1 CH4 */ - [PA12]= {GPIOA, TIMER4, NULL, 12, 2, ADCx}, /* PA12 */ /* also TIMER16 CH1 */ - [PA13]= {GPIOA, TIMER4, NULL, 13, 3, ADCx}, /* PA13 */ - [PA14]= {GPIOA, TIMER8, NULL, 14, 2, ADCx}, /* PA14 */ - [PA15]= {GPIOA, TIMER8, NULL, 15, 1, ADCx}, /* PA15 */ - - [PB3] = {GPIOB, TIMER2, NULL, 3, 2, ADCx}, /* PB3 */ - [PB4] = {GPIOB, TIMER3, NULL, 4, 1, ADCx}, /* PB4 */ /* also TIMER16 CH1 */ - [PB5] = {GPIOB, TIMER3, NULL, 5, 2, ADCx}, /* PB5 */ /* also TIMER17 CH1 */ - [PB6] = {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* PB6 */ /* also TIMER8 CH1 */ - [PB7] = {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* PB7 */ /* also TIMER3 CH4 */ - [PB8] = {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* PB8 */ /* also TIMER16 CH1 */ - [PB9] = {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* PB9 */ /* also TIMER17 CH1 */ - -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - [PC0] = {GPIOC, NULL, ADC1, 0, 0, 6}, /* PC0 */ - [PC1] = {GPIOC, NULL, ADC1, 1, 0, 7}, /* PC1 */ - [PC2] = {GPIOC, NULL, ADC1, 2, 0, 8}, /* PC2 */ - [PC3] = {GPIOC, NULL, ADC1, 3, 0, 9}, /* PC3 */ - - [PF4] = {GPIOF, NULL, ADC1, 4, 0, 5}, /* PF4 */ - - [PC4] = {GPIOC, NULL, ADC2, 4, 0, 5}, /* PC4 */ - [PC5] = {GPIOC, NULL, ADC2, 5, 0, 11}, /* PC5 */ - [PC6] = {GPIOC, TIMER8, NULL, 6, 1, ADCx}, /* PC6 */ /* also TIMER3_CH1 */ - [PC7] = {GPIOC, TIMER8, NULL, 7, 2, ADCx}, /* PC7 */ /* also TIMER3_CH2 */ - [PC8] = {GPIOC, TIMER8, NULL, 8, 3, ADCx}, /* PC8 */ /* also TIMER3_CH3 */ - [PC9] = {GPIOC, TIMER8, NULL, 9, 4, ADCx}, /* PC9 */ /* also TIMER3_CH4 */ - [PC10]= {GPIOC, NULL, NULL, 10, 0, ADCx}, /* PC10 */ - [PC11]= {GPIOC, NULL, NULL, 11, 0, ADCx}, /* PC11 */ - [PC12]= {GPIOC, NULL, NULL, 12, 0, ADCx}, /* PC12 */ - - [PD2] = {GPIOD, NULL, NULL, 2, 0, ADCx}, /* PD2 */ - -# if defined(STM32_XL_DENSITY) - [PE2] = {GPIOE, TIMER3, NULL, 2, 1, ADCx}, /* PE2 */ - [PE3] = {GPIOE, TIMER3, NULL, 3, 2, ADCx}, /* PE3 */ - [PE4] = {GPIOE, TIMER3, NULL, 4, 3, ADCx}, /* PE4 */ - [PE5] = {GPIOE, TIMER3, NULL, 5, 4, ADCx}, /* PE5 */ - [PE6] = {GPIOE, NULL, NULL, 6, 0, ADCx}, /* PE6 */ - - [PF9] = {GPIOF,TIMER15, NULL, 9, 1, ADCx}, /* PF9 */ - [PF10]= {GPIOF,TIMER15, NULL, 10, 2, ADCx}, /* PF10 */ - - [PF2] = {GPIOF, NULL, ADC1, 2, 0, 10}, /* PF2 */ - - [PE7] = {GPIOE, NULL, ADC3, 7, 0, 13}, /* PE7 */ - [PE8] = {GPIOE, NULL, ADC3, 8, 0, 6}, /* PE8 */ - [PE9] = {GPIOE, TIMER1, ADC3, 9, 1, 2}, /* PE9 */ - [PE10]= {GPIOE, NULL, ADC3, 10, 0, 14}, /* PE10 */ - [PE11]= {GPIOE, TIMER1, ADC3, 11, 2, 15}, /* PE11 */ - [PE12]= {GPIOE, NULL, ADC3, 12, 0, 15}, /* PE12 */ - [PE13]= {GPIOE, TIMER1, ADC3, 13, 3, 3}, /* PE13 */ - [PE14]= {GPIOE, TIMER1, ADC4, 14, 4, 1}, /* PE14 */ - [PE15]= {GPIOE, NULL, ADC4, 15, 0, 2}, /* PE15 */ - - [PD8] = {GPIOD, NULL, ADC4, 8, 0, 12}, /* PD8 */ - [PD9] = {GPIOD, NULL, ADC4, 9, 0, 13}, /* PD0 */ - [PD10]= {GPIOD, NULL, ADC3, 10, 0, 7}, /* PD10 */ - [PD11]= {GPIOD, NULL, ADC3, 11, 0, 8}, /* PD11 */ - [PD12]= {GPIOD, TIMER4, ADC3, 12, 1, 9}, /* PD12 */ - [PD13]= {GPIOD, TIMER4, ADC3, 13, 2, 10}, /* PD13 */ - [PD14]= {GPIOD, TIMER4, ADC3, 14, 3, 11}, /* PD14 */ - [PD15]= {GPIOD, TIMER4, NULL, 15, 4, ADCx}, /* PD15 */ - - [PF6] = {GPIOF, TIMER4, NULL, 6, 4, ADCx}, /* PF6 */ - - [PD0] = {GPIOD, NULL, NULL, 0, 0, ADCx}, /* PD0 */ - [PD1] = {GPIOD, TIMER8, NULL, 1, 4, ADCx}, /* PD1 */ - - [PD3] = {GPIOD, NULL, NULL, 3, 0, ADCx}, /* PD3 */ - [PD4] = {GPIOD, TIMER2, NULL, 4, 2, ADCx}, /* PD4 */ - [PD5] = {GPIOD, NULL, NULL, 5, 0, ADCx}, /* PD5 */ - [PD6] = {GPIOD, TIMER2, NULL, 6, 4, ADCx}, /* PD6 */ - [PD7] = {GPIOD, TIMER2, NULL, 7, 3, ADCx}, /* PD7 */ - - [PE0] = {GPIOE,TIMER16, NULL, 0, 1, ADCx}, /* PE0 */ - [PE1] = {GPIOE,TIMER17, NULL, 1, 1, ADCx}, /* PE1 */ -# endif -#endif -}; - -extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { - PA0, PA1, PA2, PA3, PA4, PA6, PA7, PB0, PB1, PB10, PB11, PB14, PB15, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, PB3, PB4, PB5, PB6, PB7, PB8, PB9, -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - PC6, PC7, PC8, PC9, -# if defined(STM32_XL_DENSITY) - PE2, PE3, PE4, PE5, PF9, PF10, PE9, PE11, PE13, PE14, PD12, PD13, PD14, PD15, PF6, PD1, PD4, PD6, PD7, PE0, PE1, -# endif -#endif -}; - -extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { - PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PB0, PB1, PB2, PB12, PB13, PB14, PB15, -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - PC0, PC1, PC2, PC3, PF4, PC4, PC5, -# if defined(STM32_XL_DENSITY) - PF2, PE7, PE8, PE9, PE10, PE11, PE12, PE13, PE14, PE15, PD8, PD9, PD10, PD11, PD12, PD13, PD14, -# endif -#endif -}; - -#define OSC_IN PF0 -#define OSC_OUT PF1 - -#define USB_DM PA11 -#define USB_DP PA12 - -extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { - OSC_IN, OSC_OUT, USB_DP, USB_DM,PB3, PA13, PA14 -}; diff --git a/STM32F3/variants/discovery_f3/ld/mem-flash.inc b/STM32F3/variants/discovery_f3/ld/mem-flash.inc deleted file mode 100644 index a6838084d..000000000 --- a/STM32F3/variants/discovery_f3/ld/mem-flash.inc +++ /dev/null @@ -1,6 +0,0 @@ -MEMORY -{ - ccm (rwx) : ORIGIN = 0x10000000, LENGTH = 8K - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 37K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 236K -} diff --git a/STM32F3/variants/discovery_f3/ld/mem-jtag.inc b/STM32F3/variants/discovery_f3/ld/mem-jtag.inc deleted file mode 100644 index 9fb445247..000000000 --- a/STM32F3/variants/discovery_f3/ld/mem-jtag.inc +++ /dev/null @@ -1,6 +0,0 @@ -MEMORY -{ - ccm (rwx) : ORIGIN = 0x10000000, LENGTH = 8K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 40K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K -} diff --git a/STM32F3/variants/discovery_f3/ld/mem-ram.inc b/STM32F3/variants/discovery_f3/ld/mem-ram.inc deleted file mode 100644 index 08d76083c..000000000 --- a/STM32F3/variants/discovery_f3/ld/mem-ram.inc +++ /dev/null @@ -1,6 +0,0 @@ -MEMORY -{ - ccm (rwx) : ORIGIN = 0x10000000, LENGTH = 8K - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 37K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K -} diff --git a/STM32F3/variants/discovery_f3/ld/vector_symbols.inc b/STM32F3/variants/discovery_f3/ld/vector_symbols.inc deleted file mode 100644 index a9d18f447..000000000 --- a/STM32F3/variants/discovery_f3/ld/vector_symbols.inc +++ /dev/null @@ -1,98 +0,0 @@ -EXTERN(__msp_init) -EXTERN(__exc_reset) -EXTERN(__exc_nmi) -EXTERN(__exc_hardfault) -EXTERN(__exc_memmanage) -EXTERN(__exc_busfault) -EXTERN(__exc_usagefault) -EXTERN(__stm32reservedexception7) -EXTERN(__stm32reservedexception8) -EXTERN(__stm32reservedexception9) -EXTERN(__stm32reservedexception10) -EXTERN(__exc_svc) -EXTERN(__exc_debug_monitor) -EXTERN(__stm32reservedexception13) -EXTERN(__exc_pendsv) -EXTERN(__exc_systick) -EXTERN(__irq_wwdg) -EXTERN(__irq_pvd) -EXTERN(__irq_tamp_stamp) -EXTERN(__irq_rtc_wkup) -EXTERN(__irq_flash) -EXTERN(__irq_rcc) -EXTERN(__irq_exti0) -EXTERN(__irq_exti1) -EXTERN(__irq_exti2) -EXTERN(__irq_exti3) -EXTERN(__irq_exti4) -EXTERN(__irq_dma1_ch1) -EXTERN(__irq_dma1_ch2) -EXTERN(__irq_dma1_ch3) -EXTERN(__irq_dma1_ch4) -EXTERN(__irq_dma1_ch5) -EXTERN(__irq_dma1_ch6) -EXTERN(__irq_dma1_ch7) -EXTERN(__irq_adc1_2) -EXTERN(__irq_usb_hp_can_tx) -EXTERN(__irq_usb_lp_can_rx0) -EXTERN(__irq_can_rx1) -EXTERN(__irq_can_sce) -EXTERN(__irq_exti9_5) -EXTERN(__irq_tim1_brk_tim15) -EXTERN(__irq_tim1_up_tim16) -EXTERN(__irq_tim1_trg_com_tim17) -EXTERN(__irq_tim1_cc) -EXTERN(__irq_tim2) -EXTERN(__irq_tim3) -EXTERN(__irq_tim4) -EXTERN(__irq_i2c1_ev) -EXTERN(__irq_i2c1_er) -EXTERN(__irq_i2c2_ev) -EXTERN(__irq_i2c2_er) -EXTERN(__irq_spi1) -EXTERN(__irq_spi2) -EXTERN(__irq_usart1) -EXTERN(__irq_usart2) -EXTERN(__irq_usart3) -EXTERN(__irq_exti15_10) -EXTERN(__irq_rtc_alarm) -EXTERN(__irq_usb_wkup) -EXTERN(__irq_tim8_brk) -EXTERN(__irq_tim8_up) -EXTERN(__irq_tim8_trg_com) -EXTERN(__irq_tim8_cc) -EXTERN(__irq_adc3) -EXTERN(__stm32reservedexception48) -EXTERN(__stm32reservedexception49) -EXTERN(__stm32reservedexception50) -EXTERN(__irq_spi3) -EXTERN(__irq_uart4) -EXTERN(__irq_uart5) -EXTERN(__irq_tim6_dacunder) -EXTERN(__irq_tim7) -EXTERN(__irq_dma2_ch1) -EXTERN(__irq_dma2_ch2) -EXTERN(__irq_dma2_ch3) -EXTERN(__irq_dma2_ch4) -EXTERN(__irq_dma2_ch5) -EXTERN(__irq_adc4) -EXTERN(__stm32reservedexception62) -EXTERN(__stm32reservedexception63) -EXTERN(__irq_comp123) -EXTERN(__irq_comp456) -EXTERN(__irq_comp7) -EXTERN(__stm32reservedexception67) -EXTERN(__stm32reservedexception68) -EXTERN(__stm32reservedexception69) -EXTERN(__stm32reservedexception70) -EXTERN(__stm32reservedexception71) -EXTERN(__stm32reservedexception72) -EXTERN(__stm32reservedexception73) -EXTERN(__irq_usb_hp) -EXTERN(__irq_usb_lp) -EXTERN(__irq_usb_wkup2) -EXTERN(__stm32reservedexception77) -EXTERN(__stm32reservedexception78) -EXTERN(__stm32reservedexception79) -EXTERN(__stm32reservedexception80) -EXTERN(__irq_fpu) diff --git a/STM32F3/variants/discovery_f3/stm32_isrs.S b/STM32F3/variants/discovery_f3/stm32_isrs.S deleted file mode 100644 index f236387aa..000000000 --- a/STM32F3/variants/discovery_f3/stm32_isrs.S +++ /dev/null @@ -1,331 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* STM32F3 performance line ISR weak declarations */ - -#include - - .thumb - -/* Default handler for all non-overridden interrupts and exceptions */ - .globl __default_handler - .type __default_handler, %function - -__default_handler: - b . - - .weak __exc_nmi - .globl __exc_nmi - .set __exc_nmi, __default_handler - .weak __exc_hardfault - .globl __exc_hardfault - .set __exc_hardfault, __default_handler - .weak __exc_memmanage - .globl __exc_memmanage - .set __exc_memmanage, __default_handler - .weak __exc_busfault - .globl __exc_busfault - .set __exc_busfault, __default_handler - .weak __exc_usagefault - .globl __exc_usagefault - .set __exc_usagefault, __default_handler - .weak __stm32reservedexception7 - .globl __stm32reservedexception7 - .set __stm32reservedexception7, __default_handler - .weak __stm32reservedexception8 - .globl __stm32reservedexception8 - .set __stm32reservedexception8, __default_handler - .weak __stm32reservedexception9 - .globl __stm32reservedexception9 - .set __stm32reservedexception9, __default_handler - .weak __stm32reservedexception10 - .globl __stm32reservedexception10 - .set __stm32reservedexception10, __default_handler - .weak __exc_svc - .globl __exc_svc - .set __exc_svc, __default_handler - .weak __exc_debug_monitor - .globl __exc_debug_monitor - .set __exc_debug_monitor, __default_handler - .weak __stm32reservedexception13 - .globl __stm32reservedexception13 - .set __stm32reservedexception13, __default_handler - .weak __exc_pendsv - .globl __exc_pendsv - .set __exc_pendsv, __default_handler - .weak __exc_systick - .globl __exc_systick - .set __exc_systick, __default_handler - .weak __irq_wwdg - .globl __irq_wwdg - .set __irq_wwdg, __default_handler - .weak __irq_pvd - .globl __irq_pvd - .set __irq_pvd, __default_handler - .weak __irq_tamp_stamp - .globl __irq_tamp_stamp - .set __irq_tamp_stamp, __default_handler - .weak __irq_rtc_wkup - .globl __irq_rtc_wkup - .set __irq_rtc_wkup, __default_handler - .weak __irq_flash - .globl __irq_flash - .set __irq_flash, __default_handler - .weak __irq_rcc - .globl __irq_rcc - .set __irq_rcc, __default_handler - .weak __irq_exti0 - .globl __irq_exti0 - .set __irq_exti0, __default_handler - .weak __irq_exti1 - .globl __irq_exti1 - .set __irq_exti1, __default_handler - .weak __irq_exti2 - .globl __irq_exti2 - .set __irq_exti2, __default_handler - .weak __irq_exti3 - .globl __irq_exti3 - .set __irq_exti3, __default_handler - .weak __irq_exti4 - .globl __irq_exti4 - .set __irq_exti4, __default_handler - .weak __irq_dma1_ch1 - .globl __irq_dma1_ch1 - .set __irq_dma1_ch1, __default_handler - .weak __irq_dma1_ch2 - .globl __irq_dma1_ch2 - .set __irq_dma1_ch2, __default_handler - .weak __irq_dma1_ch3 - .globl __irq_dma1_ch3 - .set __irq_dma1_ch3, __default_handler - .weak __irq_dma1_ch4 - .globl __irq_dma1_ch4 - .set __irq_dma1_ch4, __default_handler - .weak __irq_dma1_ch5 - .globl __irq_dma1_ch5 - .set __irq_dma1_ch5, __default_handler - .weak __irq_dma1_ch6 - .globl __irq_dma1_ch6 - .set __irq_dma1_ch6, __default_handler - .weak __irq_dma1_ch7 - .globl __irq_dma1_ch7 - .set __irq_dma1_ch7, __default_handler - .weak __irq_adc1_2 - .globl __irq_adc1_2 - .set __irq_adc1_2, __default_handler - .weak __irq_usb_hp_can_tx - .globl __irq_usb_hp_can_tx - .set __irq_usb_hp_can_tx, __default_handler - .weak __irq_usb_lp_can_rx0 - .globl __irq_usb_lp_can_rx0 - .set __irq_usb_lp_can_rx0, __default_handler - .weak __irq_can_rx1 - .globl __irq_can_rx1 - .set __irq_can_rx1, __default_handler - .weak __irq_can_sce - .globl __irq_can_sce - .set __irq_can_sce, __default_handler - .weak __irq_exti9_5 - .globl __irq_exti9_5 - .set __irq_exti9_5, __default_handler - .weak __irq_tim1_brk_tim15 - .globl __irq_tim1_brk_tim15 - .set __irq_tim1_brk_tim15, __default_handler - .weak __irq_tim1_up_tim16 - .globl __irq_tim1_up_tim16 - .set __irq_tim1_up_tim16, __default_handler - .weak __irq_tim1_trg_com_tim17 - .globl __irq_tim1_trg_com_tim17 - .set __irq_tim1_trg_com_tim17, __default_handler - .weak __irq_tim1_cc - .globl __irq_tim1_cc - .set __irq_tim1_cc, __default_handler - .weak __irq_tim2 - .globl __irq_tim2 - .set __irq_tim2, __default_handler - .weak __irq_tim3 - .globl __irq_tim3 - .set __irq_tim3, __default_handler - .weak __irq_tim4 - .globl __irq_tim4 - .set __irq_tim4, __default_handler - .weak __irq_i2c1_ev - .globl __irq_i2c1_ev - .set __irq_i2c1_ev, __default_handler - .weak __irq_i2c1_er - .globl __irq_i2c1_er - .set __irq_i2c1_er, __default_handler - .weak __irq_i2c2_ev - .globl __irq_i2c2_ev - .set __irq_i2c2_ev, __default_handler - .weak __irq_i2c2_er - .globl __irq_i2c2_er - .set __irq_i2c2_er, __default_handler - .weak __irq_spi1 - .globl __irq_spi1 - .set __irq_spi1, __default_handler - .weak __irq_spi2 - .globl __irq_spi2 - .set __irq_spi2, __default_handler - .weak __irq_usart1 - .globl __irq_usart1 - .set __irq_usart1, __default_handler - .weak __irq_usart2 - .globl __irq_usart2 - .set __irq_usart2, __default_handler - .weak __irq_usart3 - .globl __irq_usart3 - .set __irq_usart3, __default_handler - .weak __irq_exti15_10 - .globl __irq_exti15_10 - .set __irq_exti15_10, __default_handler - .weak __irq_rtc_alarm - .globl __irq_rtc_alarm - .set __irq_rtc_alarm, __default_handler - .weak __irq_usb_wkup - .globl __irq_usb_wkup - .set __irq_usb_wkup, __default_handler - - .weak __irq_tim8_brk - .globl __irq_tim8_brk - .set __irq_tim8_brk, __default_handler - .weak __irq_tim8_up - .globl __irq_tim8_up - .set __irq_tim8_up, __default_handler - .weak __irq_tim8_trg_com - .globl __irq_tim8_trg_com - .set __irq_tim8_trg_com, __default_handler - .weak __irq_tim8_cc - .globl __irq_tim8_cc - .set __irq_tim8_cc, __default_handler - .weak __irq_adc3 - .globl __irq_adc3 - .set __irq_adc3, __default_handler - .weak __stm32reservedexception48 - .globl __stm32reservedexception48 - .set __stm32reservedexception48, __default_handler - .weak __stm32reservedexception49 - .globl __stm32reservedexception49 - .set __stm32reservedexception49, __default_handler - .weak __stm32reservedexception50 - .globl __stm32reservedexception50 - .set __stm32reservedexception50, __default_handler - .weak __irq_spi3 - .globl __irq_spi3 - .set __irq_spi3, __default_handler - .weak __irq_uart4 - .globl __irq_uart4 - .set __irq_uart4, __default_handler - .weak __irq_uart5 - .globl __irq_uart5 - .set __irq_uart5, __default_handler - .weak __irq_tim6_dacunder - .globl __irq_tim6_dacunder - .set __irq_tim6_dac, __default_handler - .weak __irq_tim7 - .globl __irq_tim7 - .set __irq_tim7, __default_handler - .weak __irq_dma2_ch1 - .globl __irq_dma2_ch1 - .set __irq_dma2_ch1, __default_handler - .weak __irq_dma2_ch2 - .globl __irq_dma2_ch2 - .set __irq_dma2_ch2, __default_handler - .weak __irq_dma2_ch3 - .globl __irq_dma2_ch3 - .set __irq_dma2_ch3, __default_handler - .weak __irq_dma2_ch4 - .globl __irq_dma2_ch4 - .set __irq_dma2_ch4, __default_handler - .weak __irq_dma2_ch5 - .globl __irq_dma2_ch5 - .set __irq_dma2_ch5, __default_handler - .weak __irq_adc4 - .globl __irq_adc4 - .set __irq_adc4, __default_handler - .weak __stm32reservedexception62 - .globl __stm32reservedexception62 - .set __stm32reservedexception62, __default_handler - .weak __stm32reservedexception63 - .globl __stm32reservedexception63 - .set __stm32reservedexception63, __default_handler - .weak __irq_comp123 - .globl __irq_comp123 - .set __irq_comp123, __default_handler - .weak __irq_comp456 - .globl __irq_comp456 - .set __irq_comp456, __default_handler - .weak __irq_comp7 - .globl __irq_comp7 - .set __irq_comp7, __default_handler - .weak __stm32reservedexception67 - .globl __stm32reservedexception67 - .set __stm32reservedexception67, __default_handler - .weak __stm32reservedexception68 - .globl __stm32reservedexception68 - .set __stm32reservedexception68, __default_handler - .weak __stm32reservedexception69 - .globl __stm32reservedexception69 - .set __stm32reservedexception69, __default_handler - .weak __stm32reservedexception70 - .globl __stm32reservedexception70 - .set __stm32reservedexception70, __default_handler - .weak __stm32reservedexception71 - .globl __stm32reservedexception71 - .set __stm32reservedexception71, __default_handler - .weak __stm32reservedexception72 - .globl __stm32reservedexception72 - .set __stm32reservedexception72, __default_handler - .weak __stm32reservedexception73 - .globl __stm32reservedexception73 - .set __stm32reservedexception73, __default_handler - .weak __irq_usb_hp - .globl __irq_usb_hp - .set __irq_usb_hp, __default_handler - .weak __irq_usb_lp - .globl __irq_usb_lp - .set __irq_usb_lp, __default_handler - .weak __irq_usb_wkup2 - .globl __irq_usb_wkup2 - .set __irq_usb_wkup2, __default_handler - .weak __stm32reservedexception77 - .globl __stm32reservedexception77 - .set __stm32reservedexception77, __default_handler - .weak __stm32reservedexception78 - .globl __stm32reservedexception78 - .set __stm32reservedexception78, __default_handler - .weak __stm32reservedexception79 - .globl __stm32reservedexception79 - .set __stm32reservedexception79, __default_handler - .weak __stm32reservedexception80 - .globl __stm32reservedexception80 - .set __stm32reservedexception80, __default_handler - .weak __irq_fpu - .globl __irq_fpu - .set __irq_fpu, __default_handler - .weak __reserved - .globl __reserved - .set __reserved, __default_handler diff --git a/STM32F3/variants/discovery_f3/stm32_vector_table.S b/STM32F3/variants/discovery_f3/stm32_vector_table.S deleted file mode 100644 index f68fa4bcc..000000000 --- a/STM32F3/variants/discovery_f3/stm32_vector_table.S +++ /dev/null @@ -1,134 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ /* STM32F3 performance line vector table */ #include - .section ".stm32.interrupt_vector" - - .globl __stm32_vector_table - .type __stm32_vector_table, %object - -__stm32_vector_table: -/* CM4 core interrupts */ - .long __msp_init - .long __exc_reset - .long __exc_nmi - .long __exc_hardfault - .long __exc_memmanage - .long __exc_busfault - .long __exc_usagefault - .long __stm32reservedexception7 - .long __stm32reservedexception8 - .long __stm32reservedexception9 - .long __stm32reservedexception10 - .long __exc_svc - .long __exc_debug_monitor - .long __stm32reservedexception13 - .long __exc_pendsv - .long __exc_systick -/* Peripheral interrupts */ - .long __irq_wwdg - .long __irq_pvd - .long __irq_tamp_stamp - .long __irq_rtc_wkup - .long __irq_flash - .long __irq_rcc - .long __irq_exti0 - .long __irq_exti1 - .long __irq_exti2 - .long __irq_exti3 - .long __irq_exti4 - .long __irq_dma1_ch1 - .long __irq_dma1_ch2 - .long __irq_dma1_ch3 - .long __irq_dma1_ch4 - .long __irq_dma1_ch5 - .long __irq_dma1_ch6 - .long __irq_dma1_ch7 - .long __irq_adc1_2 - .long __irq_usb_hp_can_tx - .long __irq_usb_lp_can_rx0 - .long __irq_can_rx1 - .long __irq_can_sce - .long __irq_exti9_5 - .long __irq_tim1_brk_tim15 - .long __irq_tim1_up_tim16 - .long __irq_tim1_trg_com_tim17 - .long __irq_tim1_cc - .long __irq_tim2 - .long __irq_tim3 - .long __irq_tim4 - .long __irq_i2c1_ev - .long __irq_i2c1_er - .long __irq_i2c2_ev - .long __irq_i2c2_er - .long __irq_spi1 - .long __irq_spi2 - .long __irq_usart1 - .long __irq_usart2 - .long __irq_usart3 - .long __irq_exti15_10 - .long __irq_rtc_alarm - .long __irq_usb_wkup - - .long __irq_tim8_brk - .long __irq_tim8_up - .long __irq_tim8_trg_com - .long __irq_tim8_cc - .long __irq_adc3 - .long __stm32reservedexception48 - .long __stm32reservedexception49 - .long __stm32reservedexception50 - .long __irq_spi3 - .long __irq_uart4 - .long __irq_uart5 - .long __irq_tim6_dacunder - .long __irq_tim7 - .long __irq_dma2_ch1 - .long __irq_dma2_ch2 - .long __irq_dma2_ch3 - .long __irq_dma2_ch4 - .long __irq_dma2_ch5 - .long __irq_adc4 - .long __stm32reservedexception62 - .long __stm32reservedexception63 - .long __irq_comp123 - .long __irq_comp456 - .long __irq_comp7 - .long __stm32reservedexception67 - .long __stm32reservedexception68 - .long __stm32reservedexception69 - .long __stm32reservedexception70 - .long __stm32reservedexception71 - .long __stm32reservedexception72 - .long __stm32reservedexception73 - .long __irq_usb_hp - .long __irq_usb_lp - .long __irq_usb_wkup2 - .long __stm32reservedexception77 - .long __stm32reservedexception78 - .long __stm32reservedexception79 - .long __stm32reservedexception80 - .long __irq_fpu - - .size __stm32_vector_table, . - __stm32_vector_table diff --git a/STM32F4/STM32F4.zip b/STM32F4/STM32F4.zip new file mode 100644 index 000000000..9eab6f113 Binary files /dev/null and b/STM32F4/STM32F4.zip differ diff --git a/STM32F4/boards.txt b/STM32F4/boards.txt index 907e6f7f4..22f1aca77 100644 --- a/STM32F4/boards.txt +++ b/STM32F4/boards.txt @@ -19,31 +19,25 @@ discovery_f407.upload.maximum_data_size=131072 #discovery_f407.upload.altID=1 #discovery_f407.upload.auto_reset=true -discovery_f407.build.mcu=cortex-m4 -discovery_f407.build.f_cpu=168000000L discovery_f407.build.core=maple -discovery_f407.build.extra_flags=-DMCU_STM32F406VG -mthumb -DSTM32_HIGH_DENSITY -DSTM32F2 -DSTM32F4 -DBOARD_discovery_f4 +discovery_f407.build.f_cpu=168000000 +discovery_f407.build.extra_flags= -DLED_BUILTIN=PD14 -DCRYSTAL_FREQ=8 discovery_f407.build.ldscript=ld/jtag.ld discovery_f407.build.variant=discovery_f407 discovery_f407.build.variant_system_lib=lib_f407.a -discovery_f407.build.vect=VECT_TAB_BASE -discovery_f407.build.density=STM32_HIGH_DENSITY -discovery_f407.build.error_led_port=GPIOD -discovery_f407.build.error_led_pin=14 -discovery_f407.build.board=STM32DiscoveryF407 -discovery_f407.build.vect_flags=-DVECT_TAB_FLASH -DUSER_ADDR_ROM=(uint32)0x08000000 +discovery_f407.build.error_led_pin=PD14 +discovery_f407.build.board=discovery_f4 +discovery_f407.build.vect_flags=-DUSER_ADDR_ROM=0x08000000 -discovery_f407.menu.usb_cfg.usb_nc=USB inactive -discovery_f407.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC discovery_f407.menu.usb_cfg.usb_serial=USB serial (CDC) discovery_f407.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB +discovery_f407.menu.usb_cfg.usb_nc=USB inactive +discovery_f407.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC discovery_f407.menu.usb_cfg.usb_msc=USB Mass Storage (MSC) discovery_f407.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC #-- Optimizations discovery_f407.menu.opt.osstd=Smallest (default) -discovery_f407.menu.opt.osstd.build.flags.optimize=-Os -discovery_f407.menu.opt.osstd.build.flags.ldspecs= discovery_f407.menu.opt.oslto=Smallest Code with LTO discovery_f407.menu.opt.oslto.build.flags.optimize=-Os -flto discovery_f407.menu.opt.oslto.build.flags.ldspecs=-flto @@ -69,10 +63,168 @@ discovery_f407.menu.opt.ogstd=Debug (-g) discovery_f407.menu.opt.ogstd.build.flags.optimize=-Og discovery_f407.menu.opt.ogstd.build.flags.ldspecs= ############################################################## -generic_f407v.name=Generic STM32F407V series +blackpill_f401.name=Blackpill STM32F401CCU6 + +blackpill_f401.menu.upload_method.STLinkMethod=STLink +blackpill_f401.menu.upload_method.STLinkMethod.upload.protocol=STLink +blackpill_f401.menu.upload_method.STLinkMethod.upload.tool=stlink_upload + +blackpill_f401.upload.file_type=bin +blackpill_f401.upload.maximum_size=262144 +blackpill_f401.upload.maximum_data_size=65536 + +blackpill_f401.build.core=maple +blackpill_f401.build.f_cpu=84000000 +blackpill_f401.build.extra_flags=-DLED_BUILTIN=PC13 -DCRYSTAL_FREQ=25 -DNO_CCMRAM -DMCU_STM32F401CC +blackpill_f401.build.ldscript=ld/jtag.ld +blackpill_f401.build.variant=blackpill_f401 +blackpill_f401.build.variant_system_lib=lib_f407.a +blackpill_f401.build.error_led_pin=PC13 +blackpill_f401.build.board=blackpill_f401 +blackpill_f401.build.vect_flags=-DUSER_ADDR_ROM=0x08000000 + +blackpill_f401.menu.usb_cfg.usb_serial=USB serial (CDC) +blackpill_f401.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB +blackpill_f401.menu.usb_cfg.usb_nc=USB inactive +blackpill_f401.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC +blackpill_f401.menu.usb_cfg.usb_msc=USB Mass Storage (MSC) +blackpill_f401.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC -generic_f407v.upload.tool=stlink_upload -generic_f407v.upload.protocol=stlink +#-- Optimizations +blackpill_f401.menu.opt.osstd=Smallest (default) +blackpill_f401.menu.opt.oslto=Smallest Code with LTO +blackpill_f401.menu.opt.oslto.build.flags.optimize=-Os -flto +blackpill_f401.menu.opt.oslto.build.flags.ldspecs=-flto +blackpill_f401.menu.opt.o1std=Fast (-O1) +blackpill_f401.menu.opt.o1std.build.flags.optimize=-O1 +blackpill_f401.menu.opt.o1std.build.flags.ldspecs= +blackpill_f401.menu.opt.o1lto=Fast (-O1) with LTO +blackpill_f401.menu.opt.o1lto.build.flags.optimize=-O1 -flto +blackpill_f401.menu.opt.o1lto.build.flags.ldspecs=-flto +blackpill_f401.menu.opt.o2std=Faster (-O2) +blackpill_f401.menu.opt.o2std.build.flags.optimize=-O2 +blackpill_f401.menu.opt.o2std.build.flags.ldspecs= +blackpill_f401.menu.opt.o2lto=Faster (-O2) with LTO +blackpill_f401.menu.opt.o2lto.build.flags.optimize=-O2 -flto +blackpill_f401.menu.opt.o2lto.build.flags.ldspecs=-flto +blackpill_f401.menu.opt.o3std=Fastest (-O3) +blackpill_f401.menu.opt.o3std.build.flags.optimize=-O3 +blackpill_f401.menu.opt.o3std.build.flags.ldspecs= +blackpill_f401.menu.opt.o3lto=Fastest (-O3) with LTO +blackpill_f401.menu.opt.o3lto.build.flags.optimize=-O3 -flto +blackpill_f401.menu.opt.o3lto.build.flags.ldspecs=-flto +blackpill_f401.menu.opt.ogstd=Debug (-g) +blackpill_f401.menu.opt.ogstd.build.flags.optimize=-Og +blackpill_f401.menu.opt.ogstd.build.flags.ldspecs= +############################################################## +blackpill_f411.name=Blackpill STM32F411CEU6 + +blackpill_f411.menu.upload_method.STLinkMethod=STLink +blackpill_f411.menu.upload_method.STLinkMethod.upload.protocol=STLink +blackpill_f411.menu.upload_method.STLinkMethod.upload.tool=stlink_upload + +blackpill_f411.upload.file_type=bin +blackpill_f411.upload.maximum_size=524288 +blackpill_f411.upload.maximum_data_size=131072 + +blackpill_f411.build.core=maple +blackpill_f411.build.f_cpu=96000000 +blackpill_f411.build.extra_flags=-DLED_BUILTIN=PC13 -DCRYSTAL_FREQ=25 -DNO_CCMRAM -DMCU_STM32F411CE +blackpill_f411.build.ldscript=ld/jtag.ld +blackpill_f411.build.variant=blackpill_f411 +blackpill_f411.build.variant_system_lib=lib_f407.a +blackpill_f411.build.error_led_pin=PC13 +blackpill_f411.build.board=blackpill_f411 +blackpill_f411.build.vect_flags=-DUSER_ADDR_ROM=0x08000000 + +blackpill_f411.menu.usb_cfg.usb_serial=USB serial (CDC) +blackpill_f411.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB +blackpill_f411.menu.usb_cfg.usb_nc=USB inactive +blackpill_f411.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC +blackpill_f411.menu.usb_cfg.usb_msc=USB Mass Storage (MSC) +blackpill_f411.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC + +#-- Optimizations +blackpill_f411.menu.opt.osstd=Smallest (default) +blackpill_f411.menu.opt.oslto=Smallest Code with LTO +blackpill_f411.menu.opt.oslto.build.flags.optimize=-Os -flto +blackpill_f411.menu.opt.oslto.build.flags.ldspecs=-flto +blackpill_f411.menu.opt.o1std=Fast (-O1) +blackpill_f411.menu.opt.o1std.build.flags.optimize=-O1 +blackpill_f411.menu.opt.o1std.build.flags.ldspecs= +blackpill_f411.menu.opt.o1lto=Fast (-O1) with LTO +blackpill_f411.menu.opt.o1lto.build.flags.optimize=-O1 -flto +blackpill_f411.menu.opt.o1lto.build.flags.ldspecs=-flto +blackpill_f411.menu.opt.o2std=Faster (-O2) +blackpill_f411.menu.opt.o2std.build.flags.optimize=-O2 +blackpill_f411.menu.opt.o2std.build.flags.ldspecs= +blackpill_f411.menu.opt.o2lto=Faster (-O2) with LTO +blackpill_f411.menu.opt.o2lto.build.flags.optimize=-O2 -flto +blackpill_f411.menu.opt.o2lto.build.flags.ldspecs=-flto +blackpill_f411.menu.opt.o3std=Fastest (-O3) +blackpill_f411.menu.opt.o3std.build.flags.optimize=-O3 +blackpill_f411.menu.opt.o3std.build.flags.ldspecs= +blackpill_f411.menu.opt.o3lto=Fastest (-O3) with LTO +blackpill_f411.menu.opt.o3lto.build.flags.optimize=-O3 -flto +blackpill_f411.menu.opt.o3lto.build.flags.ldspecs=-flto +blackpill_f411.menu.opt.ogstd=Debug (-g) +blackpill_f411.menu.opt.ogstd.build.flags.optimize=-Og +blackpill_f411.menu.opt.ogstd.build.flags.ldspecs= +############################################################## +disco_f411.name=STM32 Discovery F411E + +disco_f411.upload.tool=stlink_upload +disco_f411.upload.protocol=stlink + +disco_f411.upload.file_type=bin +disco_f411.upload.maximum_size=1048576 +disco_f411.upload.maximum_data_size=131072 + +disco_f411.build.core=maple +disco_f411.build.f_cpu=96000000 +disco_f411.build.extra_flags=-DLED_BUILTIN=PD12 -DCRYSTAL_FREQ=8 -DNO_CCMRAM +disco_f411.build.ldscript=ld/jtag.ld +disco_f411.build.variant=disco_f411 +disco_f411.build.variant_system_lib=lib_f407.a +disco_f411.build.error_led_pin=PD14 +disco_f411.build.board=disco_f411 +disco_f411.build.vect_flags=-DUSER_ADDR_ROM=0x08000000 + +disco_f411.menu.usb_cfg.usb_serial=USB serial (CDC) +disco_f411.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB +disco_f411.menu.usb_cfg.usb_nc=USB inactive +disco_f411.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC +disco_f411.menu.usb_cfg.usb_msc=USB Mass Storage (MSC) +disco_f411.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC + +#-- Optimizations +disco_f411.menu.opt.osstd=Smallest (default) +disco_f411.menu.opt.oslto=Smallest Code with LTO +disco_f411.menu.opt.oslto.build.flags.optimize=-Os -flto +disco_f411.menu.opt.oslto.build.flags.ldspecs=-flto +disco_f411.menu.opt.o1std=Fast (-O1) +disco_f411.menu.opt.o1std.build.flags.optimize=-O1 +disco_f411.menu.opt.o1std.build.flags.ldspecs= +disco_f411.menu.opt.o1lto=Fast (-O1) with LTO +disco_f411.menu.opt.o1lto.build.flags.optimize=-O1 -flto +disco_f411.menu.opt.o1lto.build.flags.ldspecs=-flto +disco_f411.menu.opt.o2std=Faster (-O2) +disco_f411.menu.opt.o2std.build.flags.optimize=-O2 +disco_f411.menu.opt.o2std.build.flags.ldspecs= +disco_f411.menu.opt.o2lto=Faster (-O2) with LTO +disco_f411.menu.opt.o2lto.build.flags.optimize=-O2 -flto +disco_f411.menu.opt.o2lto.build.flags.ldspecs=-flto +disco_f411.menu.opt.o3std=Fastest (-O3) +disco_f411.menu.opt.o3std.build.flags.optimize=-O3 +disco_f411.menu.opt.o3std.build.flags.ldspecs= +disco_f411.menu.opt.o3lto=Fastest (-O3) with LTO +disco_f411.menu.opt.o3lto.build.flags.optimize=-O3 -flto +disco_f411.menu.opt.o3lto.build.flags.ldspecs=-flto +disco_f411.menu.opt.ogstd=Debug (-g) +disco_f411.menu.opt.ogstd.build.flags.optimize=-Og +disco_f411.menu.opt.ogstd.build.flags.ldspecs= +############################################################## +generic_f407v.name=Generic STM32F407V series generic_f407v.upload.file_type=bin generic_f407v.upload.maximum_size=514288 @@ -82,25 +234,18 @@ generic_f407v.upload.maximum_data_size=131072 #generic_f407v.upload.altID=1 #generic_f407v.upload.auto_reset=true -generic_f407v.build.mcu=cortex-m4 -generic_f407v.build.f_cpu=168000000L generic_f407v.build.core=maple -generic_f407v.build.extra_flags=-mthumb -DSTM32_HIGH_DENSITY -DSTM32F4 -DBOARD_generic_f407v -generic_f407v.build.ldscript=ld/jtag.ld +generic_f407v.build.f_cpu=168000000 +generic_f407v.build.extra_flags= -DCRYSTAL_FREQ=8 -DLED_BUILTIN=PA6 generic_f407v.build.variant=generic_f407v generic_f407v.build.variant_system_lib=lib_f407.a -generic_f407v.build.vect=VECT_TAB_BASE -generic_f407v.build.density=STM32_HIGH_DENSITY -generic_f407v.build.error_led_port=GPIOA -generic_f407v.build.error_led_pin=7 -generic_f407v.build.board=STM32GenericF407VET6 -generic_f407v.build.vect_flags=-DVECT_TAB_FLASH -DUSER_ADDR_ROM=(uint32)0x08000000 - -generic_f407v.menu.usb_cfg.usb_nc=USB inactive -generic_f407v.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC +generic_f407v.build.error_led_pin=PA7 +generic_f407v.build.board=generic_f407v generic_f407v.menu.usb_cfg.usb_serial=USB serial (CDC) generic_f407v.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB +generic_f407v.menu.usb_cfg.usb_nc=USB inactive +generic_f407v.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC generic_f407v.menu.usb_cfg.usb_msc=USB Mass Storage (MSC) generic_f407v.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC @@ -109,26 +254,17 @@ generic_f407v.menu.upload_method.STLinkMethod=STLink generic_f407v.menu.upload_method.STLinkMethod.upload.protocol=STLink generic_f407v.menu.upload_method.STLinkMethod.upload.tool=stlink_upload generic_f407v.menu.upload_method.STLinkMethod.upload.dfuse_addr=0x08004000 -generic_f407v.menu.upload_method.STLinkMethod.build.vect_flags=-DVECT_TAB_FLASH -DUSER_ADDR_ROM=(uint32)0x08000000 - - -generic_f407v.menu.upload_method.DFUUploadMethod=STM32duino bootloader -generic_f407v.menu.upload_method.DFUUploadMethod.upload.protocol=maple_dfu -generic_f407v.menu.upload_method.DFUUploadMethod.upload.tool=maple_upload -generic_f407v.menu.upload_method.DFUUploadMethod.build.vect_flags=-DVECT_TAB_FLASH -DUSER_ADDR_ROM=(uint32)0x08004000 -generic_f407v.menu.upload_method.DFUUploadMethod.build.ldscript=ld/bootloader_8004000.ld -generic_f407v.menu.upload_method.DFUUploadMethod.upload.usbID=1EAF:0003 -generic_f407v.menu.upload_method.DFUUploadMethod.upload.altID=2 - - - - +generic_f407v.menu.upload_method.STLinkMethod.build.vect_flags=-DUSER_ADDR_ROM=0x08000000 +generic_f407v.menu.upload_method.STLinkMethod.build.ldscript=ld/jtag.ld +generic_f407v.menu.upload_method.HIDUploadMethod=HID bootloader 2.0 +generic_f407v.menu.upload_method.HIDUploadMethod.upload.protocol=hid_boot +generic_f407v.menu.upload_method.HIDUploadMethod.upload.tool=hid_upload +generic_f407v.menu.upload_method.HIDUploadMethod.build.vect_flags=-DUSER_ADDR_ROM=0x08004000 +generic_f407v.menu.upload_method.HIDUploadMethod.build.ldscript=ld/bootloader_8004000.ld #-- Optimizations generic_f407v.menu.opt.osstd=Smallest (default) -generic_f407v.menu.opt.osstd.build.flags.optimize=-Os -generic_f407v.menu.opt.osstd.build.flags.ldspecs= generic_f407v.menu.opt.oslto=Smallest Code with LTO generic_f407v.menu.opt.oslto.build.flags.optimize=-Os -flto generic_f407v.menu.opt.oslto.build.flags.ldspecs=-flto @@ -154,133 +290,134 @@ generic_f407v.menu.opt.ogstd=Debug (-g) generic_f407v.menu.opt.ogstd.build.flags.optimize=-Og generic_f407v.menu.opt.ogstd.build.flags.ldspecs= ############################################################## -stm32f4stamp.name=STM32F4Stamp F405 - -stm32f4stamp.upload.tool=maple_upload -stm32f4stamp.upload.protocol=maple_dfu - -#stm32f4stamp.upload.use_1200bps_touch=false -stm32f4stamp.upload.file_type=bin -stm32f4stamp.upload.maximum_size=1048576 -stm32f4stamp.upload.maximum_data_size=131072 - -stm32f4stamp.upload.usbID=0483:df11 -stm32f4stamp.upload.altID=0 -#stm32f4stamp.upload.auto_reset=true -stm32f4stamp.upload.dfuse_addr=0x8000000 - -stm32f4stamp.build.mcu=cortex-m4 -stm32f4stamp.build.f_cpu=168000000L -stm32f4stamp.build.core=maple -stm32f4stamp.build.extra_flags=-DMCU_STM32F406VG -mthumb -DSTM32_HIGH_DENSITY -DSTM32F4 -DBOARD_discovery_f4 -stm32f4stamp.build.ldscript=ld/jtag.ld -stm32f4stamp.build.variant=discovery_f407 -stm32f4stamp.build.variant_system_lib=lib_f407.a -stm32f4stamp.build.vect=VECT_TAB_BASE -stm32f4stamp.build.density=STM32_HIGH_DENSITY -stm32f4stamp.build.error_led_port=GPIOD -stm32f4stamp.build.error_led_pin=14 -stm32f4stamp.build.board=STM32F4StampF405 -stm32f4stamp.build.vect_flags=-DVECT_TAB_FLASH -DUSER_ADDR_ROM=(uint32)0x08000000 - -stm32f4stamp.menu.usb_cfg.usb_nc=USB inactive -stm32f4stamp.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC -stm32f4stamp.menu.usb_cfg.usb_serial=USB serial (CDC) -stm32f4stamp.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB -stm32f4stamp.menu.usb_cfg.usb_msc=USB Mass Storage (MSC) -stm32f4stamp.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC +generic_f407v_mini.name=Generic STM32F407V mini series + +generic_f407v_mini.upload.file_type=bin +generic_f407v_mini.upload.maximum_size=514288 +generic_f407v_mini.upload.maximum_data_size=131072 + +#generic_f407v_mini.upload.usbID=0483:3748 +#generic_f407v_mini.upload.altID=1 +#generic_f407v_mini.upload.auto_reset=true + +generic_f407v_mini.build.core=maple +generic_f407v_mini.build.f_cpu=168000000 +generic_f407v_mini.build.extra_flags= -DCRYSTAL_FREQ=25 -DLED_BUILTIN=PB9 +generic_f407v_mini.build.ldscript=ld/jtag.ld +generic_f407v_mini.build.variant=generic_f407v +generic_f407v_mini.build.variant_system_lib=lib_f407.a +generic_f407v_mini.build.error_led_pin=PB9 +generic_f407v_mini.build.board=generic_f407v_mini + +generic_f407v_mini.menu.usb_cfg.usb_serial=USB serial (CDC) +generic_f407v_mini.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB +generic_f407v_mini.menu.usb_cfg.usb_nc=USB inactive +generic_f407v_mini.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC +generic_f407v_mini.menu.usb_cfg.usb_msc=USB Mass Storage (MSC) +generic_f407v_mini.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC + +#note STLink is the default from the main block of config above, so does not need settings for everything +generic_f407v_mini.menu.upload_method.STLinkMethod=STLink +generic_f407v_mini.menu.upload_method.STLinkMethod.upload.protocol=STLink +generic_f407v_mini.menu.upload_method.STLinkMethod.upload.tool=stlink_upload +generic_f407v_mini.menu.upload_method.STLinkMethod.upload.dfuse_addr=0x08004000 +generic_f407v_mini.menu.upload_method.STLinkMethod.build.vect_flags=-DUSER_ADDR_ROM=0x08000000 + +generic_f407v_mini.menu.upload_method.HIDUploadMethod=HID bootloader 2.0 +generic_f407v_mini.menu.upload_method.HIDUploadMethod.upload.protocol=hid_boot +generic_f407v_mini.menu.upload_method.HIDUploadMethod.upload.tool=hid_upload +generic_f407v_mini.menu.upload_method.HIDUploadMethod.build.vect_flags=-DUSER_ADDR_ROM=0x08004000 +generic_f407v_mini.menu.upload_method.HIDUploadMethod.build.ldscript=ld/bootloader_8004000.ld #-- Optimizations -stm32f4stamp.menu.opt.osstd=Smallest (default) -stm32f4stamp.menu.opt.osstd.build.flags.optimize=-Os -stm32f4stamp.menu.opt.osstd.build.flags.ldspecs= -stm32f4stamp.menu.opt.oslto=Smallest Code with LTO -stm32f4stamp.menu.opt.oslto.build.flags.optimize=-Os -flto -stm32f4stamp.menu.opt.oslto.build.flags.ldspecs=-flto -stm32f4stamp.menu.opt.o1std=Fast (-O1) -stm32f4stamp.menu.opt.o1std.build.flags.optimize=-O1 -stm32f4stamp.menu.opt.o1std.build.flags.ldspecs= -stm32f4stamp.menu.opt.o1lto=Fast (-O1) with LTO -stm32f4stamp.menu.opt.o1lto.build.flags.optimize=-O1 -flto -stm32f4stamp.menu.opt.o1lto.build.flags.ldspecs=-flto -stm32f4stamp.menu.opt.o2std=Faster (-O2) -stm32f4stamp.menu.opt.o2std.build.flags.optimize=-O2 -stm32f4stamp.menu.opt.o2std.build.flags.ldspecs= -stm32f4stamp.menu.opt.o2lto=Faster (-O2) with LTO -stm32f4stamp.menu.opt.o2lto.build.flags.optimize=-O2 -flto -stm32f4stamp.menu.opt.o2lto.build.flags.ldspecs=-flto -stm32f4stamp.menu.opt.o3std=Fastest (-O3) -stm32f4stamp.menu.opt.o3std.build.flags.optimize=-O3 -stm32f4stamp.menu.opt.o3std.build.flags.ldspecs= -stm32f4stamp.menu.opt.o3lto=Fastest (-O3) with LTO -stm32f4stamp.menu.opt.o3lto.build.flags.optimize=-O3 -flto -stm32f4stamp.menu.opt.o3lto.build.flags.ldspecs=-flto -stm32f4stamp.menu.opt.ogstd=Debug (-g) -stm32f4stamp.menu.opt.ogstd.build.flags.optimize=-Og -stm32f4stamp.menu.opt.ogstd.build.flags.ldspecs= +generic_f407v_mini.menu.opt.osstd=Smallest (default) +generic_f407v_mini.menu.opt.osstd.build.flags.optimize=-Os +generic_f407v_mini.menu.opt.osstd.build.flags.ldspecs= +generic_f407v_mini.menu.opt.oslto=Smallest Code with LTO +generic_f407v_mini.menu.opt.oslto.build.flags.optimize=-Os -flto +generic_f407v_mini.menu.opt.oslto.build.flags.ldspecs=-flto +generic_f407v_mini.menu.opt.o1std=Fast (-O1) +generic_f407v_mini.menu.opt.o1std.build.flags.optimize=-O1 +generic_f407v_mini.menu.opt.o1std.build.flags.ldspecs= +generic_f407v_mini.menu.opt.o1lto=Fast (-O1) with LTO +generic_f407v_mini.menu.opt.o1lto.build.flags.optimize=-O1 -flto +generic_f407v_mini.menu.opt.o1lto.build.flags.ldspecs=-flto +generic_f407v_mini.menu.opt.o2std=Faster (-O2) +generic_f407v_mini.menu.opt.o2std.build.flags.optimize=-O2 +generic_f407v_mini.menu.opt.o2std.build.flags.ldspecs= +generic_f407v_mini.menu.opt.o2lto=Faster (-O2) with LTO +generic_f407v_mini.menu.opt.o2lto.build.flags.optimize=-O2 -flto +generic_f407v_mini.menu.opt.o2lto.build.flags.ldspecs=-flto +generic_f407v_mini.menu.opt.o3std=Fastest (-O3) +generic_f407v_mini.menu.opt.o3std.build.flags.optimize=-O3 +generic_f407v_mini.menu.opt.o3std.build.flags.ldspecs= +generic_f407v_mini.menu.opt.o3lto=Fastest (-O3) with LTO +generic_f407v_mini.menu.opt.o3lto.build.flags.optimize=-O3 -flto +generic_f407v_mini.menu.opt.o3lto.build.flags.ldspecs=-flto +generic_f407v_mini.menu.opt.ogstd=Debug (-g) +generic_f407v_mini.menu.opt.ogstd.build.flags.optimize=-Og +generic_f407v_mini.menu.opt.ogstd.build.flags.ldspecs= ############################################################## -netduino2plus.name=Netduino2 F405 - -netduino2plus.upload.tool=maple_upload -netduino2plus.upload.protocol=maple_dfu - -#netduino2plus.upload.use_1200bps_touch=false -netduino2plus.upload.file_type=bin -netduino2plus.upload.maximum_size=1048576 -netduino2plus.upload.maximum_data_size=131072 - -netduino2plus.upload.usbID=0483:df11 -netduino2plus.upload.altID=0 -#netduino2plus.upload.auto_reset=true -netduino2plus.upload.dfuse_addr=0x8000000 - -netduino2plus.build.mcu=cortex-m4 -netduino2plus.build.f_cpu=168000000L -netduino2plus.build.core=maple -netduino2plus.build.extra_flags=-DMCU_STM32F406VG -mthumb -DSTM32_HIGH_DENSITY -DSTM32F4 -DBOARD_discovery_f4 -DARDUINO_STM32F4_NETDUINO2PLUS -netduino2plus.build.ldscript=ld/jtag.ld -netduino2plus.build.variant=discovery_f407 -netduino2plus.build.variant_system_lib=lib_f407.a -netduino2plus.build.vect=VECT_TAB_BASE -netduino2plus.build.density=STM32_HIGH_DENSITY -netduino2plus.build.error_led_port=GPIOD -netduino2plus.build.error_led_pin=14 -netduino2plus.build.board=Netduino2F405 - -netduino2plus.menu.usb_cfg.usb_nc=USB inactive -netduino2plus.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC -netduino2plus.menu.usb_cfg.usb_serial=USB serial (CDC) -netduino2plus.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB -netduino2plus.menu.usb_cfg.usb_msc=USB Mass Storage (MSC) -netduino2plus.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC +arch_max.name=Seeed Arch Max 1.1 + +arch_max.upload.file_type=bin +arch_max.upload.maximum_size=514288 +arch_max.upload.maximum_data_size=131072 + +arch_max.build.core=maple +arch_max.build..f_cpu=168000000 +arch_max.build.extra_flags= -DCRYSTAL_FREQ=8 -DLED_BUILTIN=PB3 +arch_max.build.variant=arch_max +arch_max.build.variant_system_lib=lib_f407.a +arch_max.build.error_led_pin=PB3 +arch_max.build.board=arch_max + +arch_max.menu.usb_cfg.usb_serial=USB serial (CDC) +arch_max.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB +arch_max.menu.usb_cfg.usb_nc=USB inactive +arch_max.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC +arch_max.menu.usb_cfg.usb_msc=USB Mass Storage (MSC) +arch_max.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC + +#note STLink is the default from the main block of config above, so does not need settings for everything +arch_max.menu.upload_method.STLinkMethod=STLink +arch_max.menu.upload_method.STLinkMethod.upload.protocol=STLink +arch_max.menu.upload_method.STLinkMethod.upload.tool=stlink_upload +arch_max.menu.upload_method.STLinkMethod.upload.dfuse_addr=0x08004000 +arch_max.menu.upload_method.STLinkMethod.build.vect_flags=-DUSER_ADDR_ROM=0x08000000 +arch_max.menu.upload_method.STLinkMethod.build.ldscript=ld/jtag.ld + +arch_max.menu.upload_method.HIDUploadMethod=HID bootloader 2.0 +arch_max.menu.upload_method.HIDUploadMethod.upload.protocol=hid_boot +arch_max.menu.upload_method.HIDUploadMethod.upload.tool=hid_upload +arch_max.menu.upload_method.HIDUploadMethod.build.vect_flags=-DUSER_ADDR_ROM=0x08004000 +arch_max.menu.upload_method.HIDUploadMethod.build.ldscript=ld/bootloader_8004000.ld #-- Optimizations -netduino2plus.menu.opt.osstd=Smallest (default) -netduino2plus.menu.opt.osstd.build.flags.optimize=-Os -netduino2plus.menu.opt.osstd.build.flags.ldspecs= -netduino2plus.menu.opt.oslto=Smallest Code with LTO -netduino2plus.menu.opt.oslto.build.flags.optimize=-Os -flto -netduino2plus.menu.opt.oslto.build.flags.ldspecs=-flto -netduino2plus.menu.opt.o1std=Fast (-O1) -netduino2plus.menu.opt.o1std.build.flags.optimize=-O1 -netduino2plus.menu.opt.o1std.build.flags.ldspecs= -netduino2plus.menu.opt.o1lto=Fast (-O1) with LTO -netduino2plus.menu.opt.o1lto.build.flags.optimize=-O1 -flto -netduino2plus.menu.opt.o1lto.build.flags.ldspecs=-flto -netduino2plus.menu.opt.o2std=Faster (-O2) -netduino2plus.menu.opt.o2std.build.flags.optimize=-O2 -netduino2plus.menu.opt.o2std.build.flags.ldspecs= -netduino2plus.menu.opt.o2lto=Faster (-O2) with LTO -netduino2plus.menu.opt.o2lto.build.flags.optimize=-O2 -flto -netduino2plus.menu.opt.o2lto.build.flags.ldspecs=-flto -netduino2plus.menu.opt.o3std=Fastest (-O3) -netduino2plus.menu.opt.o3std.build.flags.optimize=-O3 -netduino2plus.menu.opt.o3std.build.flags.ldspecs= -netduino2plus.menu.opt.o3lto=Fastest (-O3) with LTO -netduino2plus.menu.opt.o3lto.build.flags.optimize=-O3 -flto -netduino2plus.menu.opt.o3lto.build.flags.ldspecs=-flto -netduino2plus.menu.opt.ogstd=Debug (-g) -netduino2plus.menu.opt.ogstd.build.flags.optimize=-Og -netduino2plus.menu.opt.ogstd.build.flags.ldspecs= +arch_max.menu.opt.osstd=Smallest (default) +arch_max.menu.opt.oslto=Smallest Code with LTO +arch_max.menu.opt.oslto.build.flags.optimize=-Os -flto +arch_max.menu.opt.oslto.build.flags.ldspecs=-flto +arch_max.menu.opt.o1std=Fast (-O1) +arch_max.menu.opt.o1std.build.flags.optimize=-O1 +arch_max.menu.opt.o1std.build.flags.ldspecs= +arch_max.menu.opt.o1lto=Fast (-O1) with LTO +arch_max.menu.opt.o1lto.build.flags.optimize=-O1 -flto +arch_max.menu.opt.o1lto.build.flags.ldspecs=-flto +arch_max.menu.opt.o2std=Faster (-O2) +arch_max.menu.opt.o2std.build.flags.optimize=-O2 +arch_max.menu.opt.o2std.build.flags.ldspecs= +arch_max.menu.opt.o2lto=Faster (-O2) with LTO +arch_max.menu.opt.o2lto.build.flags.optimize=-O2 -flto +arch_max.menu.opt.o2lto.build.flags.ldspecs=-flto +arch_max.menu.opt.o3std=Fastest (-O3) +arch_max.menu.opt.o3std.build.flags.optimize=-O3 +arch_max.menu.opt.o3std.build.flags.ldspecs= +arch_max.menu.opt.o3lto=Fastest (-O3) with LTO +arch_max.menu.opt.o3lto.build.flags.optimize=-O3 -flto +arch_max.menu.opt.o3lto.build.flags.ldspecs=-flto +arch_max.menu.opt.ogstd=Debug (-g) +arch_max.menu.opt.ogstd.build.flags.optimize=-Og +arch_max.menu.opt.ogstd.build.flags.ldspecs= ############################################################## diff --git a/STM32F4/cores/maple/HardwareTimer.cpp b/STM32F4/cores/maple/HardwareTimer.cpp index 08e73d5f0..3193d71b7 100644 --- a/STM32F4/cores/maple/HardwareTimer.cpp +++ b/STM32F4/cores/maple/HardwareTimer.cpp @@ -26,77 +26,27 @@ #include "HardwareTimer.h" #include "boards.h" // for CYCLES_PER_MICROSECOND -#include "wirish_math.h" -// TODO [0.1.0] Remove deprecated pieces - -#ifdef STM32_MEDIUM_DENSITY -#define NR_TIMERS 4 -#elif defined(STM32_HIGH_DENSITY) -#define NR_TIMERS 8 -#else -#error "Unsupported density" -#endif #define MAX_RELOAD ((1 << 16) - 1) -HardwareTimer::HardwareTimer(uint8 timerNum) { - if (timerNum > NR_TIMERS) { - ASSERT(0); - } - timer_dev *devs[] = { - TIMER1, - TIMER2, - TIMER3, - TIMER4, -#ifdef STM32_HIGH_DENSITY - TIMER5, - TIMER6, - TIMER7, - TIMER8, -#endif - }; - this->dev = devs[timerNum - 1]; -} - -void HardwareTimer::pause(void) { - timer_pause(this->dev); -} +#define NR_TIMERS 14 -void HardwareTimer::resume(void) { - timer_resume(this->dev); -} -uint32 HardwareTimer::getPrescaleFactor(void) { - return timer_get_prescaler(this->dev) + 1; -} +/* + * HardwareTimer routines + */ -uint32 HardwareTimer::getClockSpeed(void) { - return rcc_dev_timer_clk_speed(this->dev->clk_id); -} - -void HardwareTimer::setPrescaleFactor(uint32 factor) { - timer_set_prescaler(this->dev, (uint16)(factor - 1)); -} - -uint16 HardwareTimer::getOverflow() { - return timer_get_reload(this->dev); -} - -void HardwareTimer::setOverflow(uint16 val) { - timer_set_reload(this->dev, val); -} - -uint16 HardwareTimer::getCount(void) { - return timer_get_count(this->dev); -} - -void HardwareTimer::setCount(uint16 val) { - uint16 ovf = this->getOverflow(); - timer_set_count(this->dev, min(val, ovf)); +HardwareTimer::HardwareTimer(uint8 timerNum) +{ + if (timerNum > NR_TIMERS && timerNum==0) { + ASSERT(0); + } + this->dev = timer_devices[timerNum]; } -uint16 HardwareTimer::setPeriod(uint32 microseconds) { +uint16 HardwareTimer::setPeriod(uint32 microseconds) +{ // Not the best way to handle this edge case? if (!microseconds) { this->setPrescaleFactor(1); @@ -106,46 +56,32 @@ uint16 HardwareTimer::setPeriod(uint32 microseconds) { uint32 period_cyc = microseconds * CYCLES_PER_MICROSECOND; uint16 prescaler = (uint16)(period_cyc / MAX_RELOAD + 1); - uint16 overflow = (uint16)round(period_cyc / prescaler); + uint16 overflow = (uint16)((period_cyc + (prescaler / 2)) / prescaler); this->setPrescaleFactor(prescaler); this->setOverflow(overflow); return overflow; } -void HardwareTimer::setMode(int channel, timer_mode mode) { - timer_set_mode(this->dev, (uint8)channel, (timer_mode)mode); -} - -uint16 HardwareTimer::getCompare(int channel) { - return timer_get_compare(this->dev, (uint8)channel); +void HardwareTimer::setMasterModeTrGo(uint32_t mode) +{ + this->dev->regs.bas->CR2 &= ~TIMER_CR2_MMS; + this->dev->regs.bas->CR2 |= mode; } -void HardwareTimer::setCompare(int channel, uint16 val) { - uint16 ovf = this->getOverflow(); - timer_set_compare(this->dev, (uint8)channel, min(val, ovf)); -} - -void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) { - timer_attach_interrupt(this->dev, (uint8)channel, handler); -} - -void HardwareTimer::detachInterrupt(int channel) { - timer_detach_interrupt(this->dev, (uint8)channel); -} - -void HardwareTimer::refresh(void) { - timer_generate_update(this->dev); -} -/* -- Deprecated predefined instances -------------------------------------- */ +// Predefined instances HardwareTimer Timer1(1); HardwareTimer Timer2(2); HardwareTimer Timer3(3); HardwareTimer Timer4(4); -#ifdef STM32_HIGH_DENSITY HardwareTimer Timer5(5); HardwareTimer Timer6(6); HardwareTimer Timer7(7); HardwareTimer Timer8(8); -#endif +HardwareTimer Timer9(9); +HardwareTimer Timer10(10); +HardwareTimer Timer11(11); +HardwareTimer Timer12(12); +HardwareTimer Timer13(13); +HardwareTimer Timer14(14); diff --git a/STM32F4/cores/maple/HardwareTimer.h b/STM32F4/cores/maple/HardwareTimer.h index c90356bf6..107a3b392 100644 --- a/STM32F4/cores/maple/HardwareTimer.h +++ b/STM32F4/cores/maple/HardwareTimer.h @@ -33,20 +33,20 @@ // TODO [0.1.0] Remove deprecated pieces, pick a better API -#include +#include "libmaple/timer.h" +#include "wirish_math.h" /** Timer mode. */ typedef timer_mode TimerMode; -/** @brief Deprecated; use TIMER_OUTPUT_COMPARE instead. */ -#define TIMER_OUTPUTCOMPARE TIMER_OUTPUT_COMPARE /** * @brief Interface to one of the 16-bit timer peripherals. */ -class HardwareTimer { +class HardwareTimer +{ private: - timer_dev *dev; + const timer_dev *dev; public: /** @@ -54,13 +54,15 @@ class HardwareTimer { * @param timerNum number of the timer to control. */ HardwareTimer(uint8 timerNum); + void init(void) { timer_init(this->dev); timer_pause(this->dev); } + /** * @brief Stop the counter, without affecting its configuration. * * @see HardwareTimer::resume() */ - void pause(void); + void pause(void) { timer_pause(this->dev); } /** * @brief Resume a paused timer, without affecting its configuration. @@ -75,20 +77,22 @@ class HardwareTimer { * * @see HardwareTimer::pause() */ - void resume(void); + void resume(void) { timer_resume(this->dev); } /** * @brief Get the timer's clock speed. * @return Timer input clock speed in Hz/second */ - uint32 getClockSpeed(void); + uint32 getClockSpeed(void) { + return rcc_dev_timer_clk_speed(this->dev->clk_id); + } /** * @brief Get the timer's prescale factor. * @return Timer prescaler, from 1 to 65,536. * @see HardwareTimer::setPrescaleFactor() */ - uint32 getPrescaleFactor(); + uint32 getPrescaleFactor() { return timer_get_prescaler(this->dev) + 1; } /** * @brief Set the timer's prescale factor. @@ -100,13 +104,13 @@ class HardwareTimer { * @param factor The new prescale value to set, from 1 to 65,536. * @see HardwareTimer::refresh() */ - void setPrescaleFactor(uint32 factor); + void setPrescaleFactor(uint32 factor) { timer_set_prescaler(this->dev, (uint16)(factor - 1)); } /** * @brief Get the timer overflow value. * @see HardwareTimer::setOverflow() */ - uint16 getOverflow(); + uint16 getOverflow() { return timer_get_reload(this->dev); } /** * @brief Set the timer overflow (or "reload") value. @@ -118,14 +122,14 @@ class HardwareTimer { * @param val The new overflow value to set * @see HardwareTimer::refresh() */ - void setOverflow(uint16 val); + void setOverflow(uint16 val) { timer_set_reload(this->dev, val); } /** * @brief Get the current timer count. * * @return The timer's current count value */ - uint16 getCount(void); + uint16 getCount(void) { return timer_get_count(this->dev); } /** * @brief Set the current timer count. @@ -134,7 +138,7 @@ class HardwareTimer { * the timer's overflow value, it is truncated to the * overflow value. */ - void setCount(uint16 val); + void setCount(uint16 val) { timer_set_count(this->dev, min(val, this->getOverflow())); } /** * @brief Set the timer's period in microseconds. @@ -149,18 +153,22 @@ class HardwareTimer { */ uint16 setPeriod(uint32 microseconds); + void setMasterMode(timer_mms_t mode) { + timer_set_master_mode(this->dev, mode); + } + /** * @brief Configure a timer channel's mode. * @param channel Timer channel, from 1 to 4 * @param mode Mode to set */ - void setMode(int channel, timer_mode mode); + void setMode(int channel, timer_mode mode) { timer_set_mode(this->dev, channel, mode); } /** * @brief Get the compare value for the given channel. * @see HardwareTimer::setCompare() */ - uint16 getCompare(int channel); + uint16 getCompare(int channel) { return timer_get_compare(this->dev, channel); } /** * @brief Set the compare value for the given channel. @@ -174,7 +182,9 @@ class HardwareTimer { * @see HardwareTimer::setMode() * @see HardwareTimer::attachInterrupt() */ - void setCompare(int channel, uint16 compare); + void setCompare(uint8 channel, uint16 val) { + timer_set_compare(this->dev, channel, min(val, this->getOverflow())); + } /** * @brief Attach an interrupt handler to the given channel. @@ -182,11 +192,14 @@ class HardwareTimer { * This interrupt handler will be called when the timer's counter * reaches the given channel compare value. * - * @param channel the channel to attach the ISR to, from 1 to 4. + * @param channel the channel to attach the ISR to, from 0 to 4. + * Channel 0 is for overflow interrupt (update interrupt). * @param handler The ISR to attach to the given channel. * @see voidFuncPtr */ - void attachInterrupt(int channel, voidFuncPtr handler); + void attachInterrupt(uint8 channel, voidFuncPtr handler) { + timer_attach_interrupt(this->dev, channel, handler); + } /** * @brief Remove the interrupt handler attached to the given @@ -194,10 +207,13 @@ class HardwareTimer { * * The handler will no longer be called by this timer. * - * @param channel the channel whose interrupt to detach, from 1 to 4. + * @param channel the channel whose interrupt to detach, from 0 to 4. + * Channel 0 is for overflow interrupt (update interrupt). * @see HardwareTimer::attachInterrupt() */ - void detachInterrupt(int channel); + void detachInterrupt(uint8 channel) { + timer_detach_interrupt(this->dev, (uint8)channel); + } /** * @brief Reset the counter, and update the prescaler and overflow @@ -212,126 +228,97 @@ class HardwareTimer { * @see HardwareTimer::setPrescaleFactor() * @see HardwareTimer::setOverflow() */ - void refresh(void); - - /* -- Deprecated methods ----------------------------------------------- */ - - /** @brief Deprecated; use setMode(channel, mode) instead. */ - void setChannelMode(int channel, timer_mode mode) { - setMode(channel, mode); - } - - /** @brief Deprecated; use setMode(TIMER_CH1, mode) instead. */ - void setChannel1Mode(timer_mode mode) { setMode(TIMER_CH1, mode); } - - /** @brief Deprecated; use setMode(TIMER_CH2, mode) instead. */ - void setChannel2Mode(timer_mode mode) { setMode(TIMER_CH2, mode); } + void refresh(void) { timer_generate_update(this->dev); } - /** @brief Deprecated; use setMode(TIMER_CH3, mode) instead. */ - void setChannel3Mode(timer_mode mode) { setMode(TIMER_CH3, mode); } - - /** @brief Deprecated; use setMode(TIMER_CH4, mode) instead. */ - void setChannel4Mode(timer_mode mode) { setMode(TIMER_CH4, mode); } - - /** @brief Deprecated; use return getCompare(TIMER_CH1) instead. */ - uint16 getCompare1() { return getCompare(TIMER_CH1); } - - /** @brief Deprecated; use return getCompare(TIMER_CH2) instead. */ - uint16 getCompare2() { return getCompare(TIMER_CH2); } - - /** @brief Deprecated; use return getCompare(TIMER_CH3) instead. */ - uint16 getCompare3() { return getCompare(TIMER_CH3); } - - /** @brief Deprecated; use return getCompare(TIMER_CH4) instead. */ - uint16 getCompare4() { return getCompare(TIMER_CH4); } + // SYFRE + /** + * @brief Set the Master mode TRGO signal + * These bits allow to select the information to be sent in master mode to slave timers for + * synchronization (TRGO). + * mode: + * TIMER_CR2_MMS_RESET + * TIMER_CR2_MMS_ENABLE + * TIMER_CR2_MMS_UPDATE + * TIMER_CR2_MMS_COMPARE_PULSE + * TIMER_CR2_MMS_COMPARE_OC1REF + * TIMER_CR2_MMS_COMPARE_OC2REF + * TIMER_CR2_MMS_COMPARE_OC3REF + * TIMER_CR2_MMS_COMPARE_OC4REF + */ + void setMasterModeTrGo(uint32_t mode); - /** @brief Deprecated; use setCompare(TIMER_CH1, compare) instead. */ - void setCompare1(uint16 compare) { setCompare(TIMER_CH1, compare); } + void setSlaveFlags(uint32 flags) { ((this->dev)->regs).gen->SMCR = flags; } - /** @brief Deprecated; use setCompare(TIMER_CH2, compare) instead. */ - void setCompare2(uint16 compare) { setCompare(TIMER_CH2, compare); } +//CARLOS. +/* + added these functions to make sense for the encoder mode. +*/ +//direction of movement. (to be better described). + uint8 getDirection() { return get_direction(this->dev); } - /** @brief Deprecated; use setCompare(TIMER_CH3, compare) instead. */ - void setCompare3(uint16 compare) { setCompare(TIMER_CH3, compare); } +//set if the encoder will count edges on one, which or both channels. + void setEdgeCounting(uint32 counting) { setSlaveFlags(counting); } - /** @brief Deprecated; use setCompare(TIMER_CH4, compare) instead. */ - void setCompare4(uint16 compare) { setCompare(TIMER_CH4, compare); } +//set the polarity of counting... not sure how interesting this is.. + void setPolarity(timer_channel channel, uint8 pol) { + timer_cc_set_pol(this->dev, channel, pol); + } - /** @brief Deprecated; use attachInterrupt(TIMER_CH1, handler) instead. */ - void attachCompare1Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH1, handler); + uint8_t getPolarity(timer_channel channel) { + return timer_cc_get_pol(this->dev, channel); } - /** @brief Deprecated; use attachInterrupt(TIMER_CH2, handler) instead. */ - void attachCompare2Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH2, handler); + void setInputCaptureMode(timer_channel channel, timer_ic_input_select input) { + input_capture_mode(this->dev, channel, input); } - /** @brief Deprecated; use attachInterrupt(TIMER_CH3, handler) instead. */ - void attachCompare3Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH3, handler); + uint8_t getInputCaptureFlag(timer_channel channel) { + return ( timer_get_status(this->dev) >> channel ) & 0x1; } - /** @brief Deprecated; use attachInterrupt(TIMER_CH4, handler) instead. */ - void attachCompare4Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH4, handler); + uint8_t getInputCaptureFlagOverflow(timer_channel channel) { + uint8 ret = ( timer_get_status(this->dev) >> (8+channel) ) & 0x1; + if ( ret ) timer_reset_status_bit(this->dev, (8+channel)); // clear flag + return ret; } - /** @brief Deprecated; use detachInterrupt(TIMER_CH1) instead. */ - void detachCompare1Interrupt(void) { detachInterrupt(TIMER_CH1); } + /** + * @brief Enable/disable DMA request for the input channel. + */ + void enableDMA(timer_channel channel) { timer_dma_enable_req(this->dev, channel); } - /** @brief Deprecated; use detachInterrupt(TIMER_CH2) instead. */ - void detachCompare2Interrupt(void) { detachInterrupt(TIMER_CH2); } + void disableDMA(timer_channel channel) { timer_dma_disable_req(this->dev, channel); } - /** @brief Deprecated; use detachInterrupt(TIMER_CH3) instead. */ - void detachCompare3Interrupt(void) { detachInterrupt(TIMER_CH3); } - /** @brief Deprecated; use detachInterrupt(TIMER_CH4) instead. */ - void detachCompare4Interrupt(void) { detachInterrupt(TIMER_CH4); } + /** + * @brief Get a pointer to the underlying libmaple timer_dev for + * this HardwareTimer instance. + */ + const timer_dev* c_dev(void) { return this->dev; } + - /** @brief Deprecated; use refresh() instead. */ - void generateUpdate(void) { refresh(); } }; -/* -- The rest of this file is deprecated. --------------------------------- */ /** * @brief Deprecated. * - * Pre-instantiated timer. + * Pre-instantiated timer instances. */ extern HardwareTimer Timer1; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ extern HardwareTimer Timer2; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ extern HardwareTimer Timer3; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ extern HardwareTimer Timer4; -#ifdef STM32_HIGH_DENSITY -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ extern HardwareTimer Timer5; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ +extern HardwareTimer Timer6; +extern HardwareTimer Timer7; extern HardwareTimer Timer8; -#endif +extern HardwareTimer Timer9; +extern HardwareTimer Timer10; +extern HardwareTimer Timer11; +extern HardwareTimer Timer12; +extern HardwareTimer Timer13; +extern HardwareTimer Timer14; + #endif diff --git a/STM32F4/cores/maple/IPAddress.cpp b/STM32F4/cores/maple/IPAddress.cpp index 297307e58..e38bfd5ed 100644 --- a/STM32F4/cores/maple/IPAddress.cpp +++ b/STM32F4/cores/maple/IPAddress.cpp @@ -34,14 +34,12 @@ IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_oc _address.bytes[3] = fourth_octet; } -IPAddress::IPAddress(uint32_t address) -{ - _address.dword = address; -} - IPAddress::IPAddress(const uint8_t *address) { - memcpy(_address.bytes, address, sizeof(_address.bytes)); + _address.bytes[0] = address[0]; + _address.bytes[1] = address[1]; + _address.bytes[2] = address[2]; + _address.bytes[3] = address[3]; } bool IPAddress::fromString(const char *address) @@ -88,7 +86,10 @@ bool IPAddress::fromString(const char *address) IPAddress& IPAddress::operator=(const uint8_t *address) { - memcpy(_address.bytes, address, sizeof(_address.bytes)); + _address.bytes[0] = address[0]; + _address.bytes[1] = address[1]; + _address.bytes[2] = address[2]; + _address.bytes[3] = address[3]; return *this; } @@ -127,3 +128,18 @@ String IPAddress::toString() return str; } +//----------------------------------------------------------------------------- +static char addr_str[20]; +//----------------------------------------------------------------------------- +char * ip2chr(ip_addr addr) +{ + sprintf(addr_str, "%d.%d.%d.%d", addr.bytes[0], addr.bytes[1], addr.bytes[2], addr.bytes[3]); + return (char *)&addr_str; +} +//----------------------------------------------------------------------------- +char * mac2chr(uint8_t * mac) +{ + sprintf(addr_str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return (char *)&addr_str; +} + diff --git a/STM32F4/cores/maple/IPAddress.h b/STM32F4/cores/maple/IPAddress.h index c6e06972a..4f3f4cef2 100644 --- a/STM32F4/cores/maple/IPAddress.h +++ b/STM32F4/cores/maple/IPAddress.h @@ -24,14 +24,20 @@ #include #include -// A class to make it easier to handle and pass around IP addresses +typedef union { + uint32_t dword; + uint8_t bytes[4]; // IPv4 address +} ip_addr; +// Utility functions to handle IP addresses as chars +char * ip2chr(ip_addr addr); +char * mac2chr(uint8_t * mac); + + +// A class to make it easier to handle and pass around IP addresses class IPAddress : public Printable { private: - union { - uint8_t bytes[4]; // IPv4 address - uint32_t dword; - } _address; + ip_addr _address; // Access the raw byte array containing the address. Because this returns a pointer // to the internal structure rather than a copy of the address this function should only @@ -43,7 +49,7 @@ class IPAddress : public Printable { // Constructors IPAddress(); IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); - IPAddress(uint32_t address); + IPAddress(uint32_t address) { _address.dword = address; } IPAddress(const uint8_t *address); bool fromString(const char *address); @@ -65,6 +71,7 @@ class IPAddress : public Printable { virtual size_t printTo(Print& p) const; String toString(); + char * toChars() { return ip2chr(_address); } friend class EthernetClass; friend class UDP; diff --git a/STM32F4/cores/maple/Print.cpp b/STM32F4/cores/maple/Print.cpp index 0a71cf018..2e6e15476 100644 --- a/STM32F4/cores/maple/Print.cpp +++ b/STM32F4/cores/maple/Print.cpp @@ -47,12 +47,8 @@ */ size_t Print::write(const char *str) { - size_t n = 0; - while (*str) { - write(*str++); - n++; - } - return n; + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); } size_t Print::write(const void *buffer, uint32 size) { diff --git a/STM32F4/cores/maple/Stream.cpp b/STM32F4/cores/maple/Stream.cpp index 991fa87d9..d5920dd05 100644 --- a/STM32F4/cores/maple/Stream.cpp +++ b/STM32F4/cores/maple/Stream.cpp @@ -26,37 +26,40 @@ #define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait #define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field +//----------------------------------------------------------------------------- // private method to read stream with timeout +//----------------------------------------------------------------------------- int Stream::timedRead() { - int c; _startMillis = millis(); do { - c = read(); + int c = read(); if (c >= 0) return c; } while(millis() - _startMillis < _timeout); return -1; // -1 indicates timeout } +//----------------------------------------------------------------------------- // private method to peek stream with timeout +//----------------------------------------------------------------------------- int Stream::timedPeek() { - int c; _startMillis = millis(); do { - c = peek(); + int c = peek(); if (c >= 0) return c; } while(millis() - _startMillis < _timeout); return -1; // -1 indicates timeout } +//----------------------------------------------------------------------------- // returns peek of the next digit in the stream or -1 if timeout // discards non-numeric characters +//----------------------------------------------------------------------------- int Stream::peekNextDigit() { - int c; while (1) { - c = timedPeek(); + int c = timedPeek(); if (c < 0) return c; // timeout if (c == '-') return c; if (c >= '0' && c <= '9') return c; @@ -64,36 +67,46 @@ int Stream::peekNextDigit() } } +//----------------------------------------------------------------------------- // Public Methods -////////////////////////////////////////////////////////////// - -void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +//----------------------------------------------------------------------------- +// sets the maximum number of milliseconds to wait +//----------------------------------------------------------------------------- +void Stream::setTimeout(unsigned long timeout) { _timeout = timeout; } - // find returns true if the target string is found +//----------------------------------------------------------------------------- +// find returns true if the target string is found +//----------------------------------------------------------------------------- bool Stream::find(char *target) { return findUntil(target, (char*)""); } +//----------------------------------------------------------------------------- // reads data from the stream until the target string of given length is found // returns true if target string is found, false if timed out +//----------------------------------------------------------------------------- bool Stream::find(char *target, size_t length) { return findUntil(target, length, NULL, 0); } +//----------------------------------------------------------------------------- // as find but search ends if the terminator string is found +//----------------------------------------------------------------------------- bool Stream::findUntil(char *target, char *terminator) { return findUntil(target, strlen(target), terminator, strlen(terminator)); } +//----------------------------------------------------------------------------- // reads data from the stream until the target string of the given length is found // search terminated if the terminator string is found // returns true if target string is found, false if terminated or timed out +//----------------------------------------------------------------------------- bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) { size_t index = 0; // maximum target string length is 64k bytes! @@ -124,24 +137,26 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t return false; } - +//----------------------------------------------------------------------------- // returns the first valid (long) integer value from the current position. // initial characters that are not digits (or the minus sign) are skipped // function is terminated by the first character that is not a digit. +//----------------------------------------------------------------------------- long Stream::parseInt() { return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) } +//----------------------------------------------------------------------------- // as above but a given skipChar is ignored // this allows format characters (typically commas) in values to be ignored +//----------------------------------------------------------------------------- long Stream::parseInt(char skipChar) { boolean isNegative = false; long value = 0; - int c; - c = peekNextDigit(); + int c = peekNextDigit(); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout @@ -163,23 +178,26 @@ long Stream::parseInt(char skipChar) return value; } - +//----------------------------------------------------------------------------- // as parseInt but returns a floating point value +//----------------------------------------------------------------------------- float Stream::parseFloat() { return parseFloat(NO_SKIP_CHAR); } +//----------------------------------------------------------------------------- // as above but the given skipChar is ignored // this allows format characters (typically commas) in values to be ignored -float Stream::parseFloat(char skipChar){ +//----------------------------------------------------------------------------- +float Stream::parseFloat(char skipChar) +{ boolean isNegative = false; boolean isFraction = false; long value = 0; - int c; float fraction = 1.0; - c = peekNextDigit(); + int c = peekNextDigit(); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout @@ -209,11 +227,12 @@ float Stream::parseFloat(char skipChar){ return value; } +//----------------------------------------------------------------------------- // read characters from stream into buffer // terminates if length characters have been read, or timeout (see setTimeout) // returns the number of characters placed in the buffer // the buffer is NOT null terminated. -// +//----------------------------------------------------------------------------- size_t Stream::readBytes(char *buffer, size_t length) { size_t count = 0; @@ -226,11 +245,11 @@ size_t Stream::readBytes(char *buffer, size_t length) return count; } - +//----------------------------------------------------------------------------- // as readBytes with terminator character // terminates if length characters have been read, timeout, or if the terminator character detected // returns the number of characters placed in the buffer (0 means no valid data found) - +//----------------------------------------------------------------------------- size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) { if (length < 1) return 0; @@ -244,6 +263,7 @@ size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) return index; // return number of characters, not including null terminator } +//----------------------------------------------------------------------------- String Stream::readString() { String ret; @@ -256,6 +276,7 @@ String Stream::readString() return ret; } +//----------------------------------------------------------------------------- String Stream::readStringUntil(char terminator) { String ret; @@ -268,8 +289,9 @@ String Stream::readStringUntil(char terminator) return ret; } - -int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { +//----------------------------------------------------------------------------- +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) +{ // any zero length target string automatically matches and would make // a mess of the rest of the algorithm. for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { diff --git a/STM32F4/cores/maple/Streaming.h b/STM32F4/cores/maple/Streaming.h new file mode 100644 index 000000000..4e96246f8 --- /dev/null +++ b/STM32F4/cores/maple/Streaming.h @@ -0,0 +1,142 @@ +/* +Streaming.h - Arduino library for supporting the << streaming operator +Copyright (c) 2010-2012 Mikal Hart. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* 12-05-2015 GgR + added _FILL and _TIME classes from web page +*/ + +#ifndef ARDUINO_STREAMING +#define ARDUINO_STREAMING + +#if defined(ARDUINO) && ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#define STREAMING_LIBRARY_VERSION 5.1 + +// Generic template +template +inline Print &operator <<(Print &stream, T arg) +{ stream.print(arg); return stream; } + +struct _BASED +{ + long val; + int base; + _BASED(long v, int b): val(v), base(b) + {} +}; + +#if ARDUINO >= 100 + +struct _BYTE_CODE +{ + byte val; + _BYTE_CODE(byte v) : val(v) + {} +}; +#define _BYTE(a) _BYTE_CODE(a) + +inline Print &operator <<(Print &obj, const _BYTE_CODE &arg) +{ obj.write(arg.val); return obj; } + +#else + +#define _BYTE(a) _BASED(a, BYTE) + +#endif + +#define _HEX(a) _BASED(a, HEX) +#define _DEC(a) _BASED(a, DEC) +#define _OCT(a) _BASED(a, OCT) +#define _BIN(a) _BASED(a, BIN) + +// Specialization for class _BASED +// Thanks to Arduino forum user Ben Combee who suggested this +// clever technique to allow for expressions like +// Serial << _HEX(a); + +inline Print &operator <<(Print &obj, const _BASED &arg) +{ obj.print(arg.val, arg.base); return obj; } + +#if ARDUINO >= 18 +// Specialization for class _FLOAT +// Thanks to Michael Margolis for suggesting a way +// to accommodate Arduino 0018's floating point precision +// feature like this: +// Serial << _FLOAT(gps_latitude, 6); // 6 digits of precision + +struct _FLOAT +{ + float val; + int digits; + _FLOAT(double v, int d): val(v), digits(d) + {} +}; + +inline Print &operator <<(Print &obj, const _FLOAT &arg) +{ obj.print(arg.val, arg.digits); return obj; } +#endif + +// Specialization for enum _EndLineCode +// Thanks to Arduino forum user Paul V. who suggested this +// clever technique to allow for expressions like +// Serial << "Hello!" << endl; + +enum _EndLineCode { endl }; + +inline Print &operator <<(Print &obj, _EndLineCode arg) +{ (void)arg; obj.println(); return obj; } + + +// _Fill struct from web page +// from user Rob Tillaart +// Serial << _FILL('=', 20) << endl; + +struct _FILL +{ +char ch; +int len; +_FILL(char c, int l): ch(c), len(l) +{} +}; + +inline Print &operator <<(Print &obj, const _FILL &arg) +{ for (int i=0; i< arg.len; i++) obj.write(arg.ch); return obj; } + +// _TIME struct from web page +// from user Rob Tillaart +// Serial << _TIME(1,2,3) << endl; +struct _TIME +{ +uint8_t hour; +uint8_t minu; +uint8_t sec; +_TIME(uint8_t h, uint8_t m, uint8_t s): hour(h), minu(m), sec(s) +{} +}; + +inline Print &operator <<(Print &obj, const _TIME &arg) +{ obj.print(((arg.hour<10)?"0":"")); obj.print(int(arg.hour)); +obj.print(((arg.minu<10)?":0":":")); obj.print(int(arg.minu)); +obj.print(((arg.sec<10)?":0":":")); obj.print(int(arg.sec)); +return obj; } +#endif diff --git a/STM32F4/cores/maple/avr/pgmspace.h b/STM32F4/cores/maple/avr/pgmspace.h index 9b344c9b8..23abeea3e 100644 --- a/STM32F4/cores/maple/avr/pgmspace.h +++ b/STM32F4/cores/maple/avr/pgmspace.h @@ -22,6 +22,7 @@ typedef uint32_t prog_uint32_t; #define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) #define strcpy_P(dest, src) strcpy((dest), (src)) #define strcat_P(dest, src) strcat((dest), (src)) +#define strchr_P(s, c) strchr((s), (c)) #define strcmp_P(a, b) strcmp((a), (b)) #define strstr_P(a, b) strstr((a), (b)) #define strlen_P(a) strlen((a)) diff --git a/STM32F4/cores/maple/boards.cpp b/STM32F4/cores/maple/boards.cpp index 4b0480f67..7aa6d052d 100644 --- a/STM32F4/cores/maple/boards.cpp +++ b/STM32F4/cores/maple/boards.cpp @@ -40,29 +40,24 @@ #include #include #include +#include #include "usb.h" #include "usb_serial.h" -static void setupFlash(void); static void setupClocks(void); static void setupNVIC(void); static void setupADC(void); static void setupTimers(void); -void init(void) { - setupFlash(); - - setupClocks(); +void init(void) +{ + setupClocks(); // will setup the FLASH setupNVIC(); - systick_init(SYSTICK_RELOAD_VAL); - gpio_init_all(); + systick_init(SYSTICK_RELOAD_VAL); + gpio_init_all(); -#ifdef STM32F4 - rcc_clk_enable(RCC_SYSCFG); -#else - afio_init(); -#endif + rcc_clk_enable(RCC_SYSCFG); boardInit(); setupADC(); @@ -71,11 +66,14 @@ void init(void) { #ifdef SERIAL_USB SerialUSB.begin(); // includes { setupUSB(); } #endif + + fpu_enable(); } /* You could farm this out to the files in boards/ if e.g. it takes * too long to test on Maple Native (all those FSMC pins...). */ -bool boardUsesPin(uint8 pin) { +bool boardUsesPin(uint8 pin) +{ for (int i = 0; i < BOARD_NR_USED_PINS; i++) { if (pin == boardUsedPins[i]) { return true; @@ -84,16 +82,6 @@ bool boardUsesPin(uint8 pin) { return false; } -static void setupFlash(void) { -/* -#ifndef STM32F2 - // for F2 and F4 CPUs this is done in SetupClock...(), e.g. in SetupClock168MHz() - flash_enable_prefetch(); - flash_set_latency(FLASH_WAIT_STATE_2); -#endif -*/ -} - /* * Clock setup. Note that some of this only takes effect if we're * running bare metal and the bootloader hasn't done it for us @@ -102,54 +90,39 @@ static void setupFlash(void) { * If you change this function, you MUST change the file-level Doxygen * comment above. */ -static void setupClocks() { - rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9); - rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); - rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); - rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); +static void setupClocks() +{ + rcc_clk_init(); } -static void setupNVIC() { -#ifdef VECT_TAB_FLASH - nvic_init(USER_ADDR_ROM, 0); -#elif defined VECT_TAB_RAM +static void setupNVIC() +{ +#ifdef USER_ADDR_RAM nvic_init(USER_ADDR_RAM, 0); -#elif defined VECT_TAB_BASE - nvic_init((uint32)0x08000000, 0); +#elif defined USER_ADDR_ROM + nvic_init(USER_ADDR_ROM, 0); #else #error "You must select a base address for the vector table." #endif } -static void adcDefaultConfig(const adc_dev* dev); - -static void setupADC() { -#ifdef STM32F4 - setupADC_F4(); -#else - rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6); -#endif - adc_foreach(adcDefaultConfig); -} - -static void timerDefaultConfig(timer_dev*); - -static void setupTimers() { - timer_foreach(timerDefaultConfig); -} - -static void adcDefaultConfig(const adc_dev *dev) { +static void adcDefaultConfig(const adc_dev *dev) +{ adc_init(dev); - - adc_set_extsel(dev, ADC_SWSTART); - adc_set_exttrig(dev, true); - + adc_set_exttrig(dev, ADC_EXT_TRIGGER_DISABLE); + adc_set_sampling_time(dev, ADC_SMPR_144); // 1 µs sampling+conversion time adc_enable(dev); - adc_calibrate(dev); - adc_set_sample_rate(dev, ADC_SMPR_55_5); } -static void timerDefaultConfig(timer_dev *dev) { +static void setupADC() +{ + setupADC_F4(); + adc_foreach(adcDefaultConfig); +} + +static void timerDefaultConfig(const timer_dev *dev) +{ +return; timer_adv_reg_map *regs = (dev->regs).adv; const uint16 full_overflow = 0xFFFF; const uint16 half_duty = 0x8FFF; @@ -181,3 +154,8 @@ static void timerDefaultConfig(timer_dev *dev) { regs->EGR = TIMER_EGR_UG; timer_resume(dev); } + +static void setupTimers() +{ + timer_foreach(timerDefaultConfig); +} diff --git a/STM32F4/cores/maple/boards.h b/STM32F4/cores/maple/boards.h index d37bff4a5..5d149a55b 100644 --- a/STM32F4/cores/maple/boards.h +++ b/STM32F4/cores/maple/boards.h @@ -39,31 +39,11 @@ #ifndef _BOARDS_H_ #define _BOARDS_H_ -#include + +#include #include -/* Set of all possible pin names; not all boards have all these (note - * that we use the Dx convention since all of the Maple's pins are - * "digital" pins (e.g. can be used with digitalRead() and - * digitalWrite()), but not all of them are connected to ADCs. */ -enum { - D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, - D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31, - D32, D33, D34, D35, D36, D37, D38, D39, D40, D41, D42, D43, D44, D45, D46, - D47, D48, D49, D50, D51, D52, D53, D54, D55, D56, D57, D58, D59, D60, D61, - D62, D63, D64, D65, D66, D67, D68, D69, D70, D71, D72, D73, D74, D75, D76, -#if 0 // not available on LQFP100 package - D77, D78, D79, D80, D81, D82, D83, D84, D85, D86, D87, D88, D89, D90, D91, - D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105, - D106, D107, D108, D109, D110, D111, -#endif // not available on LQFP100 package -}; -/** - * @brief Maps each Maple pin to a corresponding stm32_pin_info. - * @see stm32_pin_info - */ -extern const stm32_pin_info PIN_MAP[]; /** * @brief Pins capable of PWM output. @@ -121,16 +101,18 @@ extern bool boardUsesPin(uint8 pin); /* FIXME HACK put boards/ before these paths once IDE uses make. */ -#if defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1) -#include "aeroquad32.h" -#elif defined(BOARD_aeroquad32mini) -#include "aeroquad32mini.h" -#elif defined(BOARD_discovery_f4) +#if defined(VARIANT_discovery_f407) #include "discovery_f4.h" -#elif defined(BOARD_generic_f407v) +#elif defined(VARIANT_blackpill_f401) +#include "blackpill_f401.h" +#elif defined(VARIANT_blackpill_f411) +#include "blackpill_f411.h" +#elif defined(VARIANT_disco_f411) +#include "disco_f411.h" +#elif defined(VARIANT_generic_f407v) #include "generic_f407v.h" -#elif defined(BOARD_freeflight) -#include "freeflight.h" +#elif defined(VARIANT_arch_max) +#include "arch_max.h" #else /* * TODO turn this into a warning so people can: @@ -146,15 +128,12 @@ extern bool boardUsesPin(uint8 pin); /* Set derived definitions */ -#define CLOCK_SPEED_MHZ CYCLES_PER_MICROSECOND +#define CYCLES_PER_MICROSECOND CLOCK_SPEED_MHZ #define CLOCK_SPEED_HZ (CLOCK_SPEED_MHZ * 1000000UL) -#ifndef SYSTICK_RELOAD_VAL -#define SYSTICK_RELOAD_VAL (1000 * CYCLES_PER_MICROSECOND - 1) -#endif - #ifndef BOARD_BUTTON_PRESSED_LEVEL #define BOARD_BUTTON_PRESSED_LEVEL HIGH #endif + #endif diff --git a/STM32F4/cores/maple/ext_interrupts.cpp b/STM32F4/cores/maple/ext_interrupts.cpp index 7111d0c86..bb1d2c2eb 100644 --- a/STM32F4/cores/maple/ext_interrupts.cpp +++ b/STM32F4/cores/maple/ext_interrupts.cpp @@ -52,7 +52,7 @@ void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) { exti_trigger_mode outMode = exti_out_mode(mode); exti_attach_interrupt((afio_exti_num)(pin&0x0F), - gpio_exti_port(PIN_MAP[pin].gpio_device), + gpio_exti_port(digitalPinToPort(pin)), handler, outMode); } diff --git a/STM32F4/cores/maple/hooks.c b/STM32F4/cores/maple/hooks.c deleted file mode 100644 index 641eabc73..000000000 --- a/STM32F4/cores/maple/hooks.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (c) 2012 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/** - * Empty yield() hook. - * - * This function is intended to be used by library writers to build - * libraries or sketches that supports cooperative threads. - * - * Its defined as a weak symbol and it can be redefined to implement a - * real cooperative scheduler. - */ -static void __empty() { - // Empty -} -void yield(void) __attribute__ ((weak, alias("__empty"))); diff --git a/STM32F4/cores/maple/io.h b/STM32F4/cores/maple/io.h index aeaf0fd3a..517a1e5a9 100644 --- a/STM32F4/cores/maple/io.h +++ b/STM32F4/cores/maple/io.h @@ -122,6 +122,8 @@ void pinMode(uint8 pin, WiringPinMode mode); * @see pinMode() */ void digitalWrite(uint8 pin, uint8 value); +void digitalSet(uint8 pin); +void digitalClear(uint8 pin); /** * Read a digital value from a pin. The pin must have its mode set to @@ -143,7 +145,8 @@ uint32 digitalRead(uint8 pin); * conversion). * @see pinMode() */ -uint16 analogRead(uint8 pin); +uint16 analogReadDev(uint8 pin, const adc_dev *); +static inline uint16 analogRead(uint8 pin) { return analogReadDev(pin, ADC1); } /** * Toggles the digital value at the given pin. diff --git a/STM32F4/cores/maple/libmaple/HardwareSerial.cpp b/STM32F4/cores/maple/libmaple/HardwareSerial.cpp index 7f3d281a9..2b5a14229 100644 --- a/STM32F4/cores/maple/libmaple/HardwareSerial.cpp +++ b/STM32F4/cores/maple/libmaple/HardwareSerial.cpp @@ -38,38 +38,38 @@ #define TX1 BOARD_USART1_TX_PIN #define RX1 BOARD_USART1_RX_PIN +HardwareSerial Serial1(USART1, TX1, RX1); #ifdef BOARD_USART2_TX_PIN - #define TX2 BOARD_USART2_TX_PIN - #define RX2 BOARD_USART2_RX_PIN +#define TX2 BOARD_USART2_TX_PIN +#define RX2 BOARD_USART2_RX_PIN +HardwareSerial Serial2(USART2, TX2, RX2); #endif #ifdef BOARD_USART3_TX_PIN - #define TX3 BOARD_USART3_TX_PIN - #define RX3 BOARD_USART3_RX_PIN +#define TX3 BOARD_USART3_TX_PIN +#define RX3 BOARD_USART3_RX_PIN +HardwareSerial Serial3(USART3, TX3, RX3); #endif -#if defined STM32_HIGH_DENSITY && !defined(BOARD_maple_RET6) +#ifdef BOARD_UART4_TX_PIN #define TX4 BOARD_UART4_TX_PIN #define RX4 BOARD_UART4_RX_PIN -#define TX5 BOARD_UART5_TX_PIN -#define RX5 BOARD_UART5_RX_PIN +HardwareSerial Serial4(UART4, TX4, RX4); #endif -HardwareSerial Serial1(USART1, TX1, RX1); - -#ifdef TX2 -HardwareSerial Serial2(USART2, TX2, RX2); +#ifdef BOARD_UART5_TX_PIN +#define TX5 BOARD_UART5_TX_PIN +#define RX5 BOARD_UART5_RX_PIN +HardwareSerial Serial5(UART5, TX5, RX5); #endif -#ifdef TX3 -HardwareSerial Serial3(USART3, TX3, RX3); +#ifdef BOARD_USART6_TX_PIN +#define TX6 BOARD_USART6_TX_PIN +#define RX6 BOARD_USART6_RX_PIN +HardwareSerial Serial6(USART6, TX6, RX6); #endif -#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) -HardwareSerial Serial4(UART4, TX4, RX4); -HardwareSerial Serial5(UART5, TX5, RX5); -#endif HardwareSerial::HardwareSerial(usart_dev *usart_device, uint8 tx_pin, @@ -83,37 +83,22 @@ HardwareSerial::HardwareSerial(usart_dev *usart_device, * Set up/tear down */ -void HardwareSerial::begin(uint32 baud) { - ASSERT(baud <= usart_device->max_baud); - +void HardwareSerial::begin(uint32 baud) +{ if (baud > usart_device->max_baud) { - return; + baud = usart_device->max_baud; } -#ifdef STM32F4 - // int af = 7<<8; - if (usart_device == UART4 || usart_device == UART5) { - gpio_set_af_mode(tx_pin, 8); - gpio_set_af_mode(rx_pin, 8); + if (usart_device == UART4 || usart_device == UART5 || usart_device == USART6) { + gpio_set_af_mode(tx_pin, GPIO_AFMODE_USART4_6); + gpio_set_af_mode(rx_pin, GPIO_AFMODE_USART4_6); } else { - gpio_set_af_mode(tx_pin, 7); - gpio_set_af_mode(rx_pin, 7); + gpio_set_af_mode(tx_pin, GPIO_AFMODE_USART1_3); + gpio_set_af_mode(rx_pin, GPIO_AFMODE_USART1_3); } gpio_set_mode(tx_pin, (gpio_pin_mode)(GPIO_AF_OUTPUT_PP_PU | 0x700)); gpio_set_mode(rx_pin, (gpio_pin_mode)(GPIO_AF_INPUT_PU | 0x700)); - //gpio_set_mode(txi->gpio_device, txi->gpio_bit, (gpio_pin_mode)(GPIO_PUPD_INPUT_PU)); - //gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, (gpio_pin_mode)(GPIO_PUPD_INPUT_PU)); -#else - gpio_set_mode(tx_pin, GPIO_AF_OUTPUT_PP); - gpio_set_mode(rx_pin, GPIO_INPUT_FLOATING); -#endif -#if 0 - if (txi->timer_device != NULL) { - /* Turn off any PWM if there's a conflict on this GPIO bit. */ - timer_set_mode(txi->timer_device, txi->timer_channel, TIMER_DISABLED); - } -#endif usart_init(usart_device); usart_set_baud_rate(usart_device, baud); diff --git a/STM32F4/cores/maple/libmaple/HardwareSerial.h b/STM32F4/cores/maple/libmaple/HardwareSerial.h index b49c4cfca..3900a9181 100644 --- a/STM32F4/cores/maple/libmaple/HardwareSerial.h +++ b/STM32F4/cores/maple/libmaple/HardwareSerial.h @@ -65,6 +65,7 @@ class HardwareSerial : public Stream { uint32 pending(void); virtual int read(void); virtual size_t write(unsigned char); + virtual size_t write(const uint8 * dataptr, uint32 len) { return usart_tx(usart_device, dataptr, len); } using Print::write; /* Pin accessors */ @@ -78,10 +79,15 @@ class HardwareSerial : public Stream { extern HardwareSerial Serial1; extern HardwareSerial Serial2; -#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) +#ifdef BOARD_USART3_TX_PIN extern HardwareSerial Serial3; +#endif +#ifdef BOARD_UART4_TX_PIN extern HardwareSerial Serial4; +#endif +#ifdef BOARD_UART5_TX_PIN extern HardwareSerial Serial5; #endif +extern HardwareSerial Serial6; extern HardwareSerial &SerialDebug; #endif diff --git a/STM32F4/cores/maple/libmaple/adc.c b/STM32F4/cores/maple/libmaple/adc.c index 0f4c02c3c..3e106e7c1 100644 --- a/STM32F4/cores/maple/libmaple/adc.c +++ b/STM32F4/cores/maple/libmaple/adc.c @@ -40,26 +40,42 @@ #include "libmaple.h" #include "rcc.h" #include "adc.h" +#include "wirish_time.h" + + +voidFuncPtr adc1Handlers[ADC_LAST_IRQ_ID] = {NULL}; +voidFuncPtr adc2Handlers[ADC_LAST_IRQ_ID] = {NULL}; +voidFuncPtr adc3Handlers[ADC_LAST_IRQ_ID] = {NULL}; /** ADC1 device. */ -const adc_dev ADC1 = { +const adc_dev adc1 = { .regs = ADC1_BASE, - .clk_id = RCC_ADC1 + .clk_id = RCC_ADC1, + .dmaStream = DMA_STREAM0, // or DMA_STREAM4 + .dmaChannel = DMA_CH0, + .handler_p = &adc1Handlers }; /** ADC2 device. */ -const adc_dev ADC2 = { +const adc_dev adc2 = { .regs = ADC2_BASE, - .clk_id = RCC_ADC2 + .clk_id = RCC_ADC2, + .dmaStream = DMA_STREAM2, // or DMA_STREAM3 + .dmaChannel = DMA_CH1, + .handler_p = &adc2Handlers }; -#ifdef STM32_HIGH_DENSITY /** ADC3 device. */ -const adc_dev ADC3 = { +const adc_dev adc3 = { .regs = ADC3_BASE, - .clk_id = RCC_ADC3 + .clk_id = RCC_ADC3, + .dmaStream = DMA_STREAM0, // or DMA_STREAM1 + .dmaChannel = DMA_CH2, + .handler_p = &adc3Handlers }; -#endif + + +adc_common_reg_map* const ADC_COMMON = ADC_COMMON_BASE; /** * @brief Initialize an ADC peripheral. @@ -69,15 +85,29 @@ const adc_dev ADC3 = { * * @param dev ADC peripheral to initialize */ -void adc_init(const adc_dev *dev) { +void adc_init(const adc_dev *dev) +{ rcc_clk_enable(dev->clk_id); -#ifdef STM32F4 if(dev->clk_id == RCC_ADC1) { - rcc_reset_dev(dev->clk_id); + rcc_reset_dev(dev->clk_id); } -#else - rcc_reset_dev(dev->clk_id); -#endif +} + +/** + * @brief Set external trigger for regular channels + * @param dev ADC device + * @param adc_exten_trigger + */ +void adc_set_exttrig(const adc_dev *dev, adc_ext_trigger trigger) +{ + uint32 cr2 = dev->regs->CR2 & (~ADC_CR2_EXTEN); + dev->regs->CR2 = cr2 | (trigger << ADC_CR2_EXTEN_SHIFT); +} + +void adc_set_jexttrig(const adc_dev *dev, adc_ext_trigger trigger) +{ + uint32 cr2 = dev->regs->CR2 & (~ADC_CR2_JEXTEN); + dev->regs->CR2 = cr2 | (trigger << ADC_CR2_JEXTEN_SHIFT); } /** @@ -86,69 +116,134 @@ void adc_init(const adc_dev *dev) { * @param event Event used to trigger the start of conversion. * @see adc_extsel_event */ -void adc_set_extsel(const adc_dev *dev, adc_extsel_event event) { - uint32 cr2 = dev->regs->CR2; - cr2 &= ~ADC_CR2_EXTSEL; - cr2 |= event; - dev->regs->CR2 = cr2; +void adc_set_extsel(const adc_dev *dev, adc_extsel_event event) +{ + uint32 cr2 = dev->regs->CR2 & (~ADC_CR2_EXTSEL); + dev->regs->CR2 = cr2 | (event << ADC_CR2_EXTSEL_SHIFT); +} + +void adc_set_jextsel(const adc_dev *dev, adc_jextsel_event event) +{ + uint32 cr2 = dev->regs->CR2 & (~ADC_CR2_JEXTSEL); + dev->regs->CR2 = cr2 | (event << ADC_CR2_JEXTSEL_SHIFT); +} + +/* + enable interrupts on the ADC: ADC_EOC, ADC_JEOC, ADC_AWD +*/ +void adc_enable_irq(const adc_dev* dev) +{ + dev->regs->CR1 |= ADC_CR1_EOCIE; + nvic_irq_enable(NVIC_ADC_1_2_3); +} + +void adc_disable_irq(const adc_dev* dev) +{ + nvic_irq_disable(NVIC_ADC_1_2_3); + dev->regs->CR1 &= ~ADC_CR1_EOCIE; +} + +void adc_awd_enable_irq(const adc_dev * dev) +{ + dev->regs->CR1 |= ADC_CR1_AWDIE; + nvic_irq_enable(NVIC_ADC_1_2_3); +} + +void adc_ovr_enable_irq(const adc_dev* dev) +{ + dev->regs->CR1 |= ADC_CR1_OVRIE; + nvic_irq_enable(NVIC_ADC_1_2_3); +} + +/* + attach interrupt functionality for ADC + use ADC_EOC, ADC_JEOC, ADC_AWD + added by bubulindo +*/ +void adc_attach_interrupt(const adc_dev *dev, + adc_irq_id irq_id, + voidFuncPtr handler) +{ + if (irq_idhandler_p))[irq_id] = handler; + if(irq_id == ADC_EOC) + adc_enable_irq(dev); + else if (irq_id == ADC_AWD) + adc_awd_enable_irq(dev); + else if (irq_id == ADC_OVR) + adc_ovr_enable_irq(dev); + } +} + +void adc_detach_interrupt(const adc_dev *dev, adc_irq_id irq_id) +{ + if (irq_idhandler_p))[irq_id] = NULL; + } } /** * @brief Call a function on all ADC devices. * @param fn Function to call on each ADC device. */ -void adc_foreach(void (*fn)(const adc_dev*)) { - fn(&ADC1); - fn(&ADC2); -#ifdef STM32_HIGH_DENSITY - fn(&ADC3); -#endif +void adc_foreach(void (*fn)(const adc_dev*)) +{ + fn(ADC1); + fn(ADC2); + fn(ADC3); +} + +/* + * @param pre, setup the ADC prescaler to one of PCLK /2, /4, /6, /8 + * the templates per adc_prescaler enum + */ +void adc_set_prescaler(adc_prescaler pre) { + + ADC_COMMON->CCR &= ~ ADC_CCR_ADCPRE; + ADC_COMMON->CCR |= ((pre & 3U) << ADC_CCR_ADCPRE_SHIFT); } /** - * @brief Turn the given sample rate into values for ADC_SMPRx. Don't - * call this during conversion. + * @brief Set the given sampling times for all channels. + * Don't call this during conversion! * @param dev adc device - * @param smp_rate sample rate to set + * @param smpl_time sampling time to set * @see adc_smp_rate */ -void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate) { - uint32 adc_smpr1_val = 0, adc_smpr2_val = 0; - int i; - - for (i = 0; i < 10; i++) { - if (i < 8) { - /* ADC_SMPR1 determines sample time for channels [10,17] */ - adc_smpr1_val |= smp_rate << (i * 3); - } - /* ADC_SMPR2 determines sample time for channels [0,9] */ - adc_smpr2_val |= smp_rate << (i * 3); +void adc_set_sampling_time(const adc_dev *dev, adc_smp_rate smpl_time) +{ + uint32 adc_smpr_val = 0; + + for (uint8 i = 0; i < 10; i++) + { + adc_smpr_val |= smpl_time << (i * 3); } - dev->regs->SMPR1 = adc_smpr1_val; - dev->regs->SMPR2 = adc_smpr2_val; + dev->regs->SMPR2 = adc_smpr_val; // channels 0..9 + dev->regs->SMPR1 = adc_smpr_val&0x7FFFFFF; // channels 10..18 } -/** - * @brief Calibrate an ADC peripheral - * @param dev adc device - */ -void adc_calibrate(const adc_dev *dev) +/* + Starts a single conversion in one channel previously defined. + Results must be read through interrupt or polled outside this function. +*/ +void adc_start_single_convert(const adc_dev* dev, uint8 channel) { + adc_set_reg_seqlen(dev, 1); + dev->regs->SQR3 = channel; + adc_start_convert(dev); +} + /* -#ifndef STM32F2 - __io uint32 *rstcal_bit = bb_perip(&(dev->regs->CR2), 3); - __io uint32 *cal_bit = bb_perip(&(dev->regs->CR2), 2); - - *rstcal_bit = 1; - while (*rstcal_bit) - ; - - *cal_bit = 1; - while (*cal_bit) - ; -#endif + Starts the continuous mode on one channel of the AD. + Results must be read through interrupt or polled outside this function. */ +void adc_start_continuous_convert(const adc_dev* dev, uint8 channel) +{ + adc_set_continuous(dev); + adc_start_single_convert(dev, channel); } /** @@ -158,42 +253,190 @@ void adc_calibrate(const adc_dev *dev) * @param channel channel to convert * @return conversion result */ -uint16 adc_read(const adc_dev *dev, uint8 channel) { - adc_reg_map *regs = dev->regs; +uint16 adc_read(const adc_dev *dev, uint8 channel) +{ + adc_start_single_convert(dev, channel); - adc_set_reg_seqlen(dev, 1); + while ( !adc_is_end_of_convert(dev) ); + + return adc_get_data(dev); +} + +void adc_enable_tsvref(void) +{ + ADC_COMMON->CCR |= ADC_CCR_TSVREFE; + delayMicroseconds(10); +} + +void adc_enable_vbat(void) +{ + ADC_COMMON->CCR |= ADC_CCR_VBATE; + delayMicroseconds(10); +} + +//----------------------------------------------------------------------------- +void adc_set_reg_sequence(const adc_dev * dev, uint8 * channels, uint8 len) +{ + //run away protection + if (len > 16) len = 16; + + uint32_t seq_reg[3]; + //write the length + seq_reg[0] = seq_reg[1] = 0; + seq_reg[2] = (len - 1) << 20; + + //i goes through records, j goes through variables. + for (uint8 i = 0; i < len; i++) { //go through the channel list. + seq_reg[i/6] |= (channels[i] << ((i%6)*5)); + } + //update the registers inside with the scan sequence. + dev->regs->SQR1 = seq_reg[2]; + dev->regs->SQR2 = seq_reg[1]; + dev->regs->SQR3 = seq_reg[0]; +}; + +/* + ADC IRQ handler. + added by bubulindo +*/ +void adc_irq_handler(const adc_dev * dev) +{ + //End Of Conversion + if (dev->regs->SR & ADC_SR_EOC) { + dev->regs->SR = ~ADC_SR_EOC; + voidFuncPtr handler = (*(dev->handler_p))[ADC_EOC]; + if (handler) { + handler(); + } + } + //Injected End Of Conversion + if (dev->regs->SR & ADC_SR_JEOC) { + dev->regs->SR = ~ADC_SR_JEOC; + voidFuncPtr handler = (*(dev->handler_p))[ADC_JEOC]; + if (handler) { + handler(); + } + } + //Analog Watchdog + if (dev->regs->SR & ADC_SR_AWD) { + dev->regs->SR = ~ADC_SR_AWD; + voidFuncPtr handler = (*(dev->handler_p))[ADC_AWD]; + if (handler) { + handler(); + } + } + //ADC overrun interrupt + if (dev->regs->SR & ADC_SR_OVR) { + dev->regs->SR = ~ADC_SR_OVR; + voidFuncPtr handler = (*(dev->handler_p))[ADC_OVR]; + if (handler) { + handler(); + } + } + +} +void __irq_adc() +{ + adc_foreach(&adc_irq_handler); +} +//----------------------------------------------------------------------------- +// Read internal variables. +// Channels are: +// 16 - Temperature +// 17 - VrefInt +// Results must be read through interrupt or polled outside this function. +/* +inline void internalRead(adc_dev *dev, uint8 channel) { + adc_reg_map *regs = dev->regs; + adc_set_reg_seqlen(dev, 1); regs->SQR3 = channel; regs->CR2 |= ADC_CR2_SWSTART; - while(!(regs->SR & ADC_SR_EOC)) - ; +} +*/ + +/* + Used to configure the sequence and length of the scan mode. + Can be used instead of adc_set_reg_seqlen() as it sets both information + The channels are not the pin numbers, but ADC channels. +*/ + +/* +//fast interleaved mode +void setADCs (uint8 analogInPin) +{ + // const adc_dev *dev = adc_devices[PIN_MAP[analogInPin].adc_device]; + int pinMapADCin = PIN_MAP[analogInPin].adc_channel; + adc_set_sample_rate(ADC1, ADC_SMPR_1_5); //=0,58uS/sample. ADC_SMPR_13_5 = 1.08uS - use this one if Rin>10Kohm, + adc_set_sample_rate(ADC2, ADC_SMPR_1_5); // if not may get some sporadic noise. see datasheet. + + // adc_reg_map *regs = dev->regs; + adc_set_reg_seqlen(ADC1, 1); + ADC1->regs->SQR3 = pinMapADCin; + ADC1->regs->CR2 |= ADC_CR2_CONT; // | ADC_CR2_DMA; // Set continuous mode and DMA + ADC1->regs->CR1 |= ADC_CR1_FASTINT; // Interleaved mode + ADC1->regs->CR2 |= ADC_CR2_SWSTART; + + ADC2->regs->CR2 |= ADC_CR2_CONT; // ADC 2 continuos + ADC2->regs->SQR3 = pinMapADCin; +} +*/ + +/* + This is run inside the loop() function. + It stays active and polls for the end of the transfer. + +*/ +/* +void takeSamples () +{ + // This loop uses dual interleaved mode to get the best performance out of the ADCs + // + unsigned long samplingTime=0; + dma_init(DMA1); + dma_attach_interrupt(DMA1, DMA_CH1, DMA1_CH1_Event); + + adc_dma_enable(ADC1); + dma_setup_transfer(DMA1, DMA_CH1, &ADC1->regs->DR, DMA_SIZE_32BITS, + dataPoints32, DMA_SIZE_32BITS, (DMA_MINC_MODE | DMA_TRNS_CMPLT));// Receive buffer DMA + dma_set_num_transfers(DMA1, DMA_CH1, maxSamples / 2); + dma1_ch1_Active = 1; + // regs->CR2 |= ADC_CR2_SWSTART; //moved to setADC + dma_enable(DMA1, DMA_CH1); // Enable the channel and start the transfer. + samplingTime = micros(); + while (dma1_ch1_Active); + samplingTime = (micros() - samplingTime); + + dma_disable(DMA1, DMA_CH1); //End of trasfer, disable DMA and Continuous mode. + // regs->CR2 &= ~ADC_CR2_CONT; - return (uint16)(regs->DR & ADC_DR_DATA); } +*/ +//----------------------------------------------------------------------------- void setupADC_F4(void) { - uint32 tmpreg1 = 0; + uint32 tmpreg1 = 0; - tmpreg1 = ADC_COMMON->CCR; + tmpreg1 = ADC_COMMON->CCR; - /* Clear MULTI, DELAY, DMA and ADCPRE bits */ -#define CR_CLEAR_MASK ((uint32)0xFFFC30E0) - tmpreg1 &= CR_CLEAR_MASK; + /* Clear all bits */ +#define CR_CLEAR_MASK ((uint32)0xFF3C10E0) + tmpreg1 &= CR_CLEAR_MASK; - /* Configure ADCx: Multi mode, Delay between two sampling time, ADC prescaler, - and DMA access mode for multimode */ - /* Set MULTI bits according to ADC_Mode value */ - /* Set ADCPRE bits according to ADC_Prescaler value */ - /* Set DMA bits according to ADC_DMAAccessMode value */ - /* Set DELAY bits according to ADC_TwoSamplingDelay value */ + /* Configure ADCx: Multi mode, Delay between two sampling time, ADC prescaler, + and DMA access mode for multimode */ + /* Set MULTI bits according to ADC_Mode value */ + /* Set ADCPRE bits according to ADC_Prescaler value */ + /* Set DMA bits according to ADC_DMAAccessMode value */ + /* Set DELAY bits according to ADC_TwoSamplingDelay value */ #define ADC_Mode_Independent 0 #define ADC_Prescaler_Div2 0 #define ADC_DMAAccessMode_Disabled 0 /* DMA mode disabled */ #define ADC_TwoSamplingDelay_5Cycles 0 - tmpreg1 |= ADC_Mode_Independent | ADC_Prescaler_Div2 | ADC_DMAAccessMode_Disabled | ADC_TwoSamplingDelay_5Cycles; + tmpreg1 |= ( ADC_Mode_Independent | ADC_Prescaler_Div2 | ADC_DMAAccessMode_Disabled | ADC_TwoSamplingDelay_5Cycles ); - /* Write to ADC CCR */ - ADC_COMMON->CCR = tmpreg1; + /* Write to ADC CCR */ + ADC_COMMON->CCR = tmpreg1; } diff --git a/STM32F4/cores/maple/libmaple/adc.h b/STM32F4/cores/maple/libmaple/adc.h index a4c11ffec..b22dff468 100644 --- a/STM32F4/cores/maple/libmaple/adc.h +++ b/STM32F4/cores/maple/libmaple/adc.h @@ -36,57 +36,73 @@ #include "libmaple.h" #include "bitband.h" #include "rcc.h" +#include "dma.h" +#include #ifdef __cplusplus extern "C"{ #endif - -typedef struct -{ - __io uint32 CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ - __io uint32 CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ - __io uint32 CDR; /*!< ADC common regular data register for dual - AND triple modes, Address offset: ADC1 base address + 0x308 */ -} ADC_Common_TypeDef; -#define ADC_COMMON ((ADC_Common_TypeDef *) 0x40012300) - - /** ADC register map type. */ typedef struct adc_reg_map { - __io uint32 SR; ///< Status register - __io uint32 CR1; ///< Control register 1 - __io uint32 CR2; ///< Control register 2 - __io uint32 SMPR1; ///< Sample time register 1 - __io uint32 SMPR2; ///< Sample time register 2 - __io uint32 JOFR1; ///< Injected channel data offset register 1 - __io uint32 JOFR2; ///< Injected channel data offset register 2 - __io uint32 JOFR3; ///< Injected channel data offset register 3 - __io uint32 JOFR4; ///< Injected channel data offset register 4 - __io uint32 HTR; ///< Watchdog high threshold register - __io uint32 LTR; ///< Watchdog low threshold register - __io uint32 SQR1; ///< Regular sequence register 1 - __io uint32 SQR2; ///< Regular sequence register 2 - __io uint32 SQR3; ///< Regular sequence register 3 - __io uint32 JSQR; ///< Injected sequence register - __io uint32 JDR1; ///< Injected data register 1 - __io uint32 JDR2; ///< Injected data register 2 - __io uint32 JDR3; ///< Injected data register 3 - __io uint32 JDR4; ///< Injected data register 4 - __io uint32 DR; ///< Regular data register + __IO uint32 SR; ///< Status register + __IO uint32 CR1; ///< Control register 1 + __IO uint32 CR2; ///< Control register 2 + __IO uint32 SMPR1; ///< Sample time register 1 + __IO uint32 SMPR2; ///< Sample time register 2 + __IO uint32 JOFR1; ///< Injected channel data offset register 1 + __IO uint32 JOFR2; ///< Injected channel data offset register 2 + __IO uint32 JOFR3; ///< Injected channel data offset register 3 + __IO uint32 JOFR4; ///< Injected channel data offset register 4 + __IO uint32 HTR; ///< Watchdog high threshold register + __IO uint32 LTR; ///< Watchdog low threshold register + __IO uint32 SQR1; ///< Regular sequence register 1 + __IO uint32 SQR2; ///< Regular sequence register 2 + __IO uint32 SQR3; ///< Regular sequence register 3 + __IO uint32 JSQR; ///< Injected sequence register + __IO uint32 JDR1; ///< Injected data register 1 + __IO uint32 JDR2; ///< Injected data register 2 + __IO uint32 JDR3; ///< Injected data register 3 + __IO uint32 JDR4; ///< Injected data register 4 + __IO uint32 DR; ///< Regular data register } adc_reg_map; +//Added by bubulindo - Interrupt ID's for ADC +typedef enum { + ADC_EOC, // End Of Conversion interrupt. + ADC_AWD , // Analog WatchDog interrupt + ADC_JEOC, // Injected End Of Conversion interrupt. + ADC_OVR, // overrun interrupt + ADC_LAST_IRQ_ID +} adc_irq_id; + +extern voidFuncPtr adc1Handlers[ADC_LAST_IRQ_ID]; // EOC, JEOC, AWD Interrupts +extern voidFuncPtr adc2Handlers[ADC_LAST_IRQ_ID]; // EOC, JEOC, AWD Interrupts +extern voidFuncPtr adc3Handlers[ADC_LAST_IRQ_ID]; // EOC, JEOC, AWD Interrupts + /** ADC device type. */ -typedef struct adc_dev { +typedef struct adc_dev +{ adc_reg_map *regs; /**< Register map */ rcc_clk_id clk_id; /**< RCC clock information */ + dma_stream dmaStream; + dma_channel dmaChannel; + voidFuncPtr (*handler_p)[]; } adc_dev; -extern const adc_dev ADC1; -extern const adc_dev ADC2; -#ifdef STM32_HIGH_DENSITY -extern const adc_dev ADC3; -#endif +extern const adc_dev adc1; +extern const adc_dev adc2; +extern const adc_dev adc3; + +#define ADC1 ((adc_dev*) &adc1) +#define ADC2 ((adc_dev*) &adc2) +#define ADC3 ((adc_dev*) &adc3) + +typedef struct adc_common_reg_map { + __IO uint32 CSR; ///< Common status register + __IO uint32 CCR; ///< Common control register + __IO uint32 CDR; ///< Common regular data register for dual AND triple modes +} adc_common_reg_map; /* * Register map base pointers @@ -98,6 +114,10 @@ extern const adc_dev ADC3; #define ADC2_BASE ((struct adc_reg_map*)0x40012100) /** ADC3 register map base pointer. */ #define ADC3_BASE ((struct adc_reg_map*)0x40012200) +/** ADC common register map base pointer. */ +#define ADC_COMMON_BASE ((struct adc_common_reg_map*)0x40012300) + +extern adc_common_reg_map* const ADC_COMMON; /* * Register bit definitions @@ -105,76 +125,74 @@ extern const adc_dev ADC3; /* Status register */ -#define ADC_SR_AWD_BIT 0 -#define ADC_SR_EOC_BIT 1 -#define ADC_SR_JEOC_BIT 2 -#define ADC_SR_JSTRT_BIT 3 -#define ADC_SR_STRT_BIT 4 - -#define ADC_SR_AWD BIT(ADC_SR_AWD_BIT) -#define ADC_SR_EOC BIT(ADC_SR_EOC_BIT) -#define ADC_SR_JEOC BIT(ADC_SR_JEOC_BIT) -#define ADC_SR_JSTRT BIT(ADC_SR_JSTRT_BIT) -#define ADC_SR_STRT BIT(ADC_SR_STRT_BIT) +#define ADC_SR_OVR BIT(5) +#define ADC_SR_STRT BIT(4) +#define ADC_SR_JSTRT BIT(3) +#define ADC_SR_JEOC BIT(2) +#define ADC_SR_EOC BIT(1) +#define ADC_SR_AWD BIT(0) /* Control register 1 */ -#define ADC_CR1_EOCIE_BIT 5 -#define ADC_CR1_AWDIE_BIT 6 -#define ADC_CR1_JEOCIE_BIT 7 -#define ADC_CR1_SCAN_BIT 8 -#define ADC_CR1_AWDSGL_BIT 9 -#define ADC_CR1_JAUTO_BIT 10 -#define ADC_CR1_DISCEN_BIT 11 -#define ADC_CR1_JDISCEN_BIT 12 -#define ADC_CR1_JAWDEN_BIT 22 +#define ADC_CR1_OVRIE_BIT 26 #define ADC_CR1_AWDEN_BIT 23 - -#define ADC_CR1_AWDCH (0x1F) -#define ADC_CR1_EOCIE BIT(ADC_CR1_EOCIE_BIT) -#define ADC_CR1_AWDIE BIT(ADC_CR1_AWDIE_BIT) -#define ADC_CR1_JEOCIE BIT(ADC_CR1_JEOCIE_BIT) -#define ADC_CR1_SCAN BIT(ADC_CR1_SCAN_BIT) -#define ADC_CR1_AWDSGL BIT(ADC_CR1_AWDSGL_BIT) -#define ADC_CR1_JAUTO BIT(ADC_CR1_JAUTO_BIT) -#define ADC_CR1_DISCEN BIT(ADC_CR1_DISCEN_BIT) -#define ADC_CR1_JDISCEN BIT(ADC_CR1_JDISCEN_BIT) -#define ADC_CR1_DISCNUM (0xE000) -#define ADC_CR1_JAWDEN BIT(ADC_CR1_JAWDEN_BIT) -#define ADC_CR1_AWDEN BIT(ADC_CR1_AWDEN_BIT) +#define ADC_CR1_JAWDEN_BIT 22 +#define ADC_CR1_DISCNUM_SHIFT 13 +#define ADC_CR1_JDISCEN_BIT 12 +#define ADC_CR1_DISCEN_BIT 11 +#define ADC_CR1_JAUTO_BIT 10 +#define ADC_CR1_AWDSGL_BIT 9 +#define ADC_CR1_SCAN_BIT 8 +#define ADC_CR1_JEOCIE_BIT 7 +#define ADC_CR1_AWDIE_BIT 6 +#define ADC_CR1_EOCIE_BIT 5 +#define ADC_CR1_AWDCH_SHIFT 0 + +#define ADC_CR1_OVRIE (0x1 << ADC_CR1_OVRIE_BIT) +#define ADC_CR1_AWDEN (0x1 << ADC_CR1_AWDEN_BIT) +#define ADC_CR1_JAWDEN (0x1 << ADC_CR1_JAWDEN_BIT) +#define ADC_CR1_DISCNUM (0x3 << ADC_CR1_DISCNUM_SHIFT) +#define ADC_CR1_JDISCEN (0x1 << ADC_CR1_JDISCEN_BIT) +#define ADC_CR1_DISCEN (0x1 << ADC_CR1_DISCEN_BIT) +#define ADC_CR1_JAUTO (0x1 << ADC_CR1_JAUTO_BIT) +#define ADC_CR1_AWDSGL (0x1 << ADC_CR1_AWDSGL_BIT) +#define ADC_CR1_SCAN (0x1 << ADC_CR1_SCAN_BIT) +#define ADC_CR1_JEOCIE (0x1 << ADC_CR1_JEOCIE_BIT) +#define ADC_CR1_AWDIE (0x1 << ADC_CR1_AWDIE_BIT) +#define ADC_CR1_EOCIE (0x1 << ADC_CR1_EOCIE_BIT) +#define ADC_CR1_AWDCH (0x1F << ADC_CR1_AWDCH_SHIFT) /* Control register 2 */ -#define ADC_CR2_ADON_BIT 0 -#define ADC_CR2_CONT_BIT 1 -#define ADC_CR2_CAL_BIT 2 -#define ADC_CR2_RSTCAL_BIT 3 -#define ADC_CR2_DMA_BIT 8 -#define ADC_CR2_ALIGN_BIT 11 -#define ADC_CR2_JEXTTRIG_BIT 15 -#define ADC_CR2_EXTTRIG_BIT 20 -#define ADC_CR2_TSVREFE_BIT 23 -#define ADC_CR2_JSWSTART_BIT 22 #define ADC_CR2_SWSTART_BIT 30 -#define ADC_CR2_EXTSEL (0x0F000000) -#define ADC_CR2_JEXTSEL (0x000F0000) - - +#define ADC_CR2_EXTEN_SHIFT 28 +#define ADC_CR2_EXTSEL_SHIFT 24 +#define ADC_CR2_JSWSTART_BIT 22 +#define ADC_CR2_JEXTEN_SHIFT 20 +#define ADC_CR2_JEXTSEL_SHIFT 16 +#define ADC_CR2_ALIGN_BIT 11 +#define ADC_CR2_EOCS_BIT 10 +#define ADC_CR2_DDS_BIT 9 +#define ADC_CR2_DMA_BIT 8 +#define ADC_CR2_CONT_BIT 1 +#define ADC_CR2_ADON_BIT 0 -#define ADC_CR2_ADON BIT(ADC_CR2_ADON_BIT) -#define ADC_CR2_CONT BIT(ADC_CR2_CONT_BIT) -#define ADC_CR2_CAL BIT(ADC_CR2_CAL_BIT) -#define ADC_CR2_RSTCAL BIT(ADC_CR2_RSTCAL_BIT) -#define ADC_CR2_DMA BIT(ADC_CR2_DMA_BIT) -#define ADC_CR2_ALIGN BIT(ADC_CR2_ALIGN_BIT) -#define ADC_CR2_JEXTTRIG BIT(ADC_CR2_JEXTTRIG_BIT) -#define ADC_CR2_EXTTRIG BIT(ADC_CR2_EXTTRIG_BIT) -#define ADC_CR2_JSWSTART BIT(ADC_CR2_JSWSTART_BIT) -#define ADC_CR2_SWSTART BIT(ADC_CR2_SWSTART_BIT) -#define ADC_CR2_TSVREFE BIT(ADC_CR2_TSVREFE_BIT) +#define ADC_CR2_SWSTART (0x1 << ADC_CR2_SWSTART_BIT) +#define ADC_CR2_EXTEN (0x3 << ADC_CR2_EXTEN_SHIFT) +#define ADC_CR2_EXTSEL (0xF << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_JSWSTART (0x1 << ADC_CR2_JSWSTART_BIT) +#define ADC_CR2_JEXTEN (0x3 << ADC_CR2_JEXTEN_SHIFT) +#define ADC_CR2_JEXTSEL (0xF << ADC_CR2_JEXTSEL_SHIFT) +#define ADC_CR2_ALIGN (0x1 << ADC_CR2_ALIGN_BIT) +#define ADC_CR2_EOCS (0x1 << ADC_CR2_EOCS_BIT) +#define ADC_CR2_DDS (0x1 << ADC_CR2_DDS_BIT) +#define ADC_CR2_DMA (0x1 << ADC_CR2_DMA_BIT) +#define ADC_CR2_CONT (0x1 << ADC_CR2_CONT_BIT) +#define ADC_CR2_ADON (0x1 << ADC_CR2_ADON_BIT) /* Sample time register 1 */ +#define ADC_SMPR1_SMP18 (0x7 << 24) #define ADC_SMPR1_SMP17 (0x7 << 21) #define ADC_SMPR1_SMP16 (0x7 << 18) #define ADC_SMPR1_SMP15 (0x7 << 15) @@ -256,48 +274,116 @@ extern const adc_dev ADC3; #define ADC_DR_ADC2DATA (0xFFFF << 16) #define ADC_DR_DATA 0xFFFF +/* Common status register */ + +#define ADC_CSR_OVR3 BIT(21) +#define ADC_CSR_STRT3 BIT(20) +#define ADC_CSR_JSTRT3 BIT(19) +#define ADC_CSR_JEOC3 BIT(18) +#define ADC_CSR_EOC3 BIT(17) +#define ADC_CSR_AWD3 BIT(16) +#define ADC_CSR_OVR2 BIT(13) +#define ADC_CSR_STRT2 BIT(12) +#define ADC_CSR_JSTRT2 BIT(11) +#define ADC_CSR_JEOC2 BIT(10) +#define ADC_CSR_EOC2 BIT(9) +#define ADC_CSR_AWD2 BIT(8) +#define ADC_CSR_OVR1 BIT(5) +#define ADC_CSR_STRT1 BIT(4) +#define ADC_CSR_JSTRT1 BIT(3) +#define ADC_CSR_JEOC1 BIT(2) +#define ADC_CSR_EOC1 BIT(1) +#define ADC_CSR_AWD1 BIT(0) + +/* Common control register */ + +#define ADC_CCR_TSVREFE_BIT 23 +#define ADC_CCR_VBATE_BIT 22 +#define ADC_CCR_ADCPRE_SHIFT 16 +#define ADC_CCR_DMA_SHIFT 14 +#define ADC_CCR_DDS_BIT 13 +#define ADC_CCR_DELAY_SHIFT 8 +#define ADC_CCR_MULTI_SHIFT 0 + + +#define ADC_CCR_TSVREFE (0x1 << ADC_CCR_TSVREFE_BIT) +#define ADC_CCR_VBATE (0x1 << ADC_CCR_VBATE_BIT) +#define ADC_CCR_ADCPRE (0x3 << ADC_CCR_ADCPRE_SHIFT) +#define ADC_CCR_DMA (0x3 << ADC_CCR_DMA_SHIFT) +#define ADC_CCR_DDS (0x1 << ADC_CCR_DDS_BIT) +#define ADC_CCR_DELAY (0xF << ADC_CCR_DELAY_SHIFT) +#define ADC_CCR_MULTI (0x1F << ADC_CCR_MULTI_SHIFT) + +/** + * @brief STM32F1/F4 ADC prescalers, as divisors of PCLK2. + */ +typedef enum adc_prescaler { + /** PCLK2 divided by 2 */ + ADC_PRE_PCLK2_DIV_2 = 0, + /** PCLK2 divided by 4 */ + ADC_PRE_PCLK2_DIV_4 = 1, + /** PCLK2 divided by 6 */ + ADC_PRE_PCLK2_DIV_6 = 2, + /** PCLK2 divided by 8 */ + ADC_PRE_PCLK2_DIV_8 = 3, +} adc_prescaler; + +/* Common regular data register */ + +#define ADC_CDR_DATA2 (0xFFFF << 16) +#define ADC_CDR_DATA1 (0xFFFF) + + void adc_init(const adc_dev *dev); +typedef enum { + ADC_EXT_TRIGGER_DISABLE = 0, + ADC_EXT_TRIGGER_ON_RISING_EDGE = 1, + ADC_EXT_TRIGGER_ON_FALLING_EDGE = 2, + ADC_EXT_TRIGGER_ON_BOTH_EDGES = 3, +} adc_ext_trigger; + /** * @brief External event selector for regular group conversion. * @see adc_set_extsel */ -typedef enum adc_extsel_event { - ADC_ADC12_TIM1_CC1 = (0 << 17), /**< ADC1 and ADC2: Timer 1 CC1 event */ - ADC_ADC12_TIM1_CC2 = (1 << 17), /**< ADC1 and ADC2: Timer 1 CC2 event */ - ADC_ADC12_TIM1_CC3 = (2 << 17), /**< ADC1 and ADC2: Timer 1 CC3 event */ - ADC_ADC12_TIM2_CC2 = (3 << 17), /**< ADC1 and ADC2: Timer 2 CC2 event */ - ADC_ADC12_TIM3_TRGO = (4 << 17), /**< ADC1 and ADC2: Timer 3 TRGO event */ - ADC_ADC12_TIM4_CC4 = (5 << 17), /**< ADC1 and ADC2: Timer 4 CC4 event */ - ADC_ADC12_EXTI11 = (6 << 17), /**< ADC1 and ADC2: EXTI11 event */ -#ifdef STM32_HIGH_DENSITY - ADC_ADC12_TIM8_TRGO = (6 << 17), /**< ADC1 and ADC2: Timer 8 TRGO - event (high density only) */ -#endif - ADC_ADC12_SWSTART = (7 << 17), /**< ADC1 and ADC2: Software start */ -#ifdef STM32_HIGH_DENSITY - ADC_ADC3_TIM3_CC1 = (0 << 17), /**< ADC3: Timer 3 CC1 event - (high density only) */ - ADC_ADC3_TIM2_CC3 = (1 << 17), /**< ADC3: Timer 2 CC3 event - (high density only) */ - ADC_ADC3_TIM1_CC3 = (2 << 17), /**< ADC3: Timer 1 CC3 event - (high density only) */ - ADC_ADC3_TIM8_CC1 = (3 << 17), /**< ADC3: Timer 8 CC1 event - (high density only) */ - ADC_ADC3_TIM8_TRGO = (4 << 17), /**< ADC3: Timer 8 TRGO event - (high density only) */ - ADC_ADC3_TIM5_CC1 = (5 << 17), /**< ADC3: Timer 5 CC1 event - (high density only) */ - ADC_ADC3_TIM5_CC3 = (6 << 17), /**< ADC3: Timer 5 CC3 event - (high density only) */ - ADC_ADC3_SWSTART = (7 << 17), /**< ADC3: Software start (high - density only) */ -#endif - ADC_SWSTART = (7 << 17) /**< ADC1, ADC2, ADC3: Software start */ +typedef enum { + ADC_EXTSEL_TIM1_CC1 = 0, /**< Timer 1 CC1 event */ + ADC_EXTSEL_TIM1_CC2 = 1, /**< Timer 1 CC2 event */ + ADC_EXTSEL_TIM1_CC3 = 2, /**< Timer 1 CC3 event */ + ADC_EXTSEL_TIM2_CC2 = 3, /**< Timer 2 CC2 event */ + ADC_EXTSEL_TIM2_CC3 = 4, /**< Timer 2 CC3 event */ + ADC_EXTSEL_TIM2_CC4 = 5, /**< Timer 2 CC4 event */ + ADC_EXTSEL_TIM2_TRGO = 6, /**< Timer 2 TRGO event */ + ADC_EXTSEL_TIM3_CC1 = 7, /**< Timer 3 CC1 event */ + ADC_EXTSEL_TIM3_TRGO = 8, /**< Timer 3 TRGO event */ + ADC_EXTSEL_TIM4_CC4 = 9, /**< Timer 4 CC4 event */ + ADC_EXTSEL_TIM5_CC1 = 10, /**< Timer 5 CC1 event */ + ADC_EXTSEL_TIM5_CC2 = 11, /**< Timer 5 CC2 event */ + ADC_EXTSEL_TIM5_CC3 = 12, /**< Timer 5 CC3 event */ + ADC_EXTSEL_TIM8_CC1 = 13, /**< Timer 8 CC1 event */ + ADC_EXTSEL_TIM8_TRGO = 14, /**< Timer 8 TRGO event */ + ADC_EXTSEL_EXTI11 = 15, /**< EXTI11 event */ } adc_extsel_event; -void adc_set_extsel(const adc_dev *dev, adc_extsel_event event); -void adc_foreach(void (*fn)(const adc_dev*)); +typedef enum { + ADC_JEXTSEL_TIM1_CC4 = 0, /**< Timer 1 CC4 event */ + ADC_JEXTSEL_TIM1_TRGO = 1, /**< Timer 1 TRGO event */ + ADC_JEXTSEL_TIM2_CC1 = 2, /**< Timer 2 CC1 event */ + ADC_JEXTSEL_TIM2_TRGO = 3, /**< Timer 2 TRGO event */ + ADC_JEXTSEL_TIM3_CC2 = 4, /**< Timer 3 CC2 event */ + ADC_JEXTSEL_TIM3_CC4 = 5, /**< Timer 3 CC4 event */ + ADC_JEXTSEL_TIM4_CC1 = 6, /**< Timer 4 CC1 event */ + ADC_JEXTSEL_TIM4_CC2 = 7, /**< Timer 4 CC2 event */ + ADC_JEXTSEL_TIM4_CC3 = 8, /**< Timer 4 CC3 event */ + ADC_JEXTSEL_TIM4_TRGO = 9, /**< Timer 4 TRGO event */ + ADC_JEXTSEL_TIM5_CC4 = 10, /**< Timer 5 CC4 event */ + ADC_JEXTSEL_TIM5_TRGO = 11, /**< Timer 5 TRGO event */ + ADC_JEXTSEL_TIM8_CC2 = 12, /**< Timer 8 CC2 event */ + ADC_JEXTSEL_TIM8_CC3 = 13, /**< Timer 8 CC3 event */ + ADC_JEXTSEL_TIM8_CC4 = 14, /**< Timer 8 CC4 event */ + ADC_JEXTSEL_EXTI15 = 15, /**< EXTI15 event */ +} adc_jextsel_event; /** * @brief ADC sample times, in ADC clock cycles @@ -305,20 +391,47 @@ void adc_foreach(void (*fn)(const adc_dev*)); * These control the amount of time spent sampling the input voltage. */ typedef enum { - ADC_SMPR_1_5, /**< 1.5 ADC cycles */ - ADC_SMPR_7_5, /**< 7.5 ADC cycles */ - ADC_SMPR_13_5, /**< 13.5 ADC cycles */ - ADC_SMPR_28_5, /**< 28.5 ADC cycles */ - ADC_SMPR_41_5, /**< 41.5 ADC cycles */ - ADC_SMPR_55_5, /**< 55.5 ADC cycles */ - ADC_SMPR_71_5, /**< 71.5 ADC cycles */ - ADC_SMPR_239_5 /**< 239.5 ADC cycles */ + ADC_SMPR_3 = 0, /**< 3 ADC cycles */ + ADC_SMPR_15, /**< 15 ADC cycles */ + ADC_SMPR_28, /**< 28 ADC cycles */ + ADC_SMPR_56, /**< 56 ADC cycles */ + ADC_SMPR_84, /**< 84 ADC cycles */ + ADC_SMPR_112, /**< 112 ADC cycles */ + ADC_SMPR_144, /**< 144 ADC cycles */ + ADC_SMPR_480, /**< 480 ADC cycles */ } adc_smp_rate; -void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate); -void adc_calibrate(const adc_dev *dev); +void adc_set_prescaler(adc_prescaler pre); +void adc_set_sampling_time(const adc_dev *dev, adc_smp_rate smp_rate); +void adc_set_exttrig(const adc_dev *dev, adc_ext_trigger trigger); +void adc_set_jextrig(const adc_dev *dev, adc_ext_trigger trigger); +void adc_set_extsel(const adc_dev *dev, adc_extsel_event event); +void adc_set_jextsel(const adc_dev *dev, adc_jextsel_event event); +void adc_foreach(void (*fn)(const adc_dev*)); +void adc_enable_irq(const adc_dev* dev); +void adc_disable_irq(const adc_dev* dev); +void adc_ovr_enable_irq(const adc_dev* dev); +void adc_attach_interrupt(const adc_dev *dev, adc_irq_id irq_id, voidFuncPtr handler); +void adc_set_reg_sequence(const adc_dev * dev, uint8 * channels, uint8 len); +void adc_enable_tsvref(void); +void adc_enable_vbat(void); + uint16 adc_read(const adc_dev *dev, uint8 channel); +/* + Starts a single conversion in the specified channel. + Results must be read through interrupt or polled outside this function. +*/ +void adc_start_single_convert(const adc_dev* dev, uint8 channel); + +/* + Starts the continuous mode on one channel of the ADC channel. + Results must be read through interrupt or polled outside this function. +*/ +void adc_start_continuous_convert(const adc_dev* dev, uint8 channel); + +void setupADC_F4(void); + /** * @brief Set the regular channel sequence length. * @@ -328,47 +441,123 @@ uint16 adc_read(const adc_dev *dev, uint8 channel); * @param dev ADC device. * @param length Regular channel sequence length, from 1 to 16. */ -static inline void adc_set_reg_seqlen(const adc_dev *dev, uint8 length) { +static inline void adc_set_reg_seqlen(const adc_dev *dev, uint8 length) +{ uint32 tmp = dev->regs->SQR1; tmp &= ~ADC_SQR1_L; tmp |= (length - 1) << 20; dev->regs->SQR1 = tmp; } -/** - * @brief Set external trigger conversion mode event for regular channels - * @param dev ADC device - * @param enable If 1, conversion on external events is enabled; if 0, - * disabled. - */ -static inline void adc_set_exttrig(const adc_dev *dev, uint8 enable) { - *bb_perip(&dev->regs->CR2, ADC_CR2_EXTTRIG_BIT) = !!enable; -} - /** * @brief Enable an adc peripheral * @param dev ADC device to enable */ -static inline void adc_enable(const adc_dev *dev) { - *bb_perip(&dev->regs->CR2, ADC_CR2_ADON_BIT) = 1; +static inline void adc_enable(const adc_dev *dev) +{ + dev->regs->CR2 |= ADC_CR2_ADON; } /** * @brief Disable an ADC peripheral * @param dev ADC device to disable */ -static inline void adc_disable(const adc_dev *dev) { - *bb_perip(&dev->regs->CR2, ADC_CR2_ADON_BIT) = 0; +static inline void adc_disable(const adc_dev *dev) +{ + dev->regs->CR2 &= ~ADC_CR2_ADON; } /** * @brief Disable all ADC peripherals. */ -static inline void adc_disable_all(void) { +static inline void adc_disable_all(void) +{ adc_foreach(adc_disable); } -extern void setupADC_F4(void); +static inline void adc_awd_set_low_limit(const adc_dev * dev, uint32 limit) +{ + dev->regs->LTR = limit; +} + +static inline void adc_awd_set_high_limit(const adc_dev * dev, uint32 limit) +{ + dev->regs->HTR = limit; +} + +static inline void adc_awd_enable_channel(const adc_dev * dev, uint8 awd_channel) +{ + dev->regs->CR1 |= (awd_channel & ADC_CR1_AWDCH); +} + +void adc_awd_enable_irq(const adc_dev * dev); + +static inline void adc_awd_enable(const adc_dev * dev) +{ + dev->regs->CR1 |= ADC_CR1_AWDEN; +} + +static inline void adc_awd_disable(const adc_dev * dev) +{ + dev->regs->CR1 &= ~ADC_CR1_AWDEN; +} + +static inline void adc_set_scan_mode(const adc_dev * dev) +{ + dev->regs->CR1 |= ADC_CR1_SCAN; +} + +static inline void adc_set_continuous(const adc_dev * dev) +{ + dev->regs->CR2 |= ADC_CR2_CONT; +} + +static inline void adc_clear_continuous(const adc_dev * dev) +{ + dev->regs->CR2 &= ~ADC_CR2_CONT; +} + +static inline void adc_dma_disable(const adc_dev * dev) +{ + dev->regs->CR2 &= ~ADC_CR2_DMA; +} + +static inline void adc_dma_enable(const adc_dev * dev) +{ + dev->regs->CR2 |= ADC_CR2_DMA; +} + +static inline void adc_dma_single(const adc_dev * dev) +{ + dev->regs->CR2 &= ~ADC_CR2_DDS; +} + +static inline void adc_dma_continuous(const adc_dev * dev) +{ + dev->regs->CR2 |= ADC_CR2_DDS; +} + +static inline bool adc_is_end_of_convert(const adc_dev * dev) +{ + return (dev->regs->SR&ADC_SR_EOC); +} + +static inline uint16 adc_get_data(const adc_dev * dev) +{ + return dev->regs->DR; +} + +static inline uint16 adc_get_status(const adc_dev * dev) +{ + return dev->regs->SR; +} + +static inline void adc_start_convert(const adc_dev * dev) +{ + dev->regs->CR2 |= ADC_CR2_SWSTART; +} + + #ifdef __cplusplus } // extern "C" diff --git a/STM32F4/cores/maple/libmaple/bitband.h b/STM32F4/cores/maple/libmaple/bitband.h index 73941b0b2..2c4fdb0d1 100644 --- a/STM32F4/cores/maple/libmaple/bitband.h +++ b/STM32F4/cores/maple/libmaple/bitband.h @@ -40,10 +40,10 @@ #define BB_PERI_REF 0x40000000 #define BB_PERI_BASE 0x42000000 -static inline volatile uint32* __bb_addr(volatile void*, - uint32, - uint32, - uint32); + +#define __bb_addr(addr, bit, bb_base, bb_ref) \ + (volatile uint32*)((bb_base) + (((uint32)((uint32)(address) - (bb_ref))) * 32) + ((bit) * 4)) + /** * @brief Obtain a pointer to the bit-band address corresponding to a @@ -51,7 +51,7 @@ static inline volatile uint32* __bb_addr(volatile void*, * @param address Address in the bit-banded SRAM region * @param bit Bit in address to bit-band */ -static inline volatile uint32* bb_sramp(volatile void *address, uint32 bit) { +inline volatile uint32* bb_sramp(volatile void *address, uint32 bit) { return __bb_addr(address, bit, BB_SRAM_BASE, BB_SRAM_REF); } @@ -61,7 +61,7 @@ static inline volatile uint32* bb_sramp(volatile void *address, uint32 bit) { * @param bit Bit in address to read * @return bit's value in address. */ -static inline uint8 bb_sram_get_bit(volatile void *address, uint32 bit) { +inline uint8 bb_sram_get_bit(volatile void *address, uint32 bit) { return *bb_sramp(address, bit); } @@ -71,7 +71,7 @@ static inline uint8 bb_sram_get_bit(volatile void *address, uint32 bit) { * @param bit Bit in address to write to * @param val Value to write for bit, either 0 or 1. */ -static inline void bb_sram_set_bit(volatile void *address, +inline void bb_sram_set_bit(volatile void *address, uint32 bit, uint8 val) { *bb_sramp(address, bit) = val; @@ -83,7 +83,7 @@ static inline void bb_sram_set_bit(volatile void *address, * @param address Address in the bit-banded peripheral region * @param bit Bit in address to bit-band */ -static inline volatile uint32* bb_perip(volatile void *address, uint32 bit) { +inline volatile uint32* bb_perip(volatile void *address, uint32 bit) { return __bb_addr(address, bit, BB_PERI_BASE, BB_PERI_REF); } @@ -93,7 +93,7 @@ static inline volatile uint32* bb_perip(volatile void *address, uint32 bit) { * @param bit Bit in address to read * @return bit's value in address. */ -static inline uint8 bb_peri_get_bit(volatile void *address, uint32 bit) { +inline uint8 bb_peri_get_bit(volatile void *address, uint32 bit) { return *bb_perip(address, bit); } @@ -109,12 +109,4 @@ static inline void bb_peri_set_bit(volatile void *address, *bb_perip(address, bit) = val; } -static inline volatile uint32* __bb_addr(volatile void *address, - uint32 bit, - uint32 bb_base, - uint32 bb_ref) { - return (volatile uint32*)(bb_base + ((uint32)address - bb_ref) * 32 + - bit * 4); -} - #endif /* _BITBAND_H_ */ diff --git a/STM32F4/cores/maple/libmaple/bkp.c b/STM32F4/cores/maple/libmaple/bkp.c index 7d1ad7f01..aab99aa57 100644 --- a/STM32F4/cores/maple/libmaple/bkp.c +++ b/STM32F4/cores/maple/libmaple/bkp.c @@ -29,47 +29,21 @@ * @brief Backup register support. */ -#include "bkp.h" -#include "pwr.h" -#include "rcc.h" -#include "bitband.h" +#include +#include +#include -static inline __io uint32* data_register(uint8 reg); - -bkp_dev bkp = { - .regs = BKP_BASE, -}; -/** Backup device. */ -const bkp_dev *BKP = &bkp; - -/** - * @brief Initialize backup interface. - * - * Enables the power and backup interface clocks, and resets the - * backup device. - */ -void bkp_init(void) { - /* Don't call pwr_init(), or you'll reset the device. We just - * need the clock. */ - rcc_clk_enable(RCC_PWR); - rcc_clk_enable(RCC_BKP); - rcc_reset_dev(RCC_BKP); -} - -/** - * Enable write access to the backup registers. Backup interface must - * be initialized for subsequent register writes to work. - * @see bkp_init() +/* + * returns data register address + * reg is 1 to BKP_NR_DATA_REGS */ -void bkp_enable_writes(void) { - *bb_perip(&PWR_BASE->CR, PWR_CR_DBP) = 1; -} +static __IO uint32* data_register(uint8 reg) +{ + if ( reg==0 || reg > BKP_NR_DATA_REGS) { + return 0; + } -/** - * Disable write access to the backup registers. - */ -void bkp_disable_writes(void) { - *bb_perip(&PWR_BASE->CR, PWR_CR_DBP) = 0; + return (uint32*)BKP + reg - 1; } /** @@ -77,13 +51,13 @@ void bkp_disable_writes(void) { * @param reg Data register to read, from 1 to BKP_NR_DATA_REGS (10 on * medium-density devices, 42 on high-density devices). */ -uint16 bkp_read(uint8 reg) { - __io uint32* dr = data_register(reg); +uint32 bkp_read(uint8 reg) { + __IO uint32* dr = data_register(reg); if (!dr) { ASSERT(0); /* nonexistent register */ return 0; } - return (uint16)*dr; + return *dr; } /** @@ -96,34 +70,58 @@ uint16 bkp_read(uint8 reg) { * @param val Value to write into the register. * @see bkp_enable_writes() */ -void bkp_write(uint8 reg, uint16 val) { - __io uint32* dr = data_register(reg); +void bkp_write(uint8 reg, uint32 val) { + __IO uint32* dr = data_register(reg); if (!dr) { ASSERT(0); /* nonexistent register */ return; } - *dr = (uint32)val; + *dr = val; } /* - * Data register memory layout is not contiguous. It's split up from - * 1--NR_LOW_DRS, beginning at BKP_BASE->DR1, through to - * (NR_LOW_DRS+1)--BKP_NR_DATA_REGS, beginning at BKP_BASE->DR11. + * BKPSRAM functions */ -#define NR_LOW_DRS 10 -static inline __io uint32* data_register(uint8 reg) { - if (reg < 1 || reg > BKP_NR_DATA_REGS) { - return 0; - } +uint8_t bkp_sramread8(uint16_t offset) { + return *((uint8_t *)(BKPSRAM_BASE) + offset); +} -#if BKP_NR_DATA_REGS == NR_LOW_DRS - return (uint32*)BKP_BASE + reg; -#else - if (reg <= NR_LOW_DRS) { - return (uint32*)BKP_BASE + reg; - } else { - return (uint32*)&(BKP_BASE->DR11) + (reg - NR_LOW_DRS - 1); - } -#endif +void bkp_sramwrite8(uint16_t offset, uint8_t data) { + if (offset < BKPSIZE) + *((uint8_t *)(BKPSRAM_BASE) + offset) = data; +} + +uint16_t bkp_sramread16(uint16_t offset) { + return *((uint16_t *)(BKPSRAM_BASE) + offset); +} + +void bkp_sramwrite16(uint16_t offset, uint16_t data) { + uint16_t *p = (uint16_t *)(BKPSRAM_BASE) + offset; + if (offset * 2 < BKPSIZE) + *p = data; +} + +uint32_t bkp_sramread32(uint16_t offset) { + return *((uint32_t *)(BKPSRAM_BASE) + offset); +} + +void bkp_sramwrite32(uint16_t offset, uint32_t data) { + uint32_t *p = (uint32_t *)(BKPSRAM_BASE) + offset; + if (offset * 4 < BKPSIZE) + *p = data; +} + +/* copies data to bkpsram + * + */ +void bkp_sramwrite(uint16_t offset, uint8_t *data, uint16_t length) { + if(length > BKPSIZE - offset) + length = BKPSIZE - offset; + memcpy((void *)(BKPSRAM_BASE + offset), data, length); +} + +void bkpsram_clear() { + memset((void*)BKPSRAM_BASE, 0, BKPSIZE); } + diff --git a/STM32F4/cores/maple/libmaple/bkp.h b/STM32F4/cores/maple/libmaple/bkp.h index a81267d14..5dc886ad7 100644 --- a/STM32F4/cores/maple/libmaple/bkp.h +++ b/STM32F4/cores/maple/libmaple/bkp.h @@ -32,81 +32,56 @@ #ifndef _BKP_H_ #define _BKP_H_ -#include "libmaple.h" #ifdef __cplusplus extern "C" { #endif -#if defined(STM32_MEDIUM_DENSITY) -#define BKP_NR_DATA_REGS 10 -#elif defined(STM32_HIGH_DENSITY) -#define BKP_NR_DATA_REGS 42 -#endif +#include "libmaple.h" +#include "pwr.h" +#include "rcc.h" + + +#define BKP_NR_DATA_REGS 20 /** Backup peripheral register map type. */ +/* +* there are 20 backup registers on stm32 f401, f411, f405, f407, f427, f429 devices. +* in addition for the larger devices e.g. f405, f407, f427, f429 there is an additional +* 4KB backup sram. bkp_reg_map mainly maps the 20 backup registers. +*/ + typedef struct bkp_reg_map { - const uint32 RESERVED1; ///< Reserved - __io uint32 DR1; ///< Data register 1 - __io uint32 DR2; ///< Data register 2 - __io uint32 DR3; ///< Data register 3 - __io uint32 DR4; ///< Data register 4 - __io uint32 DR5; ///< Data register 5 - __io uint32 DR6; ///< Data register 6 - __io uint32 DR7; ///< Data register 7 - __io uint32 DR8; ///< Data register 8 - __io uint32 DR9; ///< Data register 9 - __io uint32 DR10; ///< Data register 10 - __io uint32 RTCCR; ///< RTC control register - __io uint32 CR; ///< Control register - __io uint32 CSR; ///< Control and status register -#ifdef STM32_HIGH_DENSITY - const uint32 RESERVED2; ///< Reserved - const uint32 RESERVED3; ///< Reserved - __io uint32 DR11; ///< Data register 11 - __io uint32 DR12; ///< Data register 12 - __io uint32 DR13; ///< Data register 13 - __io uint32 DR14; ///< Data register 14 - __io uint32 DR15; ///< Data register 15 - __io uint32 DR16; ///< Data register 16 - __io uint32 DR17; ///< Data register 17 - __io uint32 DR18; ///< Data register 18 - __io uint32 DR19; ///< Data register 19 - __io uint32 DR20; ///< Data register 20 - __io uint32 DR21; ///< Data register 21 - __io uint32 DR22; ///< Data register 22 - __io uint32 DR23; ///< Data register 23 - __io uint32 DR24; ///< Data register 24 - __io uint32 DR25; ///< Data register 25 - __io uint32 DR26; ///< Data register 26 - __io uint32 DR27; ///< Data register 27 - __io uint32 DR28; ///< Data register 28 - __io uint32 DR29; ///< Data register 29 - __io uint32 DR30; ///< Data register 30 - __io uint32 DR31; ///< Data register 31 - __io uint32 DR32; ///< Data register 32 - __io uint32 DR33; ///< Data register 33 - __io uint32 DR34; ///< Data register 34 - __io uint32 DR35; ///< Data register 35 - __io uint32 DR36; ///< Data register 36 - __io uint32 DR37; ///< Data register 37 - __io uint32 DR38; ///< Data register 38 - __io uint32 DR39; ///< Data register 39 - __io uint32 DR40; ///< Data register 40 - __io uint32 DR41; ///< Data register 41 - __io uint32 DR42; ///< Data register 42 -#endif + __IO uint32 DR1; ///< Data register 1 + __IO uint32 DR2; ///< Data register 2 + __IO uint32 DR3; ///< Data register 3 + __IO uint32 DR4; ///< Data register 4 + __IO uint32 DR5; ///< Data register 5 + __IO uint32 DR6; ///< Data register 6 + __IO uint32 DR7; ///< Data register 7 + __IO uint32 DR8; ///< Data register 8 + __IO uint32 DR9; ///< Data register 9 + __IO uint32 DR10; ///< Data register 10 + __IO uint32 DR11; ///< Data register 11 + __IO uint32 DR12; ///< Data register 12 + __IO uint32 DR13; ///< Data register 13 + __IO uint32 DR14; ///< Data register 14 + __IO uint32 DR15; ///< Data register 15 + __IO uint32 DR16; ///< Data register 16 + __IO uint32 DR17; ///< Data register 17 + __IO uint32 DR18; ///< Data register 18 + __IO uint32 DR19; ///< Data register 19 + __IO uint32 DR20; ///< Data register 20 } bkp_reg_map; /** Backup peripheral register map base pointer. */ -#define BKP_BASE ((struct bkp_reg_map*)0x40006C00) +#define BKP ((struct bkp_reg_map*)(0x40002800 + 0x50)) -/** Backup peripheral device type. */ -typedef struct bkp_dev { - bkp_reg_map *regs; /**< Register map */ -} bkp_dev; +// Backup SRAM(4 KB) base address +#define BKPSRAM_BASE 0x40024000UL +//4KB +#define BKPSIZE 4096 -extern const bkp_dev *BKP; /* * Register bit definitions @@ -114,50 +89,140 @@ extern const bkp_dev *BKP; /* Data Registers */ -#define BKP_DR_D 0xFFFF +#define BKP_DR_D 0xFFFFFFFF + +/* + * Convenience functions + */ +/** + * Enable write access to the backup registers. Backup interface must + * be initialized for subsequent register writes to work. + * @see bkp_init() + */ +__always_inline void bkp_enable_writes(void) { + *bb_perip(&PWR->CR, PWR_CR_DBP_BIT) = 1; +} + +/** + * Disable write access to the backup registers. + */ +__always_inline void bkp_disable_writes(void) { + *bb_perip(&PWR->CR, PWR_CR_DBP_BIT) = 0; +} + + +/** + * @brief Initialize backup interface. + * + * note that bkp_init() merely enables the backup domain clocks. + * This is not adequate to use backup domain registers and sram. + * + * to access backup registers it is necessary to initiate RTC clock + * e.g. + * RTClock rt; + * void setup() { + * bkp_init(); + * rt.begin(); + * + * // enable writes before writing to bkp registers + * // or it will hardfault, freeze + * bkp_enable_writes(); + * bkp_write(1, 100); //write 100 in bkp register 1 + * bkp_disable_writes(); + * + * int32_t regval = bkp_read(1); // read register 1 + * } + * + * if you want to access backup SRAM in addition to bkp_init() + * it is necessary to call bkp_initsram(), e.g: + * + * void setup() { + * bkp_init(); + * bkp_initsram(true); + * rt.begin(); + * + * ... + * } + * + */ +__always_inline void bkp_init(void) { + rcc_clk_enable(RCC_PWR); + /* Don't call pwr_init(), or you'll reset the device. + * We just need the clock. + pwr_init(); + */ +} + +/* + * enable BKPSRAM + * requires bkp_init() to be called prior + * + * @param bkreg + * true enable the backup power regulator, runs on VBAT e.g. coin cell + * false BKPSRAM is lost if VDD is lost, but preserves across a reset + */ +__always_inline void bkp_initsram(bool bkreg) { + + bkp_enable_writes(); + + //enable backup sram + RCC->AHB1ENR |= RCC_AHB1ENR_BKPSRAMEN; + + if(bkreg) + PWR->CSR |= PWR_CSR_BRE; + else + PWR->CSR &= ~PWR_CSR_BRE; -/* RTC Clock Calibration Register */ +} -#define BKP_RTCCR_ASOS_BIT 9 -#define BKP_RTCCR_ASOE_BIT 8 -#define BKP_RTCCR_CCO_BIT 7 +/* functions to read/write bkp registers + * note that prior to bkp_write() it is necessary to call + * bkp_enable_writes() + */ -#define BKP_RTCCR_ASOS BIT(BKP_RTCCR_ASOS_BIT) -#define BKP_RTCCR_ASOE BIT(BKP_RTCCR_ASOE_BIT) -#define BKP_RTCCR_CCO BIT(BKP_RTCCR_CCO_BIT) -#define BKP_RTCCR_CAL 0x7F +uint32 bkp_read(uint8 reg); -/* Backup control register */ +void bkp_write(uint8 reg, uint32 val); -#define BKP_CR_TPAL_BIT 1 -#define BKP_CR_TPE_BIT 0 -#define BKP_CR_TPAL BIT(BKP_CR_TPAL_BIT) -#define BKP_CR_TPE BIT(BKP_CR_TPE_BIT) +/* functions to read write bkp sram + * + * note that the offset is indexed by word sized entries + * zero is the first offset + * e.g. bkp_sramwrite32(9, data) writes to the 10th 32 bit uint32 field + * + * prior to writing bkp_sram it is necessary to call + * bkp_enable_writes() + * + */ +uint8_t bkp_sramread8(uint16_t offset); -/* Backup control/status register */ +void bkp_sramwrite8(uint16_t offset, uint8_t data); -#define BKP_CSR_TIF_BIT 9 -#define BKP_CSR_TEF_BIT 8 -#define BKP_CSR_TPIE_BIT 2 -#define BKP_CSR_CTI_BIT 1 -#define BKP_CSR_CTE_BIT 0 +uint16_t bkp_sramread16(uint16_t offset); -#define BKP_CSR_TIF BIT(BKP_CSR_TIF_BIT) -#define BKP_CSR_TEF BIT(BKP_CSR_TEF_BIT) -#define BKP_CSR_TPIE BIT(BKP_CSR_TPIE_BIT) -#define BKP_CSR_CTI BIT(BKP_CSR_CTI_BIT) -#define BKP_CSR_CTE BIT(BKP_CSR_CTE_BIT) +void bkp_sramwrite16(uint16_t offset, uint16_t data); -/* - * Convenience functions +uint32_t bkp_sramread32(uint16_t offset); + +void bkp_sramwrite32(uint16_t offset, uint32_t data); + +/* note this simply returns a pointer to the BKPSRAM + offset + * BKPSRAM is normally 4KB, this does not check if you were to read beyond that 4KB */ +inline uint8_t* bkp_sramread(uint16_t offset) { + return (uint8_t *)(BKPSRAM_BASE + offset); +} -void bkp_init(void); -void bkp_enable_writes(void); -void bkp_disable_writes(void); -uint16 bkp_read(uint8 reg); -void bkp_write(uint8 reg, uint16 val); +/* copies data to bkpsram + * note this truncate data that doesn't fit in BKPSIZE - offset + * */ +void bkp_sramwrite(uint16_t offset, uint8_t *data, uint16_t length); + +/* + * clear bkpsram entirely + */ +void bkpsram_clear(); #ifdef __cplusplus } /* extern "C" */ diff --git a/STM32F4/cores/maple/libmaple/dac.c b/STM32F4/cores/maple/libmaple/dac.c index 3853f903c..bf421467d 100644 --- a/STM32F4/cores/maple/libmaple/dac.c +++ b/STM32F4/cores/maple/libmaple/dac.c @@ -33,123 +33,142 @@ #include "gpio.h" #include "dac.h" -#ifdef STM32_HIGH_DENSITY /** * @brief DAC peripheral routines. */ -dac_dev dac = { +/** DAC device. */ +dac_dev_t const dac_dev = { .regs = DAC_BASE, }; -/** DAC device. */ -const dac_dev *DAC = &dac; /** * @brief Initialize the digital to analog converter - * @param dev DAC device - * @param flags Flags: - * DAC_CH1: Enable channel 1 - * DAC_CH2: Enable channel 2 - * @sideeffect May set PA4 or PA5 to INPUT_ANALOG */ -void dac_init(const dac_dev *dev, uint32 flags) { - /* First turn on the clock */ +void dac_init() +{ rcc_clk_enable(RCC_DAC); rcc_reset_dev(RCC_DAC); +} + +/** + * @brief Write a 12-bit value to the DAC to output + * @param channel channel to select (1 or 2) + * @param val value to write + */ +void dac_write_channel(dac_channel_t channel, uint16 val) +{ + if (channel & DAC_CH1) { + DAC->regs->DHR12R1 = DAC_DHR12R_MASK & val; + } + if (channel & DAC_CH2) { + DAC->regs->DHR12R2 = DAC_DHR12R_MASK & val; + } +} - if (flags & DAC_CH1) { - dac_enable_channel(dev, 1); +void dac_set_mask_amplitude(dac_channel_t channel, uint16 val) +{ + val &= DAC_CR_MAMP_MASK; + if (channel & DAC_CH1) { + DAC->regs->CR = (DAC->regs->CR&(~DAC_CR_MAMP1)) | (val<regs->CR = (DAC->regs->CR&(~DAC_CR_MAMP2)) | (val<regs->CR = (DAC->regs->CR&(~DAC_CR_WAVE1)) | (val<regs->CR = (DAC->regs->CR&(~DAC_CR_WAVE2)) | (val<regs->CR &= ~DAC_CR_TSEL1; + DAC->regs->CR |= (val<regs->CR &= ~DAC_CR_TSEL2; + DAC->regs->CR |= (val<regs->SWTRIGR = channel & (DAC_CH1 | DAC_CH2); } /** - * @brief Initialize the output buffer of the digital to analog converter - * @param dev DAC device - * @param flags Flags: + * @brief Enable/disable the output buffer of the digital to analog converter + * @param channel Flags: * DAC_CH1: Select channel 1 * DAC_CH2: Select channel 2 - * @param status Status: - * 1: enable buffer - * 0: disable buffer */ -void dac_enable_buffer(const dac_dev *dev, uint32 flags, int status) { - if (flags & DAC_CH1) { - if(status) { - dev->regs->CR &= ~DAC_CR_BOFF1; - } else { - dev->regs->CR |= DAC_CR_BOFF1; - } - } - - if (flags & DAC_CH2) { - if(status) { - dev->regs->CR &= ~DAC_CR_BOFF2; - } else { - dev->regs->CR |= DAC_CR_BOFF2; - } - } +void dac_enable_buffer(uint8 channel) +{ + uint32 flags = (channel&DAC_CH1)<<1 | (channel&DAC_CH2)<<16; + DAC->regs->CR |= flags; // enable the buffers simultanously } +void dac_disable_buffer(uint8 channel) +{ + uint32 flags = (channel&DAC_CH1)<<1 | (channel&DAC_CH2)<<16; + DAC->regs->CR &= ~flags; // disable the buffers simultanously +} /** - * @brief Write a 12-bit value to the DAC to output - * @param dev DAC device - * @param channel channel to select (1 or 2) - * @param val value to write + * @brief Enable/disable DMA request on trigger occurance + * @param channel Flags: + * DAC_CH1: Select channel 1 + * DAC_CH2: Select channel 2 */ -void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val) { - switch(channel) { - case 1: - dev->regs->DHR12R1 = DAC_DHR12R1_DACC1DHR & val; - break; - case 2: - dev->regs->DHR12R2 = DAC_DHR12R2_DACC2DHR & val; - break; - } +void dac_enable_dma(dac_channel_t channel) +{ + uint32 flags = (channel&DAC_CH1)<<12 | (channel&DAC_CH2)<<27; + DAC->regs->CR |= flags; // enable the channels simultanously +} + +void dac_disable_dma(dac_channel_t channel) +{ + uint32 flags = (channel&DAC_CH1)<<12 | (channel&DAC_CH2)<<27; + DAC->regs->CR &= ~flags; // disable the channels simultanously } /** * @brief Enable a DAC channel - * @param dev DAC device - * @param channel channel to enable, either 1 or 2 - * @sideeffect May change pin mode of PA4 or PA5 + * @param channel channel to enable, 1 and/or 2 + * @sideeffect Changes pin mode of PA4 or PA5 */ -void dac_enable_channel(const dac_dev *dev, uint8 channel) { - /* - * Setup ANALOG mode on PA4 and PA5. This mapping is consistent across - * all STM32 chips with a DAC. See RM0008 12.2. - */ - switch (channel) { - case 1: - gpio_set_mode((uint8_t)PA4, GPIO_INPUT_ANALOG); - dev->regs->CR |= DAC_CR_EN1; - break; - case 2: - gpio_set_mode((uint8_t)PA5, GPIO_INPUT_ANALOG); - dev->regs->CR |= DAC_CR_EN2; - break; +void dac_enable(dac_channel_t channel) +{ + // Setup ANALOG mode on PA4 and PA5. This mapping is consistent across + // all STM32 chips with a DAC. See RM0008 12.2. + if (channel & DAC_CH1) { + gpio_set_mode(PA4, GPIO_INPUT_ANALOG); + } + if (channel & DAC_CH2) { + gpio_set_mode(PA5, GPIO_INPUT_ANALOG); } + uint32 flags = (channel&DAC_CH1) | (channel&DAC_CH2)<<15; + DAC->regs->CR |= flags; // enable the channels simultanously } /** * @brief Disable a DAC channel - * @param dev DAC device - * @param channel channel to disable, either 1 or 2 + * @param channel channel to disable, 1 and/or 2 */ -void dac_disable_channel(const dac_dev *dev, uint8 channel) { - switch (channel) { - case 1: - dev->regs->CR &= ~DAC_CR_EN1; - break; - case 2: - dev->regs->CR &= ~DAC_CR_EN2; - break; - } +void dac_disable(dac_channel_t channel) +{ + uint32 flags = (channel&DAC_CH1) | (channel&DAC_CH2)<<15; + DAC->regs->CR &= ~flags; // disable the channels simultanously } - -#endif /* STM32_HIGH_DENSITY */ diff --git a/STM32F4/cores/maple/libmaple/dac.h b/STM32F4/cores/maple/libmaple/dac.h index dd1b22bda..16ad1f4ab 100644 --- a/STM32F4/cores/maple/libmaple/dac.h +++ b/STM32F4/cores/maple/libmaple/dac.h @@ -46,28 +46,29 @@ extern "C"{ /** DAC register map. */ typedef struct dac_reg_map { - __io uint32 CR; /**< Control register */ - __io uint32 SWTRIGR; /**< Software trigger register */ - __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data + __IO uint32 CR; /**< Control register */ + __IO uint32 SWTRIGR; /**< Software trigger register */ + __IO uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data holding register */ - __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data + __IO uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data holding register */ - __io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data + __IO uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data holding register */ - __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data + __IO uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data holding register */ - __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data + __IO uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data holding register */ - __io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data + __IO uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data holding register */ - __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data + __IO uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data holding register */ - __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data + __IO uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data holding register */ - __io uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding + __IO uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding register */ - __io uint32 DOR1; /**< Channel 1 data output register */ - __io uint32 DOR2; /**< Channel 2 data output register */ + __IO uint32 DOR1; /**< Channel 1 data output register */ + __IO uint32 DOR2; /**< Channel 2 data output register */ + __IO uint32 SR; /**< Status register */ } dac_reg_map; /** DAC register map base address */ @@ -78,17 +79,26 @@ typedef struct dac_reg_map { */ /** DAC device type. */ -typedef struct dac_dev { +typedef struct dac_dev_t { dac_reg_map *regs; /**< Register map */ -} dac_dev; - -extern const dac_dev *DAC; +} dac_dev_t; +extern dac_dev_t const dac_dev; +#define DAC (&dac_dev) /* * Register bit definitions */ /* Control register */ +#define DAC_CR_TSEL1_SHIFT 3 +#define DAC_CR_WAVE1_SHIFT 6 +#define DAC_CR_MAMP1_SHIFT 8 +#define DAC_CR_TSEL2_SHIFT 19 +#define DAC_CR_WAVE2_SHIFT 22 +#define DAC_CR_MAMP2_SHIFT 24 +#define DAC_CR_TSEL_MASK 0x7 +#define DAC_CR_WAVE_MASK 0x3 +#define DAC_CR_MAMP_MASK 0xF /* Channel 1 control */ #define DAC_CR_EN1 BIT(0) /* Enable */ #define DAC_CR_BOFF1 BIT(1) /* Output buffer disable */ @@ -97,6 +107,7 @@ extern const dac_dev *DAC; #define DAC_CR_WAVE1 (0x3 << 6) /* Noise/triangle wave enable */ #define DAC_CR_MAMP1 (0xF << 8) /* Mask/amplitude selector */ #define DAC_CR_DMAEN1 BIT(12) /* DMA enable */ +#define DAC_CR_DMAUDRIE1 BIT(13) /* DMA underrun interrupt enable */ /* Channel 2 control */ #define DAC_CR_EN2 BIT(16) /* Enable */ #define DAC_CR_BOFF2 BIT(17) /* Output buffer disable */ @@ -105,46 +116,53 @@ extern const dac_dev *DAC; #define DAC_CR_WAVE2 (0x3 << 22) /* Noise/triangle wave generation*/ #define DAC_CR_MAMP2 (0xF << 24) /* Mask/amplitude selector */ #define DAC_CR_DMAEN2 BIT(28) /* DMA enable */ +#define DAC_CR_DMAUDRIE2 BIT(29) /* DMA underrun interrupt enable */ + +typedef enum dac_wave_t { +DAC_WAVE_DISABLED = 0, +DAC_WAVE_NOISE = 1, +DAC_WAVE_TRIANGLE = 2, +} dac_wave_t; + +typedef enum dac_trigger_t { +DAC_TRG_TIMER6TRGO = 0, +DAC_TRG_TIMER8TRGO = 1, +DAC_TRG_TIMER7TRGO = 2, +DAC_TRG_TIMER5TRGO = 3, +DAC_TRG_TIMER2TRGO = 4, +DAC_TRG_TIMER4TRGO = 5, +DAC_TRG_EXT9 = 6, +DAC_TRG_SW = 7, +} dac_trigger_t; /* Software trigger register */ #define DAC_SWTRIGR_SWTRIG1 BIT(0) /* Channel 1 software trigger */ #define DAC_SWTRIGR_SWTRIG2 BIT(1) /* Channel 2 software trigger */ -/* Channel 1 12-bit right-aligned data holding register */ -#define DAC_DHR12R1_DACC1DHR 0x00000FFF - -/* Channel 1 12-bit left-aligned data holding register */ -#define DAC_DHR12L1_DACC1DHR 0x0000FFF0 - -/* Channel 1 8-bit left-aligned data holding register */ -#define DAC_DHR8R1_DACC1DHR 0x000000FF +// 12-bit right-aligned data mask +#define DAC_DHR12R_MASK 0x00000FFF -/* Channel 2 12-bit right-aligned data holding register */ -#define DAC_DHR12R2_DACC2DHR 0x00000FFF +// 12-bit left-aligned data mask +#define DAC_DHR12L_MASK 0x0000FFF0 -/* Channel 2 12-bit left-aligned data holding register */ -#define DAC_DHR12L2_DACC2DHR 0x0000FFF0 +// 8-bit right-aligned data mask +#define DAC_DHR8R_MASK 0x000000FF -/* Channel 2 8-bit left-aligned data holding register */ -#define DAC_DHR8R2_DACC2DHR 0x000000FF +// Dual DAC 12-bit right-aligned data masks +#define DAC_DHR12RD_CH1_MASK 0x00000FFF +#define DAC_DHR12RD_CH2_MASK 0x0FFF0000 -/* Dual DAC 12-bit right-aligned data holding register */ -#define DAC_DHR12RD_DACC1DHR 0x00000FFF -#define DAC_DHR12RD_DACC2DHR 0x0FFF0000 +// Dual DAC 12-bit left-aligned data masks +#define DAC_DHR12LD_CH1_MASK 0x0000FFF0 +#define DAC_DHR12LD_CH2_MASK 0xFFF00000 -/* Dual DAC 12-bit left-aligned data holding register */ -#define DAC_DHR12LD_DACC1DHR 0x0000FFF0 -#define DAC_DHR12LD_DACC2DHR 0xFFF00000 +// Dual DAC 8-bit right-aligned data masks +#define DAC_DHR8RD_CH1_MASK 0x000000FF +#define DAC_DHR8RD_CH2_MASK 0x0000FF00 -/* Dual DAC 8-bit left-aligned data holding register */ -#define DAC_DHR8RD_DACC1DHR 0x000000FF -#define DAC_DHR8RD_DACC2DHR 0x0000FF00 +// Data output register +#define DAC_DOR_DACCDOR 0x00000FFF -/* Channel 1 data output register */ -#define DAC_DOR1_DACC1DOR 0x00000FFF - -/* Channel 1 data output register */ -#define DAC_DOR2_DACC2DOR 0x00000FFF /* * Convenience functions @@ -152,15 +170,23 @@ extern const dac_dev *DAC; /* We take the dev argument in these convenience functions for * future-proofing */ - -#define DAC_CH1 0x1 -#define DAC_CH2 0x2 -void dac_init(const dac_dev *dev, uint32 flags); - -void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val); -void dac_enable_channel(const dac_dev *dev, uint8 channel); -void dac_disable_channel(const dac_dev *dev, uint8 channel); -void dac_enable_buffer(const dac_dev *dev, uint32 flags, int status); +typedef enum { +DAC_CH1 = 1, +DAC_CH2 = 2, +} dac_channel_t; + +extern void dac_init(); +extern void dac_write_channel(dac_channel_t channel, uint16 val); +extern void dac_set_mask_amplitude(dac_channel_t channel, uint16 val); +extern void dac_set_wave(dac_channel_t channel, dac_wave_t val); +extern void dac_set_trigger(dac_channel_t channel, dac_trigger_t val); +extern void dac_sw_trigger(dac_channel_t channel); +extern void dac_enable_buffer(dac_channel_t channel); +extern void dac_disable_buffer(dac_channel_t channel); +extern void dac_enable_dma(dac_channel_t channel); +extern void dac_disable_dma(dac_channel_t channel); +extern void dac_enable(dac_channel_t channel); +extern void dac_disable(dac_channel_t channel); #ifdef __cplusplus } // extern "C" diff --git a/STM32F4/cores/maple/libmaple/dcmi.c b/STM32F4/cores/maple/libmaple/dcmi.c new file mode 100644 index 000000000..fa654584b --- /dev/null +++ b/STM32F4/cores/maple/libmaple/dcmi.c @@ -0,0 +1,157 @@ +//----------------------------------------------------------------------------- +// @file dcmi.c +// @brief Direct camera memory interface support. +//----------------------------------------------------------------------------- + +#include "dcmi.h" +#include "gpio.h" + + +#ifdef DCMI_D0 // pins not yet defined for disco F407 + + +voidFuncPtr dcmi_irq_handler = NULL; + +// DCMI device +const dcmi_dev dcmi = +{ + .regs = DCMI_BASE, + .clk_id = RCC_DCMI, + .handler_p = &dcmi_irq_handler, +}; + +// +// DCMI routines +// +void dcmi_init(void) +{ + rcc_clk_enable(RCC_DCMI); + rcc_reset_dev(RCC_DCMI); +} + +//----------------------------------------------------------------------------- +// Configure DCMI control and data lines +// !!! Avoid overlapping with FSMC lines !!! +//----------------------------------------------------------------------------- +const uint8_t dcmi_pins[] = +{ + DCMI_PCLK, DCMI_HSYNC, DCMI_VSYNC, + DCMI_D0, DCMI_D1, DCMI_D2, DCMI_D3, DCMI_D4, DCMI_D5, DCMI_D6, DCMI_D7, +//DCMI_D8, DCMI_D9, DCMI_D10, DCMI_D11, DCMI_D12, DCMI_D13 +}; + +void dcmi_init_gpios(void) +{ + for (uint8_t i=0; iregs->CR & 0xFFFFB000; // reserved bits mask + DCMI->regs->CR = cr | flags; +} + +void dcmi_set_data_width(uint16 data_width) +{ + uint32 cr = DCMI->regs->CR & (~DCMI_CR_EDM); + DCMI->regs->CR = cr | data_width; +} + +void dcmi_set_vspol(uint8 vspol) +{ + uint32 cr = DCMI->regs->CR & (~DCMI_CR_VSPOL); + DCMI->regs->CR = cr | vspol; +} + +void dcmi_set_hspol(uint8 hspol) +{ + uint32 cr = DCMI->regs->CR & (~DCMI_CR_HSPOL); + DCMI->regs->CR = cr | hspol; +} + +void dcmi_set_pckpol(uint8 pckpol) +{ + uint32 cr = DCMI->regs->CR & (~DCMI_CR_PCKPOL); + DCMI->regs->CR = cr | pckpol; +} + +void dcmi_set_mode(uint8 capture_mode) +{ + uint32 cr = DCMI->regs->CR & (~DCMI_CR_CM); + DCMI->regs->CR = cr | capture_mode; +} + +void dcmi_set_sync_mode(uint8 ess) +{ + uint32 cr = DCMI->regs->CR & (~DCMI_CR_ESS); + DCMI->regs->CR = cr | ess; +} + +void dcmi_attach_interrupt(voidFuncPtr handler, uint8_t irq_mask) +{ + DCMI->regs->IER |= irq_mask; + dcmi_irq_handler = handler; + nvic_irq_enable(NVIC_DCMI); +} + +void dcmi_detach_interrupt(uint8_t irq_mask) +{ + DCMI->regs->IER &= (~irq_mask); + if (DCMI->regs->IER==0) + { + nvic_irq_disable(NVIC_DCMI); + dcmi_irq_handler = NULL; + } +} + +//----------------------------------------------------------------------------- +// Configure DMA2, channel 1, stream 1 (alternative: stream 7) +//----------------------------------------------------------------------------- +void dcmi_dma_config(uint32_t * buf, uint16 bufLen, voidFuncPtr func) +{ + dma_init(DMA2); + dma_setup_transfer(DMA2, DMA_STREAM1, DMA_CH1, DMA_SIZE_32BITS, + &(DCMI->regs->DR), buf, NULL, + (DMA_PRIO_VERY_HIGH | DMA_MINC_MODE | DMA_CIRC_MODE | DMA_TRNS_HALF | DMA_TRNS_CMPLT)); + + dma_set_num_transfers(DMA2, DMA_STREAM1, bufLen); + dma_set_fifo_flags(DMA2, DMA_STREAM1, (DMA_FCR_DMDIS|DMA_FCR_FTH_2_4)); + //dma_set_fifo_flags(DMA2, DMA_STREAM1, 0); + dma_clear_isr_bits(DMA2, DMA_STREAM1); + //if there is an int handler to be attached + if (func != NULL) + dma_attach_interrupt(DMA2, DMA_STREAM1, func); + + dma_enable(DMA2, DMA_STREAM1); +} +//----------------------------------------------------------------------------- +void dcmi_dma_reset(uint16 bufLen) +{ + dcmi_disable_capture(); // disable capture with DMA + dma_disable(DMA2, DMA_STREAM1); + dma_set_num_transfers(DMA2, DMA_STREAM1, bufLen); + //dma_set_fifo_flags(DMA2, DMA_STREAM1, (DMA_FCR_DMDIS|DMA_FCR_FTH_1_4)); + dma_clear_isr_bits(DMA2, DMA_STREAM1); + dma_enable(DMA2, DMA_STREAM1); + dcmi_enable_capture(); // enable capture with DMA +} +//----------------------------------------------------------------------------- +void __irq_dcmi(void) +{ + if (dcmi_irq_handler) + dcmi_irq_handler(); + dcmi_clear_irq_flags(); +} + +#endif // VARIANT_generic_f407v diff --git a/STM32F4/cores/maple/libmaple/dcmi.h b/STM32F4/cores/maple/libmaple/dcmi.h new file mode 100644 index 000000000..4de2e8e24 --- /dev/null +++ b/STM32F4/cores/maple/libmaple/dcmi.h @@ -0,0 +1,212 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Bryan Newbold. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file dcmi.h + * @brief Direct camera memory interface support. + */ + +#ifndef _DCMI_H_ +#define _DCMI_H_ + + +#include "util.h" +#include "libmaple_types.h" +#include "dmaF4.h" + + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* + * Register maps and devices + */ + +/** FSMC register map type */ +typedef struct dcmi_reg_map { + __IO uint32 CR; // Control Register + __IO uint32 SR; // Status Register + __IO uint32 RIS; // Raw Interrupt Status register + __IO uint32 IER; // Interrupt Enable Register + __IO uint32 MIS; // Masked Interrupt Status Register + __IO uint32 ICR; // Interrupt Clear Register + __IO uint32 ESCR; // Embedded Synchronization Code Register + __IO uint32 ESUR; // Embedded Synchronization Unmask Register + __IO uint32 CWSTRT; // Crop Window Start + __IO uint32 CWSIZE; // Crop Window Size + __IO uint32 DR; // Data Register +} dcmi_reg_map; + +// DCMI register map base pointer +#define DCMI_BASE (struct dcmi_reg_map *)0x50050000 + +typedef struct dcmi_dev { + dcmi_reg_map * regs; // Register map + rcc_clk_id clk_id; // Clock ID + voidFuncPtr * handler_p; // IRQ handler pointer +} dcmi_dev; + +// DCMI device +extern const dcmi_dev dcmi; +#define DCMI (&dcmi) + + +// +// Register bit definitions +// + +// Control Register +#define DCMI_CR_ENABLE BIT(14) + +#define DCMI_CR_EDM (0x3 << 10) +#define DCMI_DATA_WIDTH_8BIT (0x0 << 10) +#define DCMI_DATA_WIDTH_10BIT (0x1 << 10) +#define DCMI_DATA_WIDTH_12BIT (0x2 << 10) +#define DCMI_DATA_WIDTH_14BIT (0x3 << 10) + +#define DCMI_CR_FCRC (0x3 << 8) +#define DCMI_FRAMES_EACH (0x0 << 8) +#define DCMI_FRAMES_ONE_OF_2 (0x1 << 8) +#define DCMI_FRAMES_ONE_OF_4 (0x2 << 8) + +#define DCMI_CR_VSPOL BIT(7) +#define DCMI_VSPOL_LOW (0 << 7) +#define DCMI_VSPOL_HIGH (1 << 7) + +#define DCMI_CR_HSPOL BIT(6) +#define DCMI_HSPOL_LOW (0 << 6) +#define DCMI_HSPOL_HIGH (1 << 6) + +#define DCMI_CR_PCKPOL BIT(5) +#define DCMI_PCKPOL_FALLING (0 << 5) +#define DCMI_PCKPOL_RISING (1 << 5) + +#define DCMI_CR_ESS BIT(4) +#define DCMI_SYNC_HW (0 << 4) +#define DCMI_SYNC_EMBEDDED (1 << 4) + +#define DCMI_CR_JPEG BIT(3) +#define DCMI_JPEG_DISABLE (0 << 3) +#define DCMI_JPEG_ENABLE (1 << 3) + +#define DCMI_CR_CROP BIT(2) +#define DCMI_CROP_DISABLE (0 << 2) +#define DCMI_CROP_ENABLE (1 << 2) + +#define DCMI_CR_CM BIT(1) +#define DCMI_MODE_CONTINUOUS (0 << 1) +#define DCMI_MODE_SINGLE (1 << 1) + +#define DCMI_CR_CAPTURE BIT(0) +#define DCMI_CAPTURE_DISABLE (0 << 0) +#define DCMI_CAPTURE_ENABLE (1 << 0) + +// Status Register +#define DCMI_SR_FNE BIT(2) +#define DCMI_SR_VSYNC BIT(1) +#define DCMI_SR_HSYNC BIT(0) + +// Raw Interrupt Status Register +// Interrupt Enable Register +// Masked Interrupt Status Register +// Interrupt Clear Register +#define DCMI_FLAG_LINE BIT(4) +#define DCMI_FLAG_VSYNC BIT(3) +#define DCMI_FLAG_ERR BIT(2) +#define DCMI_FLAG_OVR BIT(1) +#define DCMI_FLAG_FRAME BIT(0) + +// Embedded Synchronization Code Register +#define DCMI_ESCR_FEC (0xFF << 24) +#define DCMI_ESCR_LEC (0xFF << 16) +#define DCMI_ESCR_LSC (0xFF << 8) +#define DCMI_ESCR_FSC (0xFF << 0) + +// Embedded Synchronization Unmask Register +#define DCMI_ESUR_FEU (0xFF << 24) +#define DCMI_ESUR_LEU (0xFF << 16) +#define DCMI_ESUR_LSU (0xFF << 8) +#define DCMI_ESUR_FSU (0xFF << 0) + +// Crop Window Start +#define DCMI_CWSTRT_VST (0x1FFF << 16) +#define DCMI_CWSTRT_HOFFCNT (0x3FFF << 0) + +// Crop Window Size +#define DCMI_CWSIZE_VLINE (0x3FFF << 16) +#define DCMI_CWSIZE_CAPCNT (0x3FFF << 0) + + +// +// DCMI routines +// + +void dcmi_init(void); +void dcmi_init_gpios(void); +void dcmi_begin(); // collection of previous two functions +void dcmi_set_data_width(uint16 data_width); +void dcmi_set_vspol(uint8 vspol); +void dcmi_set_hspol(uint8 hspol); +void dcmi_set_pckpol(uint8 pckpol); +void dcmi_set_mode(uint8 capture_mode); +void dcmi_set_sync_mode(uint8 ess); +void dcmi_attach_interrupt(voidFuncPtr handler, uint8_t irq_mask); +void dcmi_detach_interrupt(uint8_t irq_mask); +void dcmi_config(uint32_t flags); +void dcmi_dma_config(uint32_t * buf, uint16 bufLen, voidFuncPtr func); +void dcmi_dma_reset(uint16 bufLen); + +static inline void dcmi_clear_irq_flags(void) { DCMI->regs->ICR = 0x1F; } + +static inline void dcmi_enable(void) { DCMI->regs->CR |= DCMI_CR_ENABLE; } + +static inline void dcmi_disable(void) { DCMI->regs->CR &= (~DCMI_CR_ENABLE); } + +static inline void dcmi_enable_capture(void) +{ + dcmi_clear_irq_flags(); + DCMI->regs->CR |= DCMI_CAPTURE_ENABLE; +} + +static inline void dcmi_disable_capture(void) +{ + DCMI->regs->CR &= (~DCMI_CAPTURE_ENABLE); +} + +static inline uint8 dcmi_dma_get_isr_bits(void) +{ + return dma_get_isr_bits(DMA2, DMA_STREAM1); +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // _DCMI_H_ diff --git a/STM32F4/cores/maple/libmaple/dmaF4.c b/STM32F4/cores/maple/libmaple/dmaF4.c index 173f3a222..13e6de558 100644 --- a/STM32F4/cores/maple/libmaple/dmaF4.c +++ b/STM32F4/cores/maple/libmaple/dmaF4.c @@ -24,8 +24,6 @@ * SOFTWARE. *****************************************************************************/ -#ifdef STM32F4 - /** * @file dmaF4.c * @brief Direct Memory Access peripheral support @@ -39,49 +37,47 @@ * Devices */ -static dma_dev dma1 = { - .regs = DMA1_BASE, - .clk_id = RCC_DMA1, - .handlers = {{ .handler = NULL, .irq_line = 11 }, - { .handler = NULL, .irq_line = 12 }, - { .handler = NULL, .irq_line = 13 }, - { .handler = NULL, .irq_line = 14 }, - { .handler = NULL, .irq_line = 15 }, - { .handler = NULL, .irq_line = 16 }, - { .handler = NULL, .irq_line = 17 }, - { .handler = NULL, .irq_line = 47 }} + +dma_handler_t dma1_handlers[8] = { + { .handler = NULL, .irq_line = NVIC_DMA1_STREAM0 }, + { .handler = NULL, .irq_line = NVIC_DMA1_STREAM1 }, + { .handler = NULL, .irq_line = NVIC_DMA1_STREAM2 }, + { .handler = NULL, .irq_line = NVIC_DMA1_STREAM3 }, + { .handler = NULL, .irq_line = NVIC_DMA1_STREAM4 }, + { .handler = NULL, .irq_line = NVIC_DMA1_STREAM5 }, + { .handler = NULL, .irq_line = NVIC_DMA1_STREAM6 }, + { .handler = NULL, .irq_line = NVIC_DMA1_STREAM7 }, +}; + +dma_handler_t dma2_handlers[8] = { + { .handler = NULL, .irq_line = NVIC_DMA2_STREAM0 }, + { .handler = NULL, .irq_line = NVIC_DMA2_STREAM1 }, + { .handler = NULL, .irq_line = NVIC_DMA2_STREAM2 }, + { .handler = NULL, .irq_line = NVIC_DMA2_STREAM3 }, + { .handler = NULL, .irq_line = NVIC_DMA2_STREAM4 }, + { .handler = NULL, .irq_line = NVIC_DMA2_STREAM5 }, + { .handler = NULL, .irq_line = NVIC_DMA2_STREAM6 }, + { .handler = NULL, .irq_line = NVIC_DMA2_STREAM7 }, }; + /** DMA1 device */ -dma_dev *DMA1 = &dma1; - -static dma_dev dma2 = { - .regs = DMA2_BASE, - .clk_id = RCC_DMA2, - .handlers = {{ .handler = NULL, .irq_line = 56 }, - { .handler = NULL, .irq_line = 57 }, - { .handler = NULL, .irq_line = 58 }, - { .handler = NULL, .irq_line = 59 }, - { .handler = NULL, .irq_line = 60 }, - { .handler = NULL, .irq_line = 68 }, - { .handler = NULL, .irq_line = 69 }, - { .handler = NULL, .irq_line = 70 }} /* !@#$ */ +const dma_dev dma1 = { + .regs = DMA1_BASE, + .clk_id = RCC_DMA1, + .handler_p = &dma1_handlers, }; -/** DMA2 device */ -dma_dev *DMA2 = &dma2; +/** DMA2 device */ +const dma_dev dma2 = { + .regs = DMA2_BASE, + .clk_id = RCC_DMA2, + .handler_p = &dma2_handlers, +}; /* * Convenience routines */ -/** - * @brief Initialize a DMA device. - * @param dev Device to initialize. - */ -void dma_init(dma_dev *dev) { - rcc_clk_enable(dev->clk_id); -} - /** * @brief Attach an interrupt to a DMA transfer. * @@ -94,11 +90,13 @@ void dma_init(dma_dev *dev) { * @see dma_setup_transfer() * @see dma_detach_interrupt() */ -void dma_attach_interrupt(dma_dev *dev, +void dma_attach_interrupt(const dma_dev *dev, dma_stream stream, - void (*handler)(void)) { - dev->handlers[stream].handler = handler; - nvic_irq_enable(dev->handlers[stream].irq_line); + void (*handler)(void)) +{ + dma_handler_t * dma_handler_p = &(*(dev->handler_p))[stream]; + dma_handler_p->handler = handler; + nvic_irq_enable(dma_handler_p->irq_line); } /** @@ -112,113 +110,113 @@ void dma_attach_interrupt(dma_dev *dev, * @sideeffect Clears interrupt enable bits in the channel's CCR register. * @see dma_attach_interrupt() */ -void dma_detach_interrupt(dma_dev *dev, dma_stream stream) { - nvic_irq_disable(dev->handlers[stream].irq_line); - dev->handlers[stream].handler = NULL; +void dma_detach_interrupt(const dma_dev *dev, dma_stream stream) +{ + dma_handler_t * dma_handler_p = &(*(dev->handler_p))[stream]; + nvic_irq_disable(dma_handler_p->irq_line); + dma_handler_p->handler = NULL; } const uint8 dma_isr_bits_shift[] = { 0, 6, 16, 22}; -uint8 dma_get_isr_bit(dma_dev *dev, dma_stream stream, uint8_t mask) { +uint8 dma_get_isr_bit(const dma_dev *dev, dma_stream stream, uint8_t mask) +{ if ( stream&0xFC ) return ((dev->regs->HISR)>>dma_isr_bits_shift[stream&0x03]) & mask; else return ((dev->regs->LISR)>>dma_isr_bits_shift[stream&0x03]) & mask; } -void dma_clear_isr_bit(dma_dev *dev, dma_stream stream, uint8_t mask) { +void dma_clear_isr_bit(const dma_dev *dev, dma_stream stream, uint8_t mask) +{ if ( stream&0xFC ) dev->regs->HIFCR = (uint32)mask << dma_isr_bits_shift[stream&0x03]; else dev->regs->LIFCR = (uint32)mask << dma_isr_bits_shift[stream&0x03]; } +void dma_set_mem_addr(const dma_dev *dev, dma_stream stream, __IO void *addr) +{ + dma_disable(dev, stream); + dev->regs->STREAM[stream].M0AR = (uint32)addr; +} + +void dma_set_per_addr(const dma_dev *dev, dma_stream stream, __IO void *addr) +{ + dma_disable(dev, stream); + dev->regs->STREAM[stream].PAR = (uint32)addr; +} + + /* * IRQ handlers */ -static inline void dispatch_handler(dma_dev *dev, dma_stream stream) { - void (*handler)(void) = dev->handlers[stream].handler; +static inline void dispatch_handler(const dma_dev *dev, dma_stream stream) +{ + voidFuncPtr handler = (*(dev->handler_p))[stream].handler; if (handler) { handler(); - dma_clear_isr_bits(dev, stream); /* in case handler doesn't */ } + dma_clear_isr_bits(dev, stream); // in case handler doesn't } -//void __irq_dma1_stream0(void) { -void __irq_dma1_channel1(void) { +void __irq_dma1_stream0(void) { dispatch_handler(DMA1, DMA_STREAM0); } -//void __irq_dma1_stream1(void) { -void __irq_dma1_channel2(void) { +void __irq_dma1_stream1(void) { dispatch_handler(DMA1, DMA_STREAM1); } -//void __irq_dma1_stream2(void) { -void __irq_dma1_channel3(void) { +void __irq_dma1_stream2(void) { dispatch_handler(DMA1, DMA_STREAM2); } -//void __irq_dma1_stream3(void) { -void __irq_dma1_channel4(void) { +void __irq_dma1_stream3(void) { dispatch_handler(DMA1, DMA_STREAM3); } -//void __irq_dma1_stream4(void) { -void __irq_dma1_channel5(void) { +void __irq_dma1_stream4(void) { dispatch_handler(DMA1, DMA_STREAM4); } -//void __irq_dma1_stream5(void) { -void __irq_dma1_channel6(void) { +void __irq_dma1_stream5(void) { dispatch_handler(DMA1, DMA_STREAM5); } -//void __irq_dma1_stream6(void) { -void __irq_dma1_channel7(void) { +void __irq_dma1_stream6(void) { dispatch_handler(DMA1, DMA_STREAM6); } -//void __irq_dma1_stream7(void) { -void __irq_adc3(void) { +void __irq_dma1_stream7(void) { dispatch_handler(DMA1, DMA_STREAM7); } -//void __irq_dma2_stream0(void) { -void __irq_dma2_channel1(void) { +void __irq_dma2_stream0(void) { dispatch_handler(DMA2, DMA_STREAM0); } -//void __irq_dma2_stream1(void) { -void __irq_dma2_channel2(void) { +void __irq_dma2_stream1(void) { dispatch_handler(DMA2, DMA_STREAM1); } -//void __irq_dma2_stream2(void) { -void __irq_dma2_channel3(void) { +void __irq_dma2_stream2(void) { dispatch_handler(DMA2, DMA_STREAM2); } -//void __irq_dma2_stream3(void) { -void __irq_dma2_channel4_5(void) { +void __irq_dma2_stream3(void) { dispatch_handler(DMA2, DMA_STREAM3); } -//void __irq_dma2_stream4(void) { -void __irq_DMA2_Stream4_IRQHandler(void) { +void __irq_dma2_stream4(void) { dispatch_handler(DMA2, DMA_STREAM4); } -//void __irq_dma2_stream5(void) { -void __irq_DMA2_Stream5_IRQHandler(void) { +void __irq_dma2_stream5(void) { dispatch_handler(DMA2, DMA_STREAM5); } -//void __irq_dma2_stream6(void) { -void __irq_DMA2_Stream6_IRQHandler(void) { +void __irq_dma2_stream6(void) { dispatch_handler(DMA2, DMA_STREAM6); } -//void __irq_dma2_stream7(void) { -void __irq_DMA2_Stream7_IRQHandler(void) { +void __irq_dma2_stream7(void) { dispatch_handler(DMA2, DMA_STREAM7); } - -#endif diff --git a/STM32F4/cores/maple/libmaple/dmaF4.h b/STM32F4/cores/maple/libmaple/dmaF4.h index cb2376069..c53a7583a 100644 --- a/STM32F4/cores/maple/libmaple/dmaF4.h +++ b/STM32F4/cores/maple/libmaple/dmaF4.h @@ -57,22 +57,22 @@ extern "C"{ * */ typedef struct dma_stream_t { - __io uint32 CR; /**< Stream configuration register */ - __io uint32 NDTR; /**< Stream number of data register */ - __io uint32 PAR; /**< Stream peripheral address register */ - __io uint32 M0AR; /**< Stream memory address register 0 */ - __io uint32 M1AR; /**< Stream memory address register 1 */ - __io uint32 FCR; /**< Stream FIFO configuration register */ + __IO uint32 CR; /**< Stream configuration register */ + __IO uint32 NDTR; /**< Stream number of data register */ + __IO uint32 PAR; /**< Stream peripheral address register */ + __IO uint32 M0AR; /**< Stream memory address register 0 */ + __IO uint32 M1AR; /**< Stream memory address register 1 */ + __IO uint32 FCR; /**< Stream FIFO configuration register */ } dma_stream_t; /** * @brief DMA register map type. * */ typedef struct dma_reg_map { - __io uint32 LISR; /**< Low interrupt status register */ - __io uint32 HISR; /**< High interrupt status register */ - __io uint32 LIFCR; /**< Low interrupt flag clear register */ - __io uint32 HIFCR; /**< High interrupt flag clear register */ + __IO uint32 LISR; /**< Low interrupt status register */ + __IO uint32 HISR; /**< High interrupt status register */ + __IO uint32 LIFCR; /**< Low interrupt flag clear register */ + __IO uint32 HIFCR; /**< High interrupt flag clear register */ dma_stream_t STREAM[8]; } dma_reg_map; @@ -163,7 +163,7 @@ typedef struct dma_reg_map { #define DMA_FCR_FTH_FULL (0x3 << 0) // full FIFO -typedef enum dma_channel { +typedef enum { DMA_CH0 = DMA_CR_CH0, /**< Channel 0 */ DMA_CH1 = DMA_CR_CH1, /**< Channel 1 */ DMA_CH2 = DMA_CR_CH2, /**< Channel 2 */ @@ -176,16 +176,16 @@ typedef enum dma_channel { /** Encapsulates state related to a DMA channel interrupt. */ typedef struct dma_handler_config { - void (*handler)(void); /**< User-specified channel interrupt + voidFuncPtr handler; /**< User-specified channel interrupt handler */ nvic_irq_num irq_line; /**< Channel's NVIC interrupt number */ -} dma_handler_config; +} dma_handler_t; /** DMA device type */ typedef struct dma_dev { dma_reg_map *regs; /**< Register map */ rcc_clk_id clk_id; /**< Clock ID */ - dma_handler_config handlers[]; /**< + dma_handler_t (*handler_p)[]; /**< * @brief IRQ handlers and NVIC numbers. * @see dma_detach_interrupt() */ @@ -194,8 +194,10 @@ typedef struct dma_dev { /* * Devices */ -extern dma_dev *DMA1; -extern dma_dev *DMA2; +extern const dma_dev dma1; +extern const dma_dev dma2; +#define DMA1 (&dma1) +#define DMA2 (&dma2) /** Flags for DMA transfer configuration. */ typedef enum dma_mode_flags { @@ -235,7 +237,7 @@ typedef enum dma_burst_size { } dma_burst_size; /** DMA channel */ -typedef enum dma_stream { +typedef enum { DMA_STREAM0 = 0, /**< Stream 0 */ DMA_STREAM1 = 1, /**< Stream 1 */ DMA_STREAM2 = 2, /**< Stream 2 */ @@ -249,15 +251,22 @@ typedef enum dma_stream { /* * Convenience functions */ -extern void dma_init(dma_dev *dev); +/** + * @brief Initialize a DMA device. + * @param dev Device to initialize. + */ +static inline void dma_init(const dma_dev *dev) +{ + rcc_clk_enable(dev->clk_id); +} -static inline void dma_setup_transfer(dma_dev *dev, +static inline void dma_setup_transfer(const dma_dev *dev, dma_stream stream, dma_channel channel, dma_xfer_size trx_size, - __io void *peripheral_address, - __io void *memory_address0, - __io void *memory_address1, + __IO void *peripheral_address, + const void *memory_address0, + const void *memory_address1, uint32 flags) { dev->regs->STREAM[stream].CR &= ~DMA_CR_EN; // disable @@ -267,40 +276,39 @@ static inline void dma_setup_transfer(dma_dev *dev, dev->regs->STREAM[stream].M1AR = (uint32)memory_address1; dev->regs->STREAM[stream].CR = (uint32)((flags|channel|trx_size) & 0x0feffffe); // mask out reserved and enable } - -static inline void dma_set_num_transfers(dma_dev *dev, dma_stream stream, uint16 num_transfers) + +static inline void dma_set_num_transfers(const dma_dev *dev, dma_stream stream, uint16 num_transfers) { dev->regs->STREAM[stream].NDTR = (uint32)num_transfers; } -static inline void dma_set_fifo_flags(dma_dev *dev, dma_stream stream, uint8 fifo_flags) +static inline void dma_set_fifo_flags(const dma_dev *dev, dma_stream stream, uint8 fifo_flags) { dev->regs->STREAM[stream].FCR = (uint32)(fifo_flags & 0x87); // mask out reserved bits } -void dma_attach_interrupt(dma_dev *dev, - dma_stream stream, - void (*handler)(void)); +void dma_attach_interrupt(const dma_dev *dev, dma_stream stream, void (*handler)(void)); -void dma_detach_interrupt(dma_dev *dev, dma_stream stream); +void dma_detach_interrupt(const dma_dev *dev, dma_stream stream); -static inline void dma_enable(dma_dev *dev, dma_stream stream) +static inline void dma_enable(const dma_dev *dev, dma_stream stream) { dev->regs->STREAM[stream].CR |= (uint32)DMA_CR_EN; -} +} -static inline void dma_disable(dma_dev *dev, dma_stream stream) +static inline void dma_disable(const dma_dev *dev, dma_stream stream) { dev->regs->STREAM[stream].CR &= (uint32)(~DMA_CR_EN); while (dev->regs->STREAM[stream].CR & DMA_CR_EN); // wait till EN bit is reset, see AN4031, chapter 4.1 -} +} /** * @brief Check if a DMA stream is enabled * @param dev DMA device * @param stream Stream whose enabled bit to check. */ -static inline uint8 dma_is_stream_enabled(dma_dev *dev, dma_stream stream) { +static inline uint8 dma_is_enabled(const dma_dev *dev, dma_stream stream) +{ return (uint8)(dev->regs->STREAM[stream].CR & DMA_CR_EN); } @@ -314,9 +322,10 @@ static inline uint8 dma_is_stream_enabled(dma_dev *dev, dma_stream stream) { * @param dev DMA device * @param stream Stream whose ISR bits to return. */ -uint8 dma_get_isr_bit(dma_dev *dev, dma_stream stream, uint8_t mask); +uint8 dma_get_isr_bit(const dma_dev *dev, dma_stream stream, uint8_t mask); -static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_stream stream) { +static inline uint8 dma_get_isr_bits(const dma_dev *dev, dma_stream stream) +{ return dma_get_isr_bit(dev, stream, DMA_ISR_BIT_MASK); } @@ -326,12 +335,49 @@ static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_stream stream) { * @param dev DMA device * @param stream Stream whose ISR bits to clear. */ -void dma_clear_isr_bit(dma_dev *dev, dma_stream stream, uint8_t mask); +void dma_clear_isr_bit(const dma_dev *dev, dma_stream stream, uint8_t mask); -static inline void dma_clear_isr_bits(dma_dev *dev, dma_stream stream) { +static inline void dma_clear_isr_bits(const dma_dev *dev, dma_stream stream) +{ dma_clear_isr_bit(dev, stream, DMA_ISR_BIT_MASK); } +static inline uint16 dma_get_count(const dma_dev *dev, dma_stream stream) { + return dev->regs->STREAM[stream].NDTR; +} + +/** + * @brief Set the base memory address where data will be read from or + * written to. + * + * You must not call this function while the tube is enabled. + * + * If the DMA memory size is 16 bits, the address is automatically + * aligned to a half-word. If the DMA memory size is 32 bits, the + * address is aligned to a word. + * + * @param dev DMA Device + * @param tube Tube whose base memory address to set. + * @param address Memory base address to use. + */ +extern void dma_set_mem_addr(const dma_dev *dev, dma_stream stream, __IO void *address); + +/** + * @brief Set the base peripheral address where data will be read from + * or written to. + * + * You must not call this function while the channel is enabled. + * + * If the DMA peripheral size is 16 bits, the address is automatically + * aligned to a half-word. If the DMA peripheral size is 32 bits, the + * address is aligned to a word. + * + * @param dev DMA Device + * @param tube Tube whose peripheral data register base address to set. + * @param address Peripheral memory base address to use. + */ +extern void dma_set_per_addr(const dma_dev *dev, dma_stream stream, __IO void *address); + #ifdef __cplusplus } // extern "C" #endif diff --git a/STM32F4/cores/maple/libmaple/dma_common.h b/STM32F4/cores/maple/libmaple/dma_common.h deleted file mode 100644 index 15dfab9c8..000000000 --- a/STM32F4/cores/maple/libmaple/dma_common.h +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple/include/libmaple/dma_common.h - * @author Marti Bolivar - * @brief Common DMA sub-header for and . - * - * CONTENTS UNSTABLE. The existence of this file is an implementation - * detail. Never include it directly. If you need something from - * here, include instead. - */ - -/* - * There's a fair amount of common DMA functionality needed by each - * and . This header exists in order - * to provide it to both, avoiding some hacks and circular - * dependencies. - */ - -#ifndef _LIBMAPLE_DMA_COMMON_H_ -#define _LIBMAPLE_DMA_COMMON_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include -#include -#include - -/* - * Devices - */ - -struct dma_reg_map; - -/* Encapsulates state related to user interrupt handlers. You - * shouldn't touch these directly; use dma_attach_interrupt() and - * dma_detach_interupt() instead. */ -//typedef struct dma_handler_config { -// void (*handler)(void); /* User handler */ -// nvic_irq_num irq_line; /* IRQ line for interrupt */ -//} dma_handler_config; - -/** DMA device type */ -//typedef struct dma_dev { -// struct dma_reg_map *regs; /**< Register map */ -// rcc_clk_id clk_id; /**< Clock ID */ -// struct dma_handler_config handlers[]; /**< For internal use */ -//} dma_dev; - -/** - * @brief DMA channels - * - * Notes: - * - This is also the dma_tube type for STM32F1. - * - Channel 0 is not available on all STM32 series. - * - * @see dma_tube - */ -typedef enum dma_channel { - DMA_CH0 = 0, /**< Channel 0 */ - DMA_CH1 = 1, /**< Channel 1 */ - DMA_CH2 = 2, /**< Channel 2 */ - DMA_CH3 = 3, /**< Channel 3 */ - DMA_CH4 = 4, /**< Channel 4 */ - DMA_CH5 = 5, /**< Channel 5 */ - DMA_CH6 = 6, /**< Channel 6 */ - DMA_CH7 = 7, /**< Channel 7 */ -} dma_channel; - -/** - * @brief Source and destination transfer sizes. - * Use these when initializing a struct dma_tube_config. - * @see struct dma_tube_config - * @see dma_tube_cfg - */ -//typedef enum dma_xfer_size { -// DMA_SIZE_8BITS = 0, /**< 8-bit transfers */ -// DMA_SIZE_16BITS = 1, /**< 16-bit transfers */ -// DMA_SIZE_32BITS = 2, /**< 32-bit transfers */ -//} dma_xfer_size; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/STM32F4/cores/maple/libmaple/ethernet.c b/STM32F4/cores/maple/libmaple/ethernet.c new file mode 100644 index 000000000..732658913 --- /dev/null +++ b/STM32F4/cores/maple/libmaple/ethernet.c @@ -0,0 +1,63 @@ +// ethernet.c + + +#include "ethernet.h" +#include "gpio.h" + +#ifdef __cplusplus + extern "C" { +#endif // __cplusplus + +#ifdef ETH_TX_D0 + +// RMII interface IO pins +const uint8_t eth_pins[] = { +ETH_REF_CLK, ETH_MDIO, ETH_CRS_DV, ETH_TX_EN, ETH_TX_D0, ETH_TX_D1, ETH_MDC, ETH_RX_D0, ETH_RX_D1 +}; + + +// Select MII or RMII Mode/ +#define ETH_MEDIA_INTERFACE_MII 0x00000000U +#define ETH_MEDIA_INTERFACE_RMII ((uint32_t)SYSCFG_PMC_MII_RMII_SEL) + +//----------------------------------------------------------------------------- +void ethernet_init(void) +{ + rcc_clk_enable(RCC_ETHMAC); + rcc_clk_enable(RCC_ETHMACTX); + rcc_clk_enable(RCC_ETHMACRX); +// rcc_clk_enable(RCC_ETHMACPTP); + + rcc_reset_dev(RCC_ETHMAC); +} + +//----------------------------------------------------------------------------- +void ethernet_deinit(void) +{ + rcc_clk_disable(RCC_ETHMAC); + rcc_clk_disable(RCC_ETHMACTX); + rcc_clk_disable(RCC_ETHMACRX); +// rcc_clk_enable(RCC_ETHMACPTP); +} + +//----------------------------------------------------------------------------- +void ethernet_gpio_init(void) +{ + SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL_Msk); + // enable the following line for RMII + SYSCFG->PMC |= ETH_MEDIA_INTERFACE_RMII; + + // setup pins + for (uint8_t i = 0; i + +#ifdef __cplusplus + extern "C" { +#endif // __cplusplus + + +typedef struct +{ + __IO uint32_t MACCR; + __IO uint32_t MACFFR; + __IO uint32_t MACHTHR; + __IO uint32_t MACHTLR; + __IO uint32_t MACMIIAR; + __IO uint32_t MACMIIDR; + __IO uint32_t MACFCR; + __IO uint32_t MACVLANTR; /* 8 */ + uint32_t RESERVED0[2]; + __IO uint32_t MACRWUFFR; /* 11 */ + __IO uint32_t MACPMTCSR; + uint32_t RESERVED1; + __IO uint32_t MACDBGR; + __IO uint32_t MACSR; /* 15 */ + __IO uint32_t MACIMR; + __IO uint32_t MACA0HR; + __IO uint32_t MACA0LR; + __IO uint32_t MACA1HR; + __IO uint32_t MACA1LR; + __IO uint32_t MACA2HR; + __IO uint32_t MACA2LR; + __IO uint32_t MACA3HR; + __IO uint32_t MACA3LR; /* 24 */ + uint32_t RESERVED2[40]; + __IO uint32_t MMCCR; /* 65 */ + __IO uint32_t MMCRIR; + __IO uint32_t MMCTIR; + __IO uint32_t MMCRIMR; + __IO uint32_t MMCTIMR; /* 69 */ + uint32_t RESERVED3[14]; + __IO uint32_t MMCTGFSCCR; /* 84 */ + __IO uint32_t MMCTGFMSCCR; + uint32_t RESERVED4[5]; + __IO uint32_t MMCTGFCR; + uint32_t RESERVED5[10]; + __IO uint32_t MMCRFCECR; + __IO uint32_t MMCRFAECR; + uint32_t RESERVED6[10]; + __IO uint32_t MMCRGUFCR; + uint32_t RESERVED7[334]; + __IO uint32_t PTPTSCR; + __IO uint32_t PTPSSIR; + __IO uint32_t PTPTSHR; + __IO uint32_t PTPTSLR; + __IO uint32_t PTPTSHUR; + __IO uint32_t PTPTSLUR; + __IO uint32_t PTPTSAR; + __IO uint32_t PTPTTHR; + __IO uint32_t PTPTTLR; + __IO uint32_t RESERVED8; + __IO uint32_t PTPTSSR; + uint32_t RESERVED9[565]; + __IO uint32_t DMABMR; + __IO uint32_t DMATPDR; + __IO uint32_t DMARPDR; + __IO uint32_t DMARDLAR; + __IO uint32_t DMATDLAR; + __IO uint32_t DMASR; + __IO uint32_t DMAOMR; + __IO uint32_t DMAIER; + __IO uint32_t DMAMFBOCR; + __IO uint32_t DMARSWTR; + uint32_t RESERVED10[8]; + __IO uint32_t DMACHTDR; + __IO uint32_t DMACHRDR; + __IO uint32_t DMACHTBAR; + __IO uint32_t DMACHRBAR; +} eth_reg_map; + +//----------------------------------------------------------------------------- +#define ETH_BASE (0x40028000U) +#define ETH_MAC_BASE (ETH_BASE) +#define ETH_MMC_BASE (ETH_BASE + 0x0100U) +#define ETH_PTP_BASE (ETH_BASE + 0x0700U) +#define ETH_DMA_BASE (ETH_BASE + 0x1000U) + +#define ETH ((eth_reg_map*) ETH_BASE) + + +/******************************************************************************/ +/* */ +/* Ethernet MAC Registers bits definitions */ +/* */ +/******************************************************************************/ +/* Bit definition for Ethernet MAC Control Register register */ +#define ETH_MACCR_WD_Pos (23U) +#define ETH_MACCR_WD_Msk (0x1U << ETH_MACCR_WD_Pos) /*!< 0x00800000 */ +#define ETH_MACCR_WD ETH_MACCR_WD_Msk /* Watchdog disable */ +#define ETH_MACCR_JD_Pos (22U) +#define ETH_MACCR_JD_Msk (0x1U << ETH_MACCR_JD_Pos) /*!< 0x00400000 */ +#define ETH_MACCR_JD ETH_MACCR_JD_Msk /* Jabber disable */ +#define ETH_MACCR_IFG_Pos (17U) +#define ETH_MACCR_IFG_Msk (0x7U << ETH_MACCR_IFG_Pos) /*!< 0x000E0000 */ +#define ETH_MACCR_IFG ETH_MACCR_IFG_Msk /* Inter-frame gap */ +#define ETH_MACCR_IFG_96Bit 0x00000000U /* Minimum IFG between frames during transmission is 96Bit */ +#define ETH_MACCR_IFG_88Bit 0x00020000U /* Minimum IFG between frames during transmission is 88Bit */ +#define ETH_MACCR_IFG_80Bit 0x00040000U /* Minimum IFG between frames during transmission is 80Bit */ +#define ETH_MACCR_IFG_72Bit 0x00060000U /* Minimum IFG between frames during transmission is 72Bit */ +#define ETH_MACCR_IFG_64Bit 0x00080000U /* Minimum IFG between frames during transmission is 64Bit */ +#define ETH_MACCR_IFG_56Bit 0x000A0000U /* Minimum IFG between frames during transmission is 56Bit */ +#define ETH_MACCR_IFG_48Bit 0x000C0000U /* Minimum IFG between frames during transmission is 48Bit */ +#define ETH_MACCR_IFG_40Bit 0x000E0000U /* Minimum IFG between frames during transmission is 40Bit */ +#define ETH_MACCR_CSD_Pos (16U) +#define ETH_MACCR_CSD_Msk (0x1U << ETH_MACCR_CSD_Pos) /*!< 0x00010000 */ +#define ETH_MACCR_CSD ETH_MACCR_CSD_Msk /* Carrier sense disable (during transmission) */ +#define ETH_MACCR_FES_Pos (14U) +#define ETH_MACCR_FES_Msk (0x1U << ETH_MACCR_FES_Pos) /*!< 0x00004000 */ +#define ETH_MACCR_FES ETH_MACCR_FES_Msk /* Fast ethernet speed */ +#define ETH_MACCR_ROD_Pos (13U) +#define ETH_MACCR_ROD_Msk (0x1U << ETH_MACCR_ROD_Pos) /*!< 0x00002000 */ +#define ETH_MACCR_ROD ETH_MACCR_ROD_Msk /* Receive own disable */ +#define ETH_MACCR_LM_Pos (12U) +#define ETH_MACCR_LM_Msk (0x1U << ETH_MACCR_LM_Pos) /*!< 0x00001000 */ +#define ETH_MACCR_LM ETH_MACCR_LM_Msk /* loopback mode */ +#define ETH_MACCR_DM_Pos (11U) +#define ETH_MACCR_DM_Msk (0x1U << ETH_MACCR_DM_Pos) /*!< 0x00000800 */ +#define ETH_MACCR_DM ETH_MACCR_DM_Msk /* Duplex mode */ +#define ETH_MACCR_IPCO_Pos (10U) +#define ETH_MACCR_IPCO_Msk (0x1U << ETH_MACCR_IPCO_Pos) /*!< 0x00000400 */ +#define ETH_MACCR_IPCO ETH_MACCR_IPCO_Msk /* IP Checksum offload */ +#define ETH_MACCR_RD_Pos (9U) +#define ETH_MACCR_RD_Msk (0x1U << ETH_MACCR_RD_Pos) /*!< 0x00000200 */ +#define ETH_MACCR_RD ETH_MACCR_RD_Msk /* Retry disable */ +#define ETH_MACCR_APCS_Pos (7U) +#define ETH_MACCR_APCS_Msk (0x1U << ETH_MACCR_APCS_Pos) /*!< 0x00000080 */ +#define ETH_MACCR_APCS ETH_MACCR_APCS_Msk /* Automatic Pad/CRC stripping */ +#define ETH_MACCR_BL_Pos (5U) +#define ETH_MACCR_BL_Msk (0x3U << ETH_MACCR_BL_Pos) /*!< 0x00000060 */ +#define ETH_MACCR_BL ETH_MACCR_BL_Msk /* Back-off limit: random integer number (r) of slot time delays before rescheduling + a transmission attempt during retries after a collision: 0 =< r <2^k */ +#define ETH_MACCR_BL_10 0x00000000U /* k = min (n, 10) */ +#define ETH_MACCR_BL_8 0x00000020U /* k = min (n, 8) */ +#define ETH_MACCR_BL_4 0x00000040U /* k = min (n, 4) */ +#define ETH_MACCR_BL_1 0x00000060U /* k = min (n, 1) */ +#define ETH_MACCR_DC_Pos (4U) +#define ETH_MACCR_DC_Msk (0x1U << ETH_MACCR_DC_Pos) /*!< 0x00000010 */ +#define ETH_MACCR_DC ETH_MACCR_DC_Msk /* Defferal check */ +#define ETH_MACCR_TE_Pos (3U) +#define ETH_MACCR_TE_Msk (0x1U << ETH_MACCR_TE_Pos) /*!< 0x00000008 */ +#define ETH_MACCR_TE ETH_MACCR_TE_Msk /* Transmitter enable */ +#define ETH_MACCR_RE_Pos (2U) +#define ETH_MACCR_RE_Msk (0x1U << ETH_MACCR_RE_Pos) /*!< 0x00000004 */ +#define ETH_MACCR_RE ETH_MACCR_RE_Msk /* Receiver enable */ + +/* Bit definition for Ethernet MAC Frame Filter Register */ +#define ETH_MACFFR_RA_Pos (31U) +#define ETH_MACFFR_RA_Msk (0x1U << ETH_MACFFR_RA_Pos) /*!< 0x80000000 */ +#define ETH_MACFFR_RA ETH_MACFFR_RA_Msk /* Receive all */ +#define ETH_MACFFR_HPF_Pos (10U) +#define ETH_MACFFR_HPF_Msk (0x1U << ETH_MACFFR_HPF_Pos) /*!< 0x00000400 */ +#define ETH_MACFFR_HPF ETH_MACFFR_HPF_Msk /* Hash or perfect filter */ +#define ETH_MACFFR_SAF_Pos (9U) +#define ETH_MACFFR_SAF_Msk (0x1U << ETH_MACFFR_SAF_Pos) /*!< 0x00000200 */ +#define ETH_MACFFR_SAF ETH_MACFFR_SAF_Msk /* Source address filter enable */ +#define ETH_MACFFR_SAIF_Pos (8U) +#define ETH_MACFFR_SAIF_Msk (0x1U << ETH_MACFFR_SAIF_Pos) /*!< 0x00000100 */ +#define ETH_MACFFR_SAIF ETH_MACFFR_SAIF_Msk /* SA inverse filtering */ +#define ETH_MACFFR_PCF_Pos (6U) +#define ETH_MACFFR_PCF_Msk (0x3U << ETH_MACFFR_PCF_Pos) /*!< 0x000000C0 */ +#define ETH_MACFFR_PCF ETH_MACFFR_PCF_Msk /* Pass control frames: 3 cases */ +#define ETH_MACFFR_PCF_BlockAll_Pos (6U) +#define ETH_MACFFR_PCF_BlockAll_Msk (0x1U << ETH_MACFFR_PCF_BlockAll_Pos) /*!< 0x00000040 */ +#define ETH_MACFFR_PCF_BlockAll ETH_MACFFR_PCF_BlockAll_Msk /* MAC filters all control frames from reaching the application */ +#define ETH_MACFFR_PCF_ForwardAll_Pos (7U) +#define ETH_MACFFR_PCF_ForwardAll_Msk (0x1U << ETH_MACFFR_PCF_ForwardAll_Pos) /*!< 0x00000080 */ +#define ETH_MACFFR_PCF_ForwardAll ETH_MACFFR_PCF_ForwardAll_Msk /* MAC forwards all control frames to application even if they fail the Address Filter */ +#define ETH_MACFFR_PCF_ForwardPassedAddrFilter_Pos (6U) +#define ETH_MACFFR_PCF_ForwardPassedAddrFilter_Msk (0x3U << ETH_MACFFR_PCF_ForwardPassedAddrFilter_Pos) /*!< 0x000000C0 */ +#define ETH_MACFFR_PCF_ForwardPassedAddrFilter ETH_MACFFR_PCF_ForwardPassedAddrFilter_Msk /* MAC forwards control frames that pass the Address Filter. */ +#define ETH_MACFFR_BFD_Pos (5U) +#define ETH_MACFFR_BFD_Msk (0x1U << ETH_MACFFR_BFD_Pos) /*!< 0x00000020 */ +#define ETH_MACFFR_BFD ETH_MACFFR_BFD_Msk /* Broadcast frame disable */ +#define ETH_MACFFR_PAM_Pos (4U) +#define ETH_MACFFR_PAM_Msk (0x1U << ETH_MACFFR_PAM_Pos) /*!< 0x00000010 */ +#define ETH_MACFFR_PAM ETH_MACFFR_PAM_Msk /* Pass all mutlicast */ +#define ETH_MACFFR_DAIF_Pos (3U) +#define ETH_MACFFR_DAIF_Msk (0x1U << ETH_MACFFR_DAIF_Pos) /*!< 0x00000008 */ +#define ETH_MACFFR_DAIF ETH_MACFFR_DAIF_Msk /* DA Inverse filtering */ +#define ETH_MACFFR_HM_Pos (2U) +#define ETH_MACFFR_HM_Msk (0x1U << ETH_MACFFR_HM_Pos) /*!< 0x00000004 */ +#define ETH_MACFFR_HM ETH_MACFFR_HM_Msk /* Hash multicast */ +#define ETH_MACFFR_HU_Pos (1U) +#define ETH_MACFFR_HU_Msk (0x1U << ETH_MACFFR_HU_Pos) /*!< 0x00000002 */ +#define ETH_MACFFR_HU ETH_MACFFR_HU_Msk /* Hash unicast */ +#define ETH_MACFFR_PM_Pos (0U) +#define ETH_MACFFR_PM_Msk (0x1U << ETH_MACFFR_PM_Pos) /*!< 0x00000001 */ +#define ETH_MACFFR_PM ETH_MACFFR_PM_Msk /* Promiscuous mode */ + +/* Bit definition for Ethernet MAC Hash Table High Register */ +#define ETH_MACHTHR_HTH_Pos (0U) +#define ETH_MACHTHR_HTH_Msk (0xFFFFFFFFU << ETH_MACHTHR_HTH_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MACHTHR_HTH ETH_MACHTHR_HTH_Msk /* Hash table high */ + +/* Bit definition for Ethernet MAC Hash Table Low Register */ +#define ETH_MACHTLR_HTL_Pos (0U) +#define ETH_MACHTLR_HTL_Msk (0xFFFFFFFFU << ETH_MACHTLR_HTL_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MACHTLR_HTL ETH_MACHTLR_HTL_Msk /* Hash table low */ + +/* Bit definition for Ethernet MAC MII Address Register */ +#define ETH_MACMIIAR_PA_Pos (11U) +#define ETH_MACMIIAR_PA_Msk (0x1FU << ETH_MACMIIAR_PA_Pos) /*!< 0x0000F800 */ +#define ETH_MACMIIAR_PA ETH_MACMIIAR_PA_Msk /* Physical layer address */ +#define ETH_MACMIIAR_MR_Pos (6U) +#define ETH_MACMIIAR_MR_Msk (0x1FU << ETH_MACMIIAR_MR_Pos) /*!< 0x000007C0 */ +#define ETH_MACMIIAR_MR ETH_MACMIIAR_MR_Msk /* MII register in the selected PHY */ +#define ETH_MACMIIAR_CR_Pos (2U) +#define ETH_MACMIIAR_CR_Msk (0x7U << ETH_MACMIIAR_CR_Pos) /*!< 0x0000001C */ +#define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_Msk /* CR clock range: 6 cases */ +#define ETH_MACMIIAR_CR_Div42 0x00000000U /* HCLK:60-100 MHz; MDC clock= HCLK/42 */ +#define ETH_MACMIIAR_CR_Div62_Pos (2U) +#define ETH_MACMIIAR_CR_Div62_Msk (0x1U << ETH_MACMIIAR_CR_Div62_Pos) /*!< 0x00000004 */ +#define ETH_MACMIIAR_CR_Div62 ETH_MACMIIAR_CR_Div62_Msk /* HCLK:100-150 MHz; MDC clock= HCLK/62 */ +#define ETH_MACMIIAR_CR_Div16_Pos (3U) +#define ETH_MACMIIAR_CR_Div16_Msk (0x1U << ETH_MACMIIAR_CR_Div16_Pos) /*!< 0x00000008 */ +#define ETH_MACMIIAR_CR_Div16 ETH_MACMIIAR_CR_Div16_Msk /* HCLK:20-35 MHz; MDC clock= HCLK/16 */ +#define ETH_MACMIIAR_CR_Div26_Pos (2U) +#define ETH_MACMIIAR_CR_Div26_Msk (0x3U << ETH_MACMIIAR_CR_Div26_Pos) /*!< 0x0000000C */ +#define ETH_MACMIIAR_CR_Div26 ETH_MACMIIAR_CR_Div26_Msk /* HCLK:35-60 MHz; MDC clock= HCLK/26 */ +#define ETH_MACMIIAR_CR_Div102_Pos (4U) +#define ETH_MACMIIAR_CR_Div102_Msk (0x1U << ETH_MACMIIAR_CR_Div102_Pos) /*!< 0x00000010 */ +#define ETH_MACMIIAR_CR_Div102 ETH_MACMIIAR_CR_Div102_Msk /* HCLK:150-168 MHz; MDC clock= HCLK/102 */ +#define ETH_MACMIIAR_MW_Pos (1U) +#define ETH_MACMIIAR_MW_Msk (0x1U << ETH_MACMIIAR_MW_Pos) /*!< 0x00000002 */ +#define ETH_MACMIIAR_MW ETH_MACMIIAR_MW_Msk /* MII write */ +#define ETH_MACMIIAR_MB_Pos (0U) +#define ETH_MACMIIAR_MB_Msk (0x1U << ETH_MACMIIAR_MB_Pos) /*!< 0x00000001 */ +#define ETH_MACMIIAR_MB ETH_MACMIIAR_MB_Msk /* MII busy */ + +/* Bit definition for Ethernet MAC MII Data Register */ +#define ETH_MACMIIDR_MD_Pos (0U) +#define ETH_MACMIIDR_MD_Msk (0xFFFFU << ETH_MACMIIDR_MD_Pos) /*!< 0x0000FFFF */ +#define ETH_MACMIIDR_MD ETH_MACMIIDR_MD_Msk /* MII data: read/write data from/to PHY */ + +/* Bit definition for Ethernet MAC Flow Control Register */ +#define ETH_MACFCR_PT_Pos (16U) +#define ETH_MACFCR_PT_Msk (0xFFFFU << ETH_MACFCR_PT_Pos) /*!< 0xFFFF0000 */ +#define ETH_MACFCR_PT ETH_MACFCR_PT_Msk /* Pause time */ +#define ETH_MACFCR_ZQPD_Pos (7U) +#define ETH_MACFCR_ZQPD_Msk (0x1U << ETH_MACFCR_ZQPD_Pos) /*!< 0x00000080 */ +#define ETH_MACFCR_ZQPD ETH_MACFCR_ZQPD_Msk /* Zero-quanta pause disable */ +#define ETH_MACFCR_PLT_Pos (4U) +#define ETH_MACFCR_PLT_Msk (0x3U << ETH_MACFCR_PLT_Pos) /*!< 0x00000030 */ +#define ETH_MACFCR_PLT ETH_MACFCR_PLT_Msk /* Pause low threshold: 4 cases */ +#define ETH_MACFCR_PLT_Minus4 0x00000000U /* Pause time minus 4 slot times */ +#define ETH_MACFCR_PLT_Minus28_Pos (4U) +#define ETH_MACFCR_PLT_Minus28_Msk (0x1U << ETH_MACFCR_PLT_Minus28_Pos) /*!< 0x00000010 */ +#define ETH_MACFCR_PLT_Minus28 ETH_MACFCR_PLT_Minus28_Msk /* Pause time minus 28 slot times */ +#define ETH_MACFCR_PLT_Minus144_Pos (5U) +#define ETH_MACFCR_PLT_Minus144_Msk (0x1U << ETH_MACFCR_PLT_Minus144_Pos) /*!< 0x00000020 */ +#define ETH_MACFCR_PLT_Minus144 ETH_MACFCR_PLT_Minus144_Msk /* Pause time minus 144 slot times */ +#define ETH_MACFCR_PLT_Minus256_Pos (4U) +#define ETH_MACFCR_PLT_Minus256_Msk (0x3U << ETH_MACFCR_PLT_Minus256_Pos) /*!< 0x00000030 */ +#define ETH_MACFCR_PLT_Minus256 ETH_MACFCR_PLT_Minus256_Msk /* Pause time minus 256 slot times */ +#define ETH_MACFCR_UPFD_Pos (3U) +#define ETH_MACFCR_UPFD_Msk (0x1U << ETH_MACFCR_UPFD_Pos) /*!< 0x00000008 */ +#define ETH_MACFCR_UPFD ETH_MACFCR_UPFD_Msk /* Unicast pause frame detect */ +#define ETH_MACFCR_RFCE_Pos (2U) +#define ETH_MACFCR_RFCE_Msk (0x1U << ETH_MACFCR_RFCE_Pos) /*!< 0x00000004 */ +#define ETH_MACFCR_RFCE ETH_MACFCR_RFCE_Msk /* Receive flow control enable */ +#define ETH_MACFCR_TFCE_Pos (1U) +#define ETH_MACFCR_TFCE_Msk (0x1U << ETH_MACFCR_TFCE_Pos) /*!< 0x00000002 */ +#define ETH_MACFCR_TFCE ETH_MACFCR_TFCE_Msk /* Transmit flow control enable */ +#define ETH_MACFCR_FCBBPA_Pos (0U) +#define ETH_MACFCR_FCBBPA_Msk (0x1U << ETH_MACFCR_FCBBPA_Pos) /*!< 0x00000001 */ +#define ETH_MACFCR_FCBBPA ETH_MACFCR_FCBBPA_Msk /* Flow control busy/backpressure activate */ + +/* Bit definition for Ethernet MAC VLAN Tag Register */ +#define ETH_MACVLANTR_VLANTC_Pos (16U) +#define ETH_MACVLANTR_VLANTC_Msk (0x1U << ETH_MACVLANTR_VLANTC_Pos) /*!< 0x00010000 */ +#define ETH_MACVLANTR_VLANTC ETH_MACVLANTR_VLANTC_Msk /* 12-bit VLAN tag comparison */ +#define ETH_MACVLANTR_VLANTI_Pos (0U) +#define ETH_MACVLANTR_VLANTI_Msk (0xFFFFU << ETH_MACVLANTR_VLANTI_Pos) /*!< 0x0000FFFF */ +#define ETH_MACVLANTR_VLANTI ETH_MACVLANTR_VLANTI_Msk /* VLAN tag identifier (for receive frames) */ + +/* Bit definition for Ethernet MAC Remote Wake-UpFrame Filter Register */ +#define ETH_MACRWUFFR_D_Pos (0U) +#define ETH_MACRWUFFR_D_Msk (0xFFFFFFFFU << ETH_MACRWUFFR_D_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MACRWUFFR_D ETH_MACRWUFFR_D_Msk /* Wake-up frame filter register data */ +/* Eight sequential Writes to this address (offset 0x28) will write all Wake-UpFrame Filter Registers. + Eight sequential Reads from this address (offset 0x28) will read all Wake-UpFrame Filter Registers. */ +/* Wake-UpFrame Filter Reg0 : Filter 0 Byte Mask + Wake-UpFrame Filter Reg1 : Filter 1 Byte Mask + Wake-UpFrame Filter Reg2 : Filter 2 Byte Mask + Wake-UpFrame Filter Reg3 : Filter 3 Byte Mask + Wake-UpFrame Filter Reg4 : RSVD - Filter3 Command - RSVD - Filter2 Command - + RSVD - Filter1 Command - RSVD - Filter0 Command + Wake-UpFrame Filter Re5 : Filter3 Offset - Filter2 Offset - Filter1 Offset - Filter0 Offset + Wake-UpFrame Filter Re6 : Filter1 CRC16 - Filter0 CRC16 + Wake-UpFrame Filter Re7 : Filter3 CRC16 - Filter2 CRC16 */ + +/* Bit definition for Ethernet MAC PMT Control and Status Register */ +#define ETH_MACPMTCSR_WFFRPR_Pos (31U) +#define ETH_MACPMTCSR_WFFRPR_Msk (0x1U << ETH_MACPMTCSR_WFFRPR_Pos) /*!< 0x80000000 */ +#define ETH_MACPMTCSR_WFFRPR ETH_MACPMTCSR_WFFRPR_Msk /* Wake-Up Frame Filter Register Pointer Reset */ +#define ETH_MACPMTCSR_GU_Pos (9U) +#define ETH_MACPMTCSR_GU_Msk (0x1U << ETH_MACPMTCSR_GU_Pos) /*!< 0x00000200 */ +#define ETH_MACPMTCSR_GU ETH_MACPMTCSR_GU_Msk /* Global Unicast */ +#define ETH_MACPMTCSR_WFR_Pos (6U) +#define ETH_MACPMTCSR_WFR_Msk (0x1U << ETH_MACPMTCSR_WFR_Pos) /*!< 0x00000040 */ +#define ETH_MACPMTCSR_WFR ETH_MACPMTCSR_WFR_Msk /* Wake-Up Frame Received */ +#define ETH_MACPMTCSR_MPR_Pos (5U) +#define ETH_MACPMTCSR_MPR_Msk (0x1U << ETH_MACPMTCSR_MPR_Pos) /*!< 0x00000020 */ +#define ETH_MACPMTCSR_MPR ETH_MACPMTCSR_MPR_Msk /* Magic Packet Received */ +#define ETH_MACPMTCSR_WFE_Pos (2U) +#define ETH_MACPMTCSR_WFE_Msk (0x1U << ETH_MACPMTCSR_WFE_Pos) /*!< 0x00000004 */ +#define ETH_MACPMTCSR_WFE ETH_MACPMTCSR_WFE_Msk /* Wake-Up Frame Enable */ +#define ETH_MACPMTCSR_MPE_Pos (1U) +#define ETH_MACPMTCSR_MPE_Msk (0x1U << ETH_MACPMTCSR_MPE_Pos) /*!< 0x00000002 */ +#define ETH_MACPMTCSR_MPE ETH_MACPMTCSR_MPE_Msk /* Magic Packet Enable */ +#define ETH_MACPMTCSR_PD_Pos (0U) +#define ETH_MACPMTCSR_PD_Msk (0x1U << ETH_MACPMTCSR_PD_Pos) /*!< 0x00000001 */ +#define ETH_MACPMTCSR_PD ETH_MACPMTCSR_PD_Msk /* Power Down */ + +/* Bit definition for Ethernet MAC debug Register */ +#define ETH_MACDBGR_TFF_Pos (25U) +#define ETH_MACDBGR_TFF_Msk (0x1U << ETH_MACDBGR_TFF_Pos) /*!< 0x02000000 */ +#define ETH_MACDBGR_TFF ETH_MACDBGR_TFF_Msk /* Tx FIFO full */ +#define ETH_MACDBGR_TFNE_Pos (24U) +#define ETH_MACDBGR_TFNE_Msk (0x1U << ETH_MACDBGR_TFNE_Pos) /*!< 0x01000000 */ +#define ETH_MACDBGR_TFNE ETH_MACDBGR_TFNE_Msk /* Tx FIFO not empty */ +#define ETH_MACDBGR_TFWA_Pos (22U) +#define ETH_MACDBGR_TFWA_Msk (0x1U << ETH_MACDBGR_TFWA_Pos) /*!< 0x00400000 */ +#define ETH_MACDBGR_TFWA ETH_MACDBGR_TFWA_Msk /* Tx FIFO write active */ +#define ETH_MACDBGR_TFRS_Pos (20U) +#define ETH_MACDBGR_TFRS_Msk (0x3U << ETH_MACDBGR_TFRS_Pos) /*!< 0x00300000 */ +#define ETH_MACDBGR_TFRS ETH_MACDBGR_TFRS_Msk /* Tx FIFO read status mask */ +#define ETH_MACDBGR_TFRS_WRITING_Pos (20U) +#define ETH_MACDBGR_TFRS_WRITING_Msk (0x3U << ETH_MACDBGR_TFRS_WRITING_Pos) /*!< 0x00300000 */ +#define ETH_MACDBGR_TFRS_WRITING ETH_MACDBGR_TFRS_WRITING_Msk /* Writing the received TxStatus or flushing the TxFIFO */ +#define ETH_MACDBGR_TFRS_WAITING_Pos (21U) +#define ETH_MACDBGR_TFRS_WAITING_Msk (0x1U << ETH_MACDBGR_TFRS_WAITING_Pos) /*!< 0x00200000 */ +#define ETH_MACDBGR_TFRS_WAITING ETH_MACDBGR_TFRS_WAITING_Msk /* Waiting for TxStatus from MAC transmitter */ +#define ETH_MACDBGR_TFRS_READ_Pos (20U) +#define ETH_MACDBGR_TFRS_READ_Msk (0x1U << ETH_MACDBGR_TFRS_READ_Pos) /*!< 0x00100000 */ +#define ETH_MACDBGR_TFRS_READ ETH_MACDBGR_TFRS_READ_Msk /* Read state (transferring data to the MAC transmitter) */ +#define ETH_MACDBGR_TFRS_IDLE 0x00000000U /* Idle state */ +#define ETH_MACDBGR_MTP_Pos (19U) +#define ETH_MACDBGR_MTP_Msk (0x1U << ETH_MACDBGR_MTP_Pos) /*!< 0x00080000 */ +#define ETH_MACDBGR_MTP ETH_MACDBGR_MTP_Msk /* MAC transmitter in pause */ +#define ETH_MACDBGR_MTFCS_Pos (17U) +#define ETH_MACDBGR_MTFCS_Msk (0x3U << ETH_MACDBGR_MTFCS_Pos) /*!< 0x00060000 */ +#define ETH_MACDBGR_MTFCS ETH_MACDBGR_MTFCS_Msk /* MAC transmit frame controller status mask */ +#define ETH_MACDBGR_MTFCS_TRANSFERRING_Pos (17U) +#define ETH_MACDBGR_MTFCS_TRANSFERRING_Msk (0x3U << ETH_MACDBGR_MTFCS_TRANSFERRING_Pos) /*!< 0x00060000 */ +#define ETH_MACDBGR_MTFCS_TRANSFERRING ETH_MACDBGR_MTFCS_TRANSFERRING_Msk /* Transferring input frame for transmission */ +#define ETH_MACDBGR_MTFCS_GENERATINGPCF_Pos (18U) +#define ETH_MACDBGR_MTFCS_GENERATINGPCF_Msk (0x1U << ETH_MACDBGR_MTFCS_GENERATINGPCF_Pos) /*!< 0x00040000 */ +#define ETH_MACDBGR_MTFCS_GENERATINGPCF ETH_MACDBGR_MTFCS_GENERATINGPCF_Msk /* Generating and transmitting a Pause control frame (in full duplex mode) */ +#define ETH_MACDBGR_MTFCS_WAITING_Pos (17U) +#define ETH_MACDBGR_MTFCS_WAITING_Msk (0x1U << ETH_MACDBGR_MTFCS_WAITING_Pos) /*!< 0x00020000 */ +#define ETH_MACDBGR_MTFCS_WAITING ETH_MACDBGR_MTFCS_WAITING_Msk /* Waiting for Status of previous frame or IFG/backoff period to be over */ +#define ETH_MACDBGR_MTFCS_IDLE 0x00000000U /* Idle */ +#define ETH_MACDBGR_MMTEA_Pos (16U) +#define ETH_MACDBGR_MMTEA_Msk (0x1U << ETH_MACDBGR_MMTEA_Pos) /*!< 0x00010000 */ +#define ETH_MACDBGR_MMTEA ETH_MACDBGR_MMTEA_Msk /* MAC MII transmit engine active */ +#define ETH_MACDBGR_RFFL_Pos (8U) +#define ETH_MACDBGR_RFFL_Msk (0x3U << ETH_MACDBGR_RFFL_Pos) /*!< 0x00000300 */ +#define ETH_MACDBGR_RFFL ETH_MACDBGR_RFFL_Msk /* Rx FIFO fill level mask */ +#define ETH_MACDBGR_RFFL_FULL_Pos (8U) +#define ETH_MACDBGR_RFFL_FULL_Msk (0x3U << ETH_MACDBGR_RFFL_FULL_Pos) /*!< 0x00000300 */ +#define ETH_MACDBGR_RFFL_FULL ETH_MACDBGR_RFFL_FULL_Msk /* RxFIFO full */ +#define ETH_MACDBGR_RFFL_ABOVEFCT_Pos (9U) +#define ETH_MACDBGR_RFFL_ABOVEFCT_Msk (0x1U << ETH_MACDBGR_RFFL_ABOVEFCT_Pos) /*!< 0x00000200 */ +#define ETH_MACDBGR_RFFL_ABOVEFCT ETH_MACDBGR_RFFL_ABOVEFCT_Msk /* RxFIFO fill-level above flow-control activate threshold */ +#define ETH_MACDBGR_RFFL_BELOWFCT_Pos (8U) +#define ETH_MACDBGR_RFFL_BELOWFCT_Msk (0x1U << ETH_MACDBGR_RFFL_BELOWFCT_Pos) /*!< 0x00000100 */ +#define ETH_MACDBGR_RFFL_BELOWFCT ETH_MACDBGR_RFFL_BELOWFCT_Msk /* RxFIFO fill-level below flow-control de-activate threshold */ +#define ETH_MACDBGR_RFFL_EMPTY 0x00000000U /* RxFIFO empty */ +#define ETH_MACDBGR_RFRCS_Pos (5U) +#define ETH_MACDBGR_RFRCS_Msk (0x3U << ETH_MACDBGR_RFRCS_Pos) /*!< 0x00000060 */ +#define ETH_MACDBGR_RFRCS ETH_MACDBGR_RFRCS_Msk /* Rx FIFO read controller status mask */ +#define ETH_MACDBGR_RFRCS_FLUSHING_Pos (5U) +#define ETH_MACDBGR_RFRCS_FLUSHING_Msk (0x3U << ETH_MACDBGR_RFRCS_FLUSHING_Pos) /*!< 0x00000060 */ +#define ETH_MACDBGR_RFRCS_FLUSHING ETH_MACDBGR_RFRCS_FLUSHING_Msk /* Flushing the frame data and status */ +#define ETH_MACDBGR_RFRCS_STATUSREADING_Pos (6U) +#define ETH_MACDBGR_RFRCS_STATUSREADING_Msk (0x1U << ETH_MACDBGR_RFRCS_STATUSREADING_Pos) /*!< 0x00000040 */ +#define ETH_MACDBGR_RFRCS_STATUSREADING ETH_MACDBGR_RFRCS_STATUSREADING_Msk /* Reading frame status (or time-stamp) */ +#define ETH_MACDBGR_RFRCS_DATAREADING_Pos (5U) +#define ETH_MACDBGR_RFRCS_DATAREADING_Msk (0x1U << ETH_MACDBGR_RFRCS_DATAREADING_Pos) /*!< 0x00000020 */ +#define ETH_MACDBGR_RFRCS_DATAREADING ETH_MACDBGR_RFRCS_DATAREADING_Msk /* Reading frame data */ +#define ETH_MACDBGR_RFRCS_IDLE 0x00000000U /* IDLE state */ +#define ETH_MACDBGR_RFWRA_Pos (4U) +#define ETH_MACDBGR_RFWRA_Msk (0x1U << ETH_MACDBGR_RFWRA_Pos) /*!< 0x00000010 */ +#define ETH_MACDBGR_RFWRA ETH_MACDBGR_RFWRA_Msk /* Rx FIFO write controller active */ +#define ETH_MACDBGR_MSFRWCS_Pos (1U) +#define ETH_MACDBGR_MSFRWCS_Msk (0x3U << ETH_MACDBGR_MSFRWCS_Pos) /*!< 0x00000006 */ +#define ETH_MACDBGR_MSFRWCS ETH_MACDBGR_MSFRWCS_Msk /* MAC small FIFO read / write controllers status mask */ +#define ETH_MACDBGR_MSFRWCS_1 (0x2U << ETH_MACDBGR_MSFRWCS_Pos) /*!< 0x00000004 */ +#define ETH_MACDBGR_MSFRWCS_0 (0x1U << ETH_MACDBGR_MSFRWCS_Pos) /*!< 0x00000002 */ +#define ETH_MACDBGR_MMRPEA_Pos (0U) +#define ETH_MACDBGR_MMRPEA_Msk (0x1U << ETH_MACDBGR_MMRPEA_Pos) /*!< 0x00000001 */ +#define ETH_MACDBGR_MMRPEA ETH_MACDBGR_MMRPEA_Msk /* MAC MII receive protocol engine active */ + +/* Bit definition for Ethernet MAC Status Register */ +#define ETH_MACSR_TSTS_Pos (9U) +#define ETH_MACSR_TSTS_Msk (0x1U << ETH_MACSR_TSTS_Pos) /*!< 0x00000200 */ +#define ETH_MACSR_TSTS ETH_MACSR_TSTS_Msk /* Time stamp trigger status */ +#define ETH_MACSR_MMCTS_Pos (6U) +#define ETH_MACSR_MMCTS_Msk (0x1U << ETH_MACSR_MMCTS_Pos) /*!< 0x00000040 */ +#define ETH_MACSR_MMCTS ETH_MACSR_MMCTS_Msk /* MMC transmit status */ +#define ETH_MACSR_MMMCRS_Pos (5U) +#define ETH_MACSR_MMMCRS_Msk (0x1U << ETH_MACSR_MMMCRS_Pos) /*!< 0x00000020 */ +#define ETH_MACSR_MMMCRS ETH_MACSR_MMMCRS_Msk /* MMC receive status */ +#define ETH_MACSR_MMCS_Pos (4U) +#define ETH_MACSR_MMCS_Msk (0x1U << ETH_MACSR_MMCS_Pos) /*!< 0x00000010 */ +#define ETH_MACSR_MMCS ETH_MACSR_MMCS_Msk /* MMC status */ +#define ETH_MACSR_PMTS_Pos (3U) +#define ETH_MACSR_PMTS_Msk (0x1U << ETH_MACSR_PMTS_Pos) /*!< 0x00000008 */ +#define ETH_MACSR_PMTS ETH_MACSR_PMTS_Msk /* PMT status */ + +/* Bit definition for Ethernet MAC Interrupt Mask Register */ +#define ETH_MACIMR_TSTIM_Pos (9U) +#define ETH_MACIMR_TSTIM_Msk (0x1U << ETH_MACIMR_TSTIM_Pos) /*!< 0x00000200 */ +#define ETH_MACIMR_TSTIM ETH_MACIMR_TSTIM_Msk /* Time stamp trigger interrupt mask */ +#define ETH_MACIMR_PMTIM_Pos (3U) +#define ETH_MACIMR_PMTIM_Msk (0x1U << ETH_MACIMR_PMTIM_Pos) /*!< 0x00000008 */ +#define ETH_MACIMR_PMTIM ETH_MACIMR_PMTIM_Msk /* PMT interrupt mask */ + +/* Bit definition for Ethernet MAC Address0 High Register */ +#define ETH_MACA0HR_MACA0H_Pos (0U) +#define ETH_MACA0HR_MACA0H_Msk (0xFFFFU << ETH_MACA0HR_MACA0H_Pos) /*!< 0x0000FFFF */ +#define ETH_MACA0HR_MACA0H ETH_MACA0HR_MACA0H_Msk /* MAC address0 high */ + +/* Bit definition for Ethernet MAC Address0 Low Register */ +#define ETH_MACA0LR_MACA0L_Pos (0U) +#define ETH_MACA0LR_MACA0L_Msk (0xFFFFFFFFU << ETH_MACA0LR_MACA0L_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MACA0LR_MACA0L ETH_MACA0LR_MACA0L_Msk /* MAC address0 low */ + +/* Bit definition for Ethernet MAC Address1 High Register */ +#define ETH_MACA1HR_AE_Pos (31U) +#define ETH_MACA1HR_AE_Msk (0x1U << ETH_MACA1HR_AE_Pos) /*!< 0x80000000 */ +#define ETH_MACA1HR_AE ETH_MACA1HR_AE_Msk /* Address enable */ +#define ETH_MACA1HR_SA_Pos (30U) +#define ETH_MACA1HR_SA_Msk (0x1U << ETH_MACA1HR_SA_Pos) /*!< 0x40000000 */ +#define ETH_MACA1HR_SA ETH_MACA1HR_SA_Msk /* Source address */ +#define ETH_MACA1HR_MBC_Pos (24U) +#define ETH_MACA1HR_MBC_Msk (0x3FU << ETH_MACA1HR_MBC_Pos) /*!< 0x3F000000 */ +#define ETH_MACA1HR_MBC ETH_MACA1HR_MBC_Msk /* Mask byte control: bits to mask for comparison of the MAC Address bytes */ +#define ETH_MACA1HR_MBC_HBits15_8 0x20000000U /* Mask MAC Address high reg bits [15:8] */ +#define ETH_MACA1HR_MBC_HBits7_0 0x10000000U /* Mask MAC Address high reg bits [7:0] */ +#define ETH_MACA1HR_MBC_LBits31_24 0x08000000U /* Mask MAC Address low reg bits [31:24] */ +#define ETH_MACA1HR_MBC_LBits23_16 0x04000000U /* Mask MAC Address low reg bits [23:16] */ +#define ETH_MACA1HR_MBC_LBits15_8 0x02000000U /* Mask MAC Address low reg bits [15:8] */ +#define ETH_MACA1HR_MBC_LBits7_0 0x01000000U /* Mask MAC Address low reg bits [7:0] */ +#define ETH_MACA1HR_MACA1H_Pos (0U) +#define ETH_MACA1HR_MACA1H_Msk (0xFFFFU << ETH_MACA1HR_MACA1H_Pos) /*!< 0x0000FFFF */ +#define ETH_MACA1HR_MACA1H ETH_MACA1HR_MACA1H_Msk /* MAC address1 high */ + +/* Bit definition for Ethernet MAC Address1 Low Register */ +#define ETH_MACA1LR_MACA1L_Pos (0U) +#define ETH_MACA1LR_MACA1L_Msk (0xFFFFFFFFU << ETH_MACA1LR_MACA1L_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MACA1LR_MACA1L ETH_MACA1LR_MACA1L_Msk /* MAC address1 low */ + +/* Bit definition for Ethernet MAC Address2 High Register */ +#define ETH_MACA2HR_AE_Pos (31U) +#define ETH_MACA2HR_AE_Msk (0x1U << ETH_MACA2HR_AE_Pos) /*!< 0x80000000 */ +#define ETH_MACA2HR_AE ETH_MACA2HR_AE_Msk /* Address enable */ +#define ETH_MACA2HR_SA_Pos (30U) +#define ETH_MACA2HR_SA_Msk (0x1U << ETH_MACA2HR_SA_Pos) /*!< 0x40000000 */ +#define ETH_MACA2HR_SA ETH_MACA2HR_SA_Msk /* Source address */ +#define ETH_MACA2HR_MBC_Pos (24U) +#define ETH_MACA2HR_MBC_Msk (0x3FU << ETH_MACA2HR_MBC_Pos) /*!< 0x3F000000 */ +#define ETH_MACA2HR_MBC ETH_MACA2HR_MBC_Msk /* Mask byte control */ +#define ETH_MACA2HR_MBC_HBits15_8 0x20000000U /* Mask MAC Address high reg bits [15:8] */ +#define ETH_MACA2HR_MBC_HBits7_0 0x10000000U /* Mask MAC Address high reg bits [7:0] */ +#define ETH_MACA2HR_MBC_LBits31_24 0x08000000U /* Mask MAC Address low reg bits [31:24] */ +#define ETH_MACA2HR_MBC_LBits23_16 0x04000000U /* Mask MAC Address low reg bits [23:16] */ +#define ETH_MACA2HR_MBC_LBits15_8 0x02000000U /* Mask MAC Address low reg bits [15:8] */ +#define ETH_MACA2HR_MBC_LBits7_0 0x01000000U /* Mask MAC Address low reg bits [70] */ +#define ETH_MACA2HR_MACA2H_Pos (0U) +#define ETH_MACA2HR_MACA2H_Msk (0xFFFFU << ETH_MACA2HR_MACA2H_Pos) /*!< 0x0000FFFF */ +#define ETH_MACA2HR_MACA2H ETH_MACA2HR_MACA2H_Msk /* MAC address1 high */ + +/* Bit definition for Ethernet MAC Address2 Low Register */ +#define ETH_MACA2LR_MACA2L_Pos (0U) +#define ETH_MACA2LR_MACA2L_Msk (0xFFFFFFFFU << ETH_MACA2LR_MACA2L_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MACA2LR_MACA2L ETH_MACA2LR_MACA2L_Msk /* MAC address2 low */ + +/* Bit definition for Ethernet MAC Address3 High Register */ +#define ETH_MACA3HR_AE_Pos (31U) +#define ETH_MACA3HR_AE_Msk (0x1U << ETH_MACA3HR_AE_Pos) /*!< 0x80000000 */ +#define ETH_MACA3HR_AE ETH_MACA3HR_AE_Msk /* Address enable */ +#define ETH_MACA3HR_SA_Pos (30U) +#define ETH_MACA3HR_SA_Msk (0x1U << ETH_MACA3HR_SA_Pos) /*!< 0x40000000 */ +#define ETH_MACA3HR_SA ETH_MACA3HR_SA_Msk /* Source address */ +#define ETH_MACA3HR_MBC_Pos (24U) +#define ETH_MACA3HR_MBC_Msk (0x3FU << ETH_MACA3HR_MBC_Pos) /*!< 0x3F000000 */ +#define ETH_MACA3HR_MBC ETH_MACA3HR_MBC_Msk /* Mask byte control */ +#define ETH_MACA3HR_MBC_HBits15_8 0x20000000U /* Mask MAC Address high reg bits [15:8] */ +#define ETH_MACA3HR_MBC_HBits7_0 0x10000000U /* Mask MAC Address high reg bits [7:0] */ +#define ETH_MACA3HR_MBC_LBits31_24 0x08000000U /* Mask MAC Address low reg bits [31:24] */ +#define ETH_MACA3HR_MBC_LBits23_16 0x04000000U /* Mask MAC Address low reg bits [23:16] */ +#define ETH_MACA3HR_MBC_LBits15_8 0x02000000U /* Mask MAC Address low reg bits [15:8] */ +#define ETH_MACA3HR_MBC_LBits7_0 0x01000000U /* Mask MAC Address low reg bits [70] */ +#define ETH_MACA3HR_MACA3H_Pos (0U) +#define ETH_MACA3HR_MACA3H_Msk (0xFFFFU << ETH_MACA3HR_MACA3H_Pos) /*!< 0x0000FFFF */ +#define ETH_MACA3HR_MACA3H ETH_MACA3HR_MACA3H_Msk /* MAC address3 high */ + +/* Bit definition for Ethernet MAC Address3 Low Register */ +#define ETH_MACA3LR_MACA3L_Pos (0U) +#define ETH_MACA3LR_MACA3L_Msk (0xFFFFFFFFU << ETH_MACA3LR_MACA3L_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MACA3LR_MACA3L ETH_MACA3LR_MACA3L_Msk /* MAC address3 low */ + +/******************************************************************************/ +/* Ethernet MMC Registers bits definition */ +/******************************************************************************/ + +/* Bit definition for Ethernet MMC Contol Register */ +#define ETH_MMCCR_MCFHP_Pos (5U) +#define ETH_MMCCR_MCFHP_Msk (0x1U << ETH_MMCCR_MCFHP_Pos) /*!< 0x00000020 */ +#define ETH_MMCCR_MCFHP ETH_MMCCR_MCFHP_Msk /* MMC counter Full-Half preset */ +#define ETH_MMCCR_MCP_Pos (4U) +#define ETH_MMCCR_MCP_Msk (0x1U << ETH_MMCCR_MCP_Pos) /*!< 0x00000010 */ +#define ETH_MMCCR_MCP ETH_MMCCR_MCP_Msk /* MMC counter preset */ +#define ETH_MMCCR_MCF_Pos (3U) +#define ETH_MMCCR_MCF_Msk (0x1U << ETH_MMCCR_MCF_Pos) /*!< 0x00000008 */ +#define ETH_MMCCR_MCF ETH_MMCCR_MCF_Msk /* MMC Counter Freeze */ +#define ETH_MMCCR_ROR_Pos (2U) +#define ETH_MMCCR_ROR_Msk (0x1U << ETH_MMCCR_ROR_Pos) /*!< 0x00000004 */ +#define ETH_MMCCR_ROR ETH_MMCCR_ROR_Msk /* Reset on Read */ +#define ETH_MMCCR_CSR_Pos (1U) +#define ETH_MMCCR_CSR_Msk (0x1U << ETH_MMCCR_CSR_Pos) /*!< 0x00000002 */ +#define ETH_MMCCR_CSR ETH_MMCCR_CSR_Msk /* Counter Stop Rollover */ +#define ETH_MMCCR_CR_Pos (0U) +#define ETH_MMCCR_CR_Msk (0x1U << ETH_MMCCR_CR_Pos) /*!< 0x00000001 */ +#define ETH_MMCCR_CR ETH_MMCCR_CR_Msk /* Counters Reset */ + +/* Bit definition for Ethernet MMC Receive Interrupt Register */ +#define ETH_MMCRIR_RGUFS_Pos (17U) +#define ETH_MMCRIR_RGUFS_Msk (0x1U << ETH_MMCRIR_RGUFS_Pos) /*!< 0x00020000 */ +#define ETH_MMCRIR_RGUFS ETH_MMCRIR_RGUFS_Msk /* Set when Rx good unicast frames counter reaches half the maximum value */ +#define ETH_MMCRIR_RFAES_Pos (6U) +#define ETH_MMCRIR_RFAES_Msk (0x1U << ETH_MMCRIR_RFAES_Pos) /*!< 0x00000040 */ +#define ETH_MMCRIR_RFAES ETH_MMCRIR_RFAES_Msk /* Set when Rx alignment error counter reaches half the maximum value */ +#define ETH_MMCRIR_RFCES_Pos (5U) +#define ETH_MMCRIR_RFCES_Msk (0x1U << ETH_MMCRIR_RFCES_Pos) /*!< 0x00000020 */ +#define ETH_MMCRIR_RFCES ETH_MMCRIR_RFCES_Msk /* Set when Rx crc error counter reaches half the maximum value */ + +/* Bit definition for Ethernet MMC Transmit Interrupt Register */ +#define ETH_MMCTIR_TGFS_Pos (21U) +#define ETH_MMCTIR_TGFS_Msk (0x1U << ETH_MMCTIR_TGFS_Pos) /*!< 0x00200000 */ +#define ETH_MMCTIR_TGFS ETH_MMCTIR_TGFS_Msk /* Set when Tx good frame count counter reaches half the maximum value */ +#define ETH_MMCTIR_TGFMSCS_Pos (15U) +#define ETH_MMCTIR_TGFMSCS_Msk (0x1U << ETH_MMCTIR_TGFMSCS_Pos) /*!< 0x00008000 */ +#define ETH_MMCTIR_TGFMSCS ETH_MMCTIR_TGFMSCS_Msk /* Set when Tx good multi col counter reaches half the maximum value */ +#define ETH_MMCTIR_TGFSCS_Pos (14U) +#define ETH_MMCTIR_TGFSCS_Msk (0x1U << ETH_MMCTIR_TGFSCS_Pos) /*!< 0x00004000 */ +#define ETH_MMCTIR_TGFSCS ETH_MMCTIR_TGFSCS_Msk /* Set when Tx good single col counter reaches half the maximum value */ + +/* Bit definition for Ethernet MMC Receive Interrupt Mask Register */ +#define ETH_MMCRIMR_RGUFM_Pos (17U) +#define ETH_MMCRIMR_RGUFM_Msk (0x1U << ETH_MMCRIMR_RGUFM_Pos) /*!< 0x00020000 */ +#define ETH_MMCRIMR_RGUFM ETH_MMCRIMR_RGUFM_Msk /* Mask the interrupt when Rx good unicast frames counter reaches half the maximum value */ +#define ETH_MMCRIMR_RFAEM_Pos (6U) +#define ETH_MMCRIMR_RFAEM_Msk (0x1U << ETH_MMCRIMR_RFAEM_Pos) /*!< 0x00000040 */ +#define ETH_MMCRIMR_RFAEM ETH_MMCRIMR_RFAEM_Msk /* Mask the interrupt when when Rx alignment error counter reaches half the maximum value */ +#define ETH_MMCRIMR_RFCEM_Pos (5U) +#define ETH_MMCRIMR_RFCEM_Msk (0x1U << ETH_MMCRIMR_RFCEM_Pos) /*!< 0x00000020 */ +#define ETH_MMCRIMR_RFCEM ETH_MMCRIMR_RFCEM_Msk /* Mask the interrupt when Rx crc error counter reaches half the maximum value */ + +/* Bit definition for Ethernet MMC Transmit Interrupt Mask Register */ +#define ETH_MMCTIMR_TGFM_Pos (21U) +#define ETH_MMCTIMR_TGFM_Msk (0x1U << ETH_MMCTIMR_TGFM_Pos) /*!< 0x00200000 */ +#define ETH_MMCTIMR_TGFM ETH_MMCTIMR_TGFM_Msk /* Mask the interrupt when Tx good frame count counter reaches half the maximum value */ +#define ETH_MMCTIMR_TGFMSCM_Pos (15U) +#define ETH_MMCTIMR_TGFMSCM_Msk (0x1U << ETH_MMCTIMR_TGFMSCM_Pos) /*!< 0x00008000 */ +#define ETH_MMCTIMR_TGFMSCM ETH_MMCTIMR_TGFMSCM_Msk /* Mask the interrupt when Tx good multi col counter reaches half the maximum value */ +#define ETH_MMCTIMR_TGFSCM_Pos (14U) +#define ETH_MMCTIMR_TGFSCM_Msk (0x1U << ETH_MMCTIMR_TGFSCM_Pos) /*!< 0x00004000 */ +#define ETH_MMCTIMR_TGFSCM ETH_MMCTIMR_TGFSCM_Msk /* Mask the interrupt when Tx good single col counter reaches half the maximum value */ + +/* Bit definition for Ethernet MMC Transmitted Good Frames after Single Collision Counter Register */ +#define ETH_MMCTGFSCCR_TGFSCC_Pos (0U) +#define ETH_MMCTGFSCCR_TGFSCC_Msk (0xFFFFFFFFU << ETH_MMCTGFSCCR_TGFSCC_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MMCTGFSCCR_TGFSCC ETH_MMCTGFSCCR_TGFSCC_Msk /* Number of successfully transmitted frames after a single collision in Half-duplex mode. */ + +/* Bit definition for Ethernet MMC Transmitted Good Frames after More than a Single Collision Counter Register */ +#define ETH_MMCTGFMSCCR_TGFMSCC_Pos (0U) +#define ETH_MMCTGFMSCCR_TGFMSCC_Msk (0xFFFFFFFFU << ETH_MMCTGFMSCCR_TGFMSCC_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MMCTGFMSCCR_TGFMSCC ETH_MMCTGFMSCCR_TGFMSCC_Msk /* Number of successfully transmitted frames after more than a single collision in Half-duplex mode. */ + +/* Bit definition for Ethernet MMC Transmitted Good Frames Counter Register */ +#define ETH_MMCTGFCR_TGFC_Pos (0U) +#define ETH_MMCTGFCR_TGFC_Msk (0xFFFFFFFFU << ETH_MMCTGFCR_TGFC_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MMCTGFCR_TGFC ETH_MMCTGFCR_TGFC_Msk /* Number of good frames transmitted. */ + +/* Bit definition for Ethernet MMC Received Frames with CRC Error Counter Register */ +#define ETH_MMCRFCECR_RFCEC_Pos (0U) +#define ETH_MMCRFCECR_RFCEC_Msk (0xFFFFFFFFU << ETH_MMCRFCECR_RFCEC_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MMCRFCECR_RFCEC ETH_MMCRFCECR_RFCEC_Msk /* Number of frames received with CRC error. */ + +/* Bit definition for Ethernet MMC Received Frames with Alignement Error Counter Register */ +#define ETH_MMCRFAECR_RFAEC_Pos (0U) +#define ETH_MMCRFAECR_RFAEC_Msk (0xFFFFFFFFU << ETH_MMCRFAECR_RFAEC_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MMCRFAECR_RFAEC ETH_MMCRFAECR_RFAEC_Msk /* Number of frames received with alignment (dribble) error */ + +/* Bit definition for Ethernet MMC Received Good Unicast Frames Counter Register */ +#define ETH_MMCRGUFCR_RGUFC_Pos (0U) +#define ETH_MMCRGUFCR_RGUFC_Msk (0xFFFFFFFFU << ETH_MMCRGUFCR_RGUFC_Pos) /*!< 0xFFFFFFFF */ +#define ETH_MMCRGUFCR_RGUFC ETH_MMCRGUFCR_RGUFC_Msk /* Number of good unicast frames received. */ + +/******************************************************************************/ +/* Ethernet PTP Registers bits definition */ +/******************************************************************************/ + +/* Bit definition for Ethernet PTP Time Stamp Contol Register */ +#define ETH_PTPTSCR_TSCNT_Pos (16U) +#define ETH_PTPTSCR_TSCNT_Msk (0x3U << ETH_PTPTSCR_TSCNT_Pos) /*!< 0x00030000 */ +#define ETH_PTPTSCR_TSCNT ETH_PTPTSCR_TSCNT_Msk /* Time stamp clock node type */ +#define ETH_PTPTSSR_TSSMRME_Pos (15U) +#define ETH_PTPTSSR_TSSMRME_Msk (0x1U << ETH_PTPTSSR_TSSMRME_Pos) /*!< 0x00008000 */ +#define ETH_PTPTSSR_TSSMRME ETH_PTPTSSR_TSSMRME_Msk /* Time stamp snapshot for message relevant to master enable */ +#define ETH_PTPTSSR_TSSEME_Pos (14U) +#define ETH_PTPTSSR_TSSEME_Msk (0x1U << ETH_PTPTSSR_TSSEME_Pos) /*!< 0x00004000 */ +#define ETH_PTPTSSR_TSSEME ETH_PTPTSSR_TSSEME_Msk /* Time stamp snapshot for event message enable */ +#define ETH_PTPTSSR_TSSIPV4FE_Pos (13U) +#define ETH_PTPTSSR_TSSIPV4FE_Msk (0x1U << ETH_PTPTSSR_TSSIPV4FE_Pos) /*!< 0x00002000 */ +#define ETH_PTPTSSR_TSSIPV4FE ETH_PTPTSSR_TSSIPV4FE_Msk /* Time stamp snapshot for IPv4 frames enable */ +#define ETH_PTPTSSR_TSSIPV6FE_Pos (12U) +#define ETH_PTPTSSR_TSSIPV6FE_Msk (0x1U << ETH_PTPTSSR_TSSIPV6FE_Pos) /*!< 0x00001000 */ +#define ETH_PTPTSSR_TSSIPV6FE ETH_PTPTSSR_TSSIPV6FE_Msk /* Time stamp snapshot for IPv6 frames enable */ +#define ETH_PTPTSSR_TSSPTPOEFE_Pos (11U) +#define ETH_PTPTSSR_TSSPTPOEFE_Msk (0x1U << ETH_PTPTSSR_TSSPTPOEFE_Pos) /*!< 0x00000800 */ +#define ETH_PTPTSSR_TSSPTPOEFE ETH_PTPTSSR_TSSPTPOEFE_Msk /* Time stamp snapshot for PTP over ethernet frames enable */ +#define ETH_PTPTSSR_TSPTPPSV2E_Pos (10U) +#define ETH_PTPTSSR_TSPTPPSV2E_Msk (0x1U << ETH_PTPTSSR_TSPTPPSV2E_Pos) /*!< 0x00000400 */ +#define ETH_PTPTSSR_TSPTPPSV2E ETH_PTPTSSR_TSPTPPSV2E_Msk /* Time stamp PTP packet snooping for version2 format enable */ +#define ETH_PTPTSSR_TSSSR_Pos (9U) +#define ETH_PTPTSSR_TSSSR_Msk (0x1U << ETH_PTPTSSR_TSSSR_Pos) /*!< 0x00000200 */ +#define ETH_PTPTSSR_TSSSR ETH_PTPTSSR_TSSSR_Msk /* Time stamp Sub-seconds rollover */ +#define ETH_PTPTSSR_TSSARFE_Pos (8U) +#define ETH_PTPTSSR_TSSARFE_Msk (0x1U << ETH_PTPTSSR_TSSARFE_Pos) /*!< 0x00000100 */ +#define ETH_PTPTSSR_TSSARFE ETH_PTPTSSR_TSSARFE_Msk /* Time stamp snapshot for all received frames enable */ + +#define ETH_PTPTSCR_TSARU_Pos (5U) +#define ETH_PTPTSCR_TSARU_Msk (0x1U << ETH_PTPTSCR_TSARU_Pos) /*!< 0x00000020 */ +#define ETH_PTPTSCR_TSARU ETH_PTPTSCR_TSARU_Msk /* Addend register update */ +#define ETH_PTPTSCR_TSITE_Pos (4U) +#define ETH_PTPTSCR_TSITE_Msk (0x1U << ETH_PTPTSCR_TSITE_Pos) /*!< 0x00000010 */ +#define ETH_PTPTSCR_TSITE ETH_PTPTSCR_TSITE_Msk /* Time stamp interrupt trigger enable */ +#define ETH_PTPTSCR_TSSTU_Pos (3U) +#define ETH_PTPTSCR_TSSTU_Msk (0x1U << ETH_PTPTSCR_TSSTU_Pos) /*!< 0x00000008 */ +#define ETH_PTPTSCR_TSSTU ETH_PTPTSCR_TSSTU_Msk /* Time stamp update */ +#define ETH_PTPTSCR_TSSTI_Pos (2U) +#define ETH_PTPTSCR_TSSTI_Msk (0x1U << ETH_PTPTSCR_TSSTI_Pos) /*!< 0x00000004 */ +#define ETH_PTPTSCR_TSSTI ETH_PTPTSCR_TSSTI_Msk /* Time stamp initialize */ +#define ETH_PTPTSCR_TSFCU_Pos (1U) +#define ETH_PTPTSCR_TSFCU_Msk (0x1U << ETH_PTPTSCR_TSFCU_Pos) /*!< 0x00000002 */ +#define ETH_PTPTSCR_TSFCU ETH_PTPTSCR_TSFCU_Msk /* Time stamp fine or coarse update */ +#define ETH_PTPTSCR_TSE_Pos (0U) +#define ETH_PTPTSCR_TSE_Msk (0x1U << ETH_PTPTSCR_TSE_Pos) /*!< 0x00000001 */ +#define ETH_PTPTSCR_TSE ETH_PTPTSCR_TSE_Msk /* Time stamp enable */ + +/* Bit definition for Ethernet PTP Sub-Second Increment Register */ +#define ETH_PTPSSIR_STSSI_Pos (0U) +#define ETH_PTPSSIR_STSSI_Msk (0xFFU << ETH_PTPSSIR_STSSI_Pos) /*!< 0x000000FF */ +#define ETH_PTPSSIR_STSSI ETH_PTPSSIR_STSSI_Msk /* System time Sub-second increment value */ + +/* Bit definition for Ethernet PTP Time Stamp High Register */ +#define ETH_PTPTSHR_STS_Pos (0U) +#define ETH_PTPTSHR_STS_Msk (0xFFFFFFFFU << ETH_PTPTSHR_STS_Pos) /*!< 0xFFFFFFFF */ +#define ETH_PTPTSHR_STS ETH_PTPTSHR_STS_Msk /* System Time second */ + +/* Bit definition for Ethernet PTP Time Stamp Low Register */ +#define ETH_PTPTSLR_STPNS_Pos (31U) +#define ETH_PTPTSLR_STPNS_Msk (0x1U << ETH_PTPTSLR_STPNS_Pos) /*!< 0x80000000 */ +#define ETH_PTPTSLR_STPNS ETH_PTPTSLR_STPNS_Msk /* System Time Positive or negative time */ +#define ETH_PTPTSLR_STSS_Pos (0U) +#define ETH_PTPTSLR_STSS_Msk (0x7FFFFFFFU << ETH_PTPTSLR_STSS_Pos) /*!< 0x7FFFFFFF */ +#define ETH_PTPTSLR_STSS ETH_PTPTSLR_STSS_Msk /* System Time sub-seconds */ + +/* Bit definition for Ethernet PTP Time Stamp High Update Register */ +#define ETH_PTPTSHUR_TSUS_Pos (0U) +#define ETH_PTPTSHUR_TSUS_Msk (0xFFFFFFFFU << ETH_PTPTSHUR_TSUS_Pos) /*!< 0xFFFFFFFF */ +#define ETH_PTPTSHUR_TSUS ETH_PTPTSHUR_TSUS_Msk /* Time stamp update seconds */ + +/* Bit definition for Ethernet PTP Time Stamp Low Update Register */ +#define ETH_PTPTSLUR_TSUPNS_Pos (31U) +#define ETH_PTPTSLUR_TSUPNS_Msk (0x1U << ETH_PTPTSLUR_TSUPNS_Pos) /*!< 0x80000000 */ +#define ETH_PTPTSLUR_TSUPNS ETH_PTPTSLUR_TSUPNS_Msk /* Time stamp update Positive or negative time */ +#define ETH_PTPTSLUR_TSUSS_Pos (0U) +#define ETH_PTPTSLUR_TSUSS_Msk (0x7FFFFFFFU << ETH_PTPTSLUR_TSUSS_Pos) /*!< 0x7FFFFFFF */ +#define ETH_PTPTSLUR_TSUSS ETH_PTPTSLUR_TSUSS_Msk /* Time stamp update sub-seconds */ + +/* Bit definition for Ethernet PTP Time Stamp Addend Register */ +#define ETH_PTPTSAR_TSA_Pos (0U) +#define ETH_PTPTSAR_TSA_Msk (0xFFFFFFFFU << ETH_PTPTSAR_TSA_Pos) /*!< 0xFFFFFFFF */ +#define ETH_PTPTSAR_TSA ETH_PTPTSAR_TSA_Msk /* Time stamp addend */ + +/* Bit definition for Ethernet PTP Target Time High Register */ +#define ETH_PTPTTHR_TTSH_Pos (0U) +#define ETH_PTPTTHR_TTSH_Msk (0xFFFFFFFFU << ETH_PTPTTHR_TTSH_Pos) /*!< 0xFFFFFFFF */ +#define ETH_PTPTTHR_TTSH ETH_PTPTTHR_TTSH_Msk /* Target time stamp high */ + +/* Bit definition for Ethernet PTP Target Time Low Register */ +#define ETH_PTPTTLR_TTSL_Pos (0U) +#define ETH_PTPTTLR_TTSL_Msk (0xFFFFFFFFU << ETH_PTPTTLR_TTSL_Pos) /*!< 0xFFFFFFFF */ +#define ETH_PTPTTLR_TTSL ETH_PTPTTLR_TTSL_Msk /* Target time stamp low */ + +/* Bit definition for Ethernet PTP Time Stamp Status Register */ +#define ETH_PTPTSSR_TSTTR_Pos (5U) +#define ETH_PTPTSSR_TSTTR_Msk (0x1U << ETH_PTPTSSR_TSTTR_Pos) /*!< 0x00000020 */ +#define ETH_PTPTSSR_TSTTR ETH_PTPTSSR_TSTTR_Msk /* Time stamp target time reached */ +#define ETH_PTPTSSR_TSSO_Pos (4U) +#define ETH_PTPTSSR_TSSO_Msk (0x1U << ETH_PTPTSSR_TSSO_Pos) /*!< 0x00000010 */ +#define ETH_PTPTSSR_TSSO ETH_PTPTSSR_TSSO_Msk /* Time stamp seconds overflow */ + +/******************************************************************************/ +/* Ethernet DMA Registers bits definition */ +/******************************************************************************/ + +/* Bit definition for Ethernet DMA Bus Mode Register */ +#define ETH_DMABMR_AAB_Pos (25U) +#define ETH_DMABMR_AAB_Msk (0x1U << ETH_DMABMR_AAB_Pos) /*!< 0x02000000 */ +#define ETH_DMABMR_AAB ETH_DMABMR_AAB_Msk /* Address-Aligned beats */ +#define ETH_DMABMR_FPM_Pos (24U) +#define ETH_DMABMR_FPM_Msk (0x1U << ETH_DMABMR_FPM_Pos) /*!< 0x01000000 */ +#define ETH_DMABMR_FPM ETH_DMABMR_FPM_Msk /* 4xPBL mode */ +#define ETH_DMABMR_USP_Pos (23U) +#define ETH_DMABMR_USP_Msk (0x1U << ETH_DMABMR_USP_Pos) /*!< 0x00800000 */ +#define ETH_DMABMR_USP ETH_DMABMR_USP_Msk /* Use separate PBL */ +#define ETH_DMABMR_RDP_Pos (17U) +#define ETH_DMABMR_RDP_Msk (0x3FU << ETH_DMABMR_RDP_Pos) /*!< 0x007E0000 */ +#define ETH_DMABMR_RDP ETH_DMABMR_RDP_Msk /* RxDMA PBL */ +#define ETH_DMABMR_RDP_1Beat 0x00020000U /* maximum number of beats to be transferred in one RxDMA transaction is 1 */ +#define ETH_DMABMR_RDP_2Beat 0x00040000U /* maximum number of beats to be transferred in one RxDMA transaction is 2 */ +#define ETH_DMABMR_RDP_4Beat 0x00080000U /* maximum number of beats to be transferred in one RxDMA transaction is 4 */ +#define ETH_DMABMR_RDP_8Beat 0x00100000U /* maximum number of beats to be transferred in one RxDMA transaction is 8 */ +#define ETH_DMABMR_RDP_16Beat 0x00200000U /* maximum number of beats to be transferred in one RxDMA transaction is 16 */ +#define ETH_DMABMR_RDP_32Beat 0x00400000U /* maximum number of beats to be transferred in one RxDMA transaction is 32 */ +#define ETH_DMABMR_RDP_4xPBL_4Beat 0x01020000U /* maximum number of beats to be transferred in one RxDMA transaction is 4 */ +#define ETH_DMABMR_RDP_4xPBL_8Beat 0x01040000U /* maximum number of beats to be transferred in one RxDMA transaction is 8 */ +#define ETH_DMABMR_RDP_4xPBL_16Beat 0x01080000U /* maximum number of beats to be transferred in one RxDMA transaction is 16 */ +#define ETH_DMABMR_RDP_4xPBL_32Beat 0x01100000U /* maximum number of beats to be transferred in one RxDMA transaction is 32 */ +#define ETH_DMABMR_RDP_4xPBL_64Beat 0x01200000U /* maximum number of beats to be transferred in one RxDMA transaction is 64 */ +#define ETH_DMABMR_RDP_4xPBL_128Beat 0x01400000U /* maximum number of beats to be transferred in one RxDMA transaction is 128 */ +#define ETH_DMABMR_FB_Pos (16U) +#define ETH_DMABMR_FB_Msk (0x1U << ETH_DMABMR_FB_Pos) /*!< 0x00010000 */ +#define ETH_DMABMR_FB ETH_DMABMR_FB_Msk /* Fixed Burst */ +#define ETH_DMABMR_RTPR_Pos (14U) +#define ETH_DMABMR_RTPR_Msk (0x3U << ETH_DMABMR_RTPR_Pos) /*!< 0x0000C000 */ +#define ETH_DMABMR_RTPR ETH_DMABMR_RTPR_Msk /* Rx Tx priority ratio */ +#define ETH_DMABMR_RTPR_1_1 0x00000000U /* Rx Tx priority ratio */ +#define ETH_DMABMR_RTPR_2_1 0x00004000U /* Rx Tx priority ratio */ +#define ETH_DMABMR_RTPR_3_1 0x00008000U /* Rx Tx priority ratio */ +#define ETH_DMABMR_RTPR_4_1 0x0000C000U /* Rx Tx priority ratio */ +#define ETH_DMABMR_PBL_Pos (8U) +#define ETH_DMABMR_PBL_Msk (0x3FU << ETH_DMABMR_PBL_Pos) /*!< 0x00003F00 */ +#define ETH_DMABMR_PBL ETH_DMABMR_PBL_Msk /* Programmable burst length */ +#define ETH_DMABMR_PBL_1Beat 0x00000100U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */ +#define ETH_DMABMR_PBL_2Beat 0x00000200U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */ +#define ETH_DMABMR_PBL_4Beat 0x00000400U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */ +#define ETH_DMABMR_PBL_8Beat 0x00000800U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */ +#define ETH_DMABMR_PBL_16Beat 0x00001000U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */ +#define ETH_DMABMR_PBL_32Beat 0x00002000U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */ +#define ETH_DMABMR_PBL_4xPBL_4Beat 0x01000100U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */ +#define ETH_DMABMR_PBL_4xPBL_8Beat 0x01000200U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */ +#define ETH_DMABMR_PBL_4xPBL_16Beat 0x01000400U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */ +#define ETH_DMABMR_PBL_4xPBL_32Beat 0x01000800U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */ +#define ETH_DMABMR_PBL_4xPBL_64Beat 0x01001000U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 64 */ +#define ETH_DMABMR_PBL_4xPBL_128Beat 0x01002000U /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 128 */ +#define ETH_DMABMR_EDE_Pos (7U) +#define ETH_DMABMR_EDE_Msk (0x1U << ETH_DMABMR_EDE_Pos) /*!< 0x00000080 */ +#define ETH_DMABMR_EDE ETH_DMABMR_EDE_Msk /* Enhanced Descriptor Enable */ +#define ETH_DMABMR_DSL_Pos (2U) +#define ETH_DMABMR_DSL_Msk (0x1FU << ETH_DMABMR_DSL_Pos) /*!< 0x0000007C */ +#define ETH_DMABMR_DSL ETH_DMABMR_DSL_Msk /* Descriptor Skip Length */ +#define ETH_DMABMR_DA_Pos (1U) +#define ETH_DMABMR_DA_Msk (0x1U << ETH_DMABMR_DA_Pos) /*!< 0x00000002 */ +#define ETH_DMABMR_DA ETH_DMABMR_DA_Msk /* DMA arbitration scheme */ +#define ETH_DMABMR_SR_Pos (0U) +#define ETH_DMABMR_SR_Msk (0x1U << ETH_DMABMR_SR_Pos) /*!< 0x00000001 */ +#define ETH_DMABMR_SR ETH_DMABMR_SR_Msk /* Software reset */ + +/* Bit definition for Ethernet DMA Transmit Poll Demand Register */ +#define ETH_DMATPDR_TPD_Pos (0U) +#define ETH_DMATPDR_TPD_Msk (0xFFFFFFFFU << ETH_DMATPDR_TPD_Pos) /*!< 0xFFFFFFFF */ +#define ETH_DMATPDR_TPD ETH_DMATPDR_TPD_Msk /* Transmit poll demand */ + +/* Bit definition for Ethernet DMA Receive Poll Demand Register */ +#define ETH_DMARPDR_RPD_Pos (0U) +#define ETH_DMARPDR_RPD_Msk (0xFFFFFFFFU << ETH_DMARPDR_RPD_Pos) /*!< 0xFFFFFFFF */ +#define ETH_DMARPDR_RPD ETH_DMARPDR_RPD_Msk /* Receive poll demand */ + +/* Bit definition for Ethernet DMA Receive Descriptor List Address Register */ +#define ETH_DMARDLAR_SRL_Pos (0U) +#define ETH_DMARDLAR_SRL_Msk (0xFFFFFFFFU << ETH_DMARDLAR_SRL_Pos) /*!< 0xFFFFFFFF */ +#define ETH_DMARDLAR_SRL ETH_DMARDLAR_SRL_Msk /* Start of receive list */ + +/* Bit definition for Ethernet DMA Transmit Descriptor List Address Register */ +#define ETH_DMATDLAR_STL_Pos (0U) +#define ETH_DMATDLAR_STL_Msk (0xFFFFFFFFU << ETH_DMATDLAR_STL_Pos) /*!< 0xFFFFFFFF */ +#define ETH_DMATDLAR_STL ETH_DMATDLAR_STL_Msk /* Start of transmit list */ + +/* Bit definition for Ethernet DMA Status Register */ +#define ETH_DMASR_TSTS_Pos (29U) +#define ETH_DMASR_TSTS_Msk (0x1U << ETH_DMASR_TSTS_Pos) /*!< 0x20000000 */ +#define ETH_DMASR_TSTS ETH_DMASR_TSTS_Msk /* Time-stamp trigger status */ +#define ETH_DMASR_PMTS_Pos (28U) +#define ETH_DMASR_PMTS_Msk (0x1U << ETH_DMASR_PMTS_Pos) /*!< 0x10000000 */ +#define ETH_DMASR_PMTS ETH_DMASR_PMTS_Msk /* PMT status */ +#define ETH_DMASR_MMCS_Pos (27U) +#define ETH_DMASR_MMCS_Msk (0x1U << ETH_DMASR_MMCS_Pos) /*!< 0x08000000 */ +#define ETH_DMASR_MMCS ETH_DMASR_MMCS_Msk /* MMC status */ +#define ETH_DMASR_EBS_Pos (23U) +#define ETH_DMASR_EBS_Msk (0x7U << ETH_DMASR_EBS_Pos) /*!< 0x03800000 */ +#define ETH_DMASR_EBS ETH_DMASR_EBS_Msk /* Error bits status */ + /* combination with EBS[2:0] for GetFlagStatus function */ +#define ETH_DMASR_EBS_DescAccess_Pos (25U) +#define ETH_DMASR_EBS_DescAccess_Msk (0x1U << ETH_DMASR_EBS_DescAccess_Pos) /*!< 0x02000000 */ +#define ETH_DMASR_EBS_DescAccess ETH_DMASR_EBS_DescAccess_Msk /* Error bits 0-data buffer, 1-desc. access */ +#define ETH_DMASR_EBS_ReadTransf_Pos (24U) +#define ETH_DMASR_EBS_ReadTransf_Msk (0x1U << ETH_DMASR_EBS_ReadTransf_Pos) /*!< 0x01000000 */ +#define ETH_DMASR_EBS_ReadTransf ETH_DMASR_EBS_ReadTransf_Msk /* Error bits 0-write trnsf, 1-read transfr */ +#define ETH_DMASR_EBS_DataTransfTx_Pos (23U) +#define ETH_DMASR_EBS_DataTransfTx_Msk (0x1U << ETH_DMASR_EBS_DataTransfTx_Pos) /*!< 0x00800000 */ +#define ETH_DMASR_EBS_DataTransfTx ETH_DMASR_EBS_DataTransfTx_Msk /* Error bits 0-Rx DMA, 1-Tx DMA */ +#define ETH_DMASR_TPS_Pos (20U) +#define ETH_DMASR_TPS_Msk (0x7U << ETH_DMASR_TPS_Pos) /*!< 0x00700000 */ +#define ETH_DMASR_TPS ETH_DMASR_TPS_Msk /* Transmit process state */ +#define ETH_DMASR_TPS_Stopped 0x00000000U /* Stopped - Reset or Stop Tx Command issued */ +#define ETH_DMASR_TPS_Fetching_Pos (20U) +#define ETH_DMASR_TPS_Fetching_Msk (0x1U << ETH_DMASR_TPS_Fetching_Pos) /*!< 0x00100000 */ +#define ETH_DMASR_TPS_Fetching ETH_DMASR_TPS_Fetching_Msk /* Running - fetching the Tx descriptor */ +#define ETH_DMASR_TPS_Waiting_Pos (21U) +#define ETH_DMASR_TPS_Waiting_Msk (0x1U << ETH_DMASR_TPS_Waiting_Pos) /*!< 0x00200000 */ +#define ETH_DMASR_TPS_Waiting ETH_DMASR_TPS_Waiting_Msk /* Running - waiting for status */ +#define ETH_DMASR_TPS_Reading_Pos (20U) +#define ETH_DMASR_TPS_Reading_Msk (0x3U << ETH_DMASR_TPS_Reading_Pos) /*!< 0x00300000 */ +#define ETH_DMASR_TPS_Reading ETH_DMASR_TPS_Reading_Msk /* Running - reading the data from host memory */ +#define ETH_DMASR_TPS_Suspended_Pos (21U) +#define ETH_DMASR_TPS_Suspended_Msk (0x3U << ETH_DMASR_TPS_Suspended_Pos) /*!< 0x00600000 */ +#define ETH_DMASR_TPS_Suspended ETH_DMASR_TPS_Suspended_Msk /* Suspended - Tx Descriptor unavailabe */ +#define ETH_DMASR_TPS_Closing_Pos (20U) +#define ETH_DMASR_TPS_Closing_Msk (0x7U << ETH_DMASR_TPS_Closing_Pos) /*!< 0x00700000 */ +#define ETH_DMASR_TPS_Closing ETH_DMASR_TPS_Closing_Msk /* Running - closing Rx descriptor */ +#define ETH_DMASR_RPS_Pos (17U) +#define ETH_DMASR_RPS_Msk (0x7U << ETH_DMASR_RPS_Pos) /*!< 0x000E0000 */ +#define ETH_DMASR_RPS ETH_DMASR_RPS_Msk /* Receive process state */ +#define ETH_DMASR_RPS_Stopped 0x00000000U /* Stopped - Reset or Stop Rx Command issued */ +#define ETH_DMASR_RPS_Fetching_Pos (17U) +#define ETH_DMASR_RPS_Fetching_Msk (0x1U << ETH_DMASR_RPS_Fetching_Pos) /*!< 0x00020000 */ +#define ETH_DMASR_RPS_Fetching ETH_DMASR_RPS_Fetching_Msk /* Running - fetching the Rx descriptor */ +#define ETH_DMASR_RPS_Waiting_Pos (17U) +#define ETH_DMASR_RPS_Waiting_Msk (0x3U << ETH_DMASR_RPS_Waiting_Pos) /*!< 0x00060000 */ +#define ETH_DMASR_RPS_Waiting ETH_DMASR_RPS_Waiting_Msk /* Running - waiting for packet */ +#define ETH_DMASR_RPS_Suspended_Pos (19U) +#define ETH_DMASR_RPS_Suspended_Msk (0x1U << ETH_DMASR_RPS_Suspended_Pos) /*!< 0x00080000 */ +#define ETH_DMASR_RPS_Suspended ETH_DMASR_RPS_Suspended_Msk /* Suspended - Rx Descriptor unavailable */ +#define ETH_DMASR_RPS_Closing_Pos (17U) +#define ETH_DMASR_RPS_Closing_Msk (0x5U << ETH_DMASR_RPS_Closing_Pos) /*!< 0x000A0000 */ +#define ETH_DMASR_RPS_Closing ETH_DMASR_RPS_Closing_Msk /* Running - closing descriptor */ +#define ETH_DMASR_RPS_Queuing_Pos (17U) +#define ETH_DMASR_RPS_Queuing_Msk (0x7U << ETH_DMASR_RPS_Queuing_Pos) /*!< 0x000E0000 */ +#define ETH_DMASR_RPS_Queuing ETH_DMASR_RPS_Queuing_Msk /* Running - queuing the recieve frame into host memory */ +#define ETH_DMASR_NIS_Pos (16U) +#define ETH_DMASR_NIS_Msk (0x1U << ETH_DMASR_NIS_Pos) /*!< 0x00010000 */ +#define ETH_DMASR_NIS ETH_DMASR_NIS_Msk /* Normal interrupt summary */ +#define ETH_DMASR_AIS_Pos (15U) +#define ETH_DMASR_AIS_Msk (0x1U << ETH_DMASR_AIS_Pos) /*!< 0x00008000 */ +#define ETH_DMASR_AIS ETH_DMASR_AIS_Msk /* Abnormal interrupt summary */ +#define ETH_DMASR_ERS_Pos (14U) +#define ETH_DMASR_ERS_Msk (0x1U << ETH_DMASR_ERS_Pos) /*!< 0x00004000 */ +#define ETH_DMASR_ERS ETH_DMASR_ERS_Msk /* Early receive status */ +#define ETH_DMASR_FBES_Pos (13U) +#define ETH_DMASR_FBES_Msk (0x1U << ETH_DMASR_FBES_Pos) /*!< 0x00002000 */ +#define ETH_DMASR_FBES ETH_DMASR_FBES_Msk /* Fatal bus error status */ +#define ETH_DMASR_ETS_Pos (10U) +#define ETH_DMASR_ETS_Msk (0x1U << ETH_DMASR_ETS_Pos) /*!< 0x00000400 */ +#define ETH_DMASR_ETS ETH_DMASR_ETS_Msk /* Early transmit status */ +#define ETH_DMASR_RWTS_Pos (9U) +#define ETH_DMASR_RWTS_Msk (0x1U << ETH_DMASR_RWTS_Pos) /*!< 0x00000200 */ +#define ETH_DMASR_RWTS ETH_DMASR_RWTS_Msk /* Receive watchdog timeout status */ +#define ETH_DMASR_RPSS_Pos (8U) +#define ETH_DMASR_RPSS_Msk (0x1U << ETH_DMASR_RPSS_Pos) /*!< 0x00000100 */ +#define ETH_DMASR_RPSS ETH_DMASR_RPSS_Msk /* Receive process stopped status */ +#define ETH_DMASR_RBUS_Pos (7U) +#define ETH_DMASR_RBUS_Msk (0x1U << ETH_DMASR_RBUS_Pos) /*!< 0x00000080 */ +#define ETH_DMASR_RBUS ETH_DMASR_RBUS_Msk /* Receive buffer unavailable status */ +#define ETH_DMASR_RS_Pos (6U) +#define ETH_DMASR_RS_Msk (0x1U << ETH_DMASR_RS_Pos) /*!< 0x00000040 */ +#define ETH_DMASR_RS ETH_DMASR_RS_Msk /* Receive status */ +#define ETH_DMASR_TUS_Pos (5U) +#define ETH_DMASR_TUS_Msk (0x1U << ETH_DMASR_TUS_Pos) /*!< 0x00000020 */ +#define ETH_DMASR_TUS ETH_DMASR_TUS_Msk /* Transmit underflow status */ +#define ETH_DMASR_ROS_Pos (4U) +#define ETH_DMASR_ROS_Msk (0x1U << ETH_DMASR_ROS_Pos) /*!< 0x00000010 */ +#define ETH_DMASR_ROS ETH_DMASR_ROS_Msk /* Receive overflow status */ +#define ETH_DMASR_TJTS_Pos (3U) +#define ETH_DMASR_TJTS_Msk (0x1U << ETH_DMASR_TJTS_Pos) /*!< 0x00000008 */ +#define ETH_DMASR_TJTS ETH_DMASR_TJTS_Msk /* Transmit jabber timeout status */ +#define ETH_DMASR_TBUS_Pos (2U) +#define ETH_DMASR_TBUS_Msk (0x1U << ETH_DMASR_TBUS_Pos) /*!< 0x00000004 */ +#define ETH_DMASR_TBUS ETH_DMASR_TBUS_Msk /* Transmit buffer unavailable status */ +#define ETH_DMASR_TPSS_Pos (1U) +#define ETH_DMASR_TPSS_Msk (0x1U << ETH_DMASR_TPSS_Pos) /*!< 0x00000002 */ +#define ETH_DMASR_TPSS ETH_DMASR_TPSS_Msk /* Transmit process stopped status */ +#define ETH_DMASR_TS_Pos (0U) +#define ETH_DMASR_TS_Msk (0x1U << ETH_DMASR_TS_Pos) /*!< 0x00000001 */ +#define ETH_DMASR_TS ETH_DMASR_TS_Msk /* Transmit status */ + +/* Bit definition for Ethernet DMA Operation Mode Register */ +#define ETH_DMAOMR_DTCEFD_Pos (26U) +#define ETH_DMAOMR_DTCEFD_Msk (0x1U << ETH_DMAOMR_DTCEFD_Pos) /*!< 0x04000000 */ +#define ETH_DMAOMR_DTCEFD ETH_DMAOMR_DTCEFD_Msk /* Disable Dropping of TCP/IP checksum error frames */ +#define ETH_DMAOMR_RSF_Pos (25U) +#define ETH_DMAOMR_RSF_Msk (0x1U << ETH_DMAOMR_RSF_Pos) /*!< 0x02000000 */ +#define ETH_DMAOMR_RSF ETH_DMAOMR_RSF_Msk /* Receive store and forward */ +#define ETH_DMAOMR_DFRF_Pos (24U) +#define ETH_DMAOMR_DFRF_Msk (0x1U << ETH_DMAOMR_DFRF_Pos) /*!< 0x01000000 */ +#define ETH_DMAOMR_DFRF ETH_DMAOMR_DFRF_Msk /* Disable flushing of received frames */ +#define ETH_DMAOMR_TSF_Pos (21U) +#define ETH_DMAOMR_TSF_Msk (0x1U << ETH_DMAOMR_TSF_Pos) /*!< 0x00200000 */ +#define ETH_DMAOMR_TSF ETH_DMAOMR_TSF_Msk /* Transmit store and forward */ +#define ETH_DMAOMR_FTF_Pos (20U) +#define ETH_DMAOMR_FTF_Msk (0x1U << ETH_DMAOMR_FTF_Pos) /*!< 0x00100000 */ +#define ETH_DMAOMR_FTF ETH_DMAOMR_FTF_Msk /* Flush transmit FIFO */ +#define ETH_DMAOMR_TTC_Pos (14U) +#define ETH_DMAOMR_TTC_Msk (0x7U << ETH_DMAOMR_TTC_Pos) /*!< 0x0001C000 */ +#define ETH_DMAOMR_TTC ETH_DMAOMR_TTC_Msk /* Transmit threshold control */ +#define ETH_DMAOMR_TTC_64Bytes 0x00000000U /* threshold level of the MTL Transmit FIFO is 64 Bytes */ +#define ETH_DMAOMR_TTC_128Bytes 0x00004000U /* threshold level of the MTL Transmit FIFO is 128 Bytes */ +#define ETH_DMAOMR_TTC_192Bytes 0x00008000U /* threshold level of the MTL Transmit FIFO is 192 Bytes */ +#define ETH_DMAOMR_TTC_256Bytes 0x0000C000U /* threshold level of the MTL Transmit FIFO is 256 Bytes */ +#define ETH_DMAOMR_TTC_40Bytes 0x00010000U /* threshold level of the MTL Transmit FIFO is 40 Bytes */ +#define ETH_DMAOMR_TTC_32Bytes 0x00014000U /* threshold level of the MTL Transmit FIFO is 32 Bytes */ +#define ETH_DMAOMR_TTC_24Bytes 0x00018000U /* threshold level of the MTL Transmit FIFO is 24 Bytes */ +#define ETH_DMAOMR_TTC_16Bytes 0x0001C000U /* threshold level of the MTL Transmit FIFO is 16 Bytes */ +#define ETH_DMAOMR_ST_Pos (13U) +#define ETH_DMAOMR_ST_Msk (0x1U << ETH_DMAOMR_ST_Pos) /*!< 0x00002000 */ +#define ETH_DMAOMR_ST ETH_DMAOMR_ST_Msk /* Start/stop transmission command */ +#define ETH_DMAOMR_FEF_Pos (7U) +#define ETH_DMAOMR_FEF_Msk (0x1U << ETH_DMAOMR_FEF_Pos) /*!< 0x00000080 */ +#define ETH_DMAOMR_FEF ETH_DMAOMR_FEF_Msk /* Forward error frames */ +#define ETH_DMAOMR_FUGF_Pos (6U) +#define ETH_DMAOMR_FUGF_Msk (0x1U << ETH_DMAOMR_FUGF_Pos) /*!< 0x00000040 */ +#define ETH_DMAOMR_FUGF ETH_DMAOMR_FUGF_Msk /* Forward undersized good frames */ +#define ETH_DMAOMR_RTC_Pos (3U) +#define ETH_DMAOMR_RTC_Msk (0x3U << ETH_DMAOMR_RTC_Pos) /*!< 0x00000018 */ +#define ETH_DMAOMR_RTC ETH_DMAOMR_RTC_Msk /* receive threshold control */ +#define ETH_DMAOMR_RTC_64Bytes 0x00000000U /* threshold level of the MTL Receive FIFO is 64 Bytes */ +#define ETH_DMAOMR_RTC_32Bytes 0x00000008U /* threshold level of the MTL Receive FIFO is 32 Bytes */ +#define ETH_DMAOMR_RTC_96Bytes 0x00000010U /* threshold level of the MTL Receive FIFO is 96 Bytes */ +#define ETH_DMAOMR_RTC_128Bytes 0x00000018U /* threshold level of the MTL Receive FIFO is 128 Bytes */ +#define ETH_DMAOMR_OSF_Pos (2U) +#define ETH_DMAOMR_OSF_Msk (0x1U << ETH_DMAOMR_OSF_Pos) /*!< 0x00000004 */ +#define ETH_DMAOMR_OSF ETH_DMAOMR_OSF_Msk /* operate on second frame */ +#define ETH_DMAOMR_SR_Pos (1U) +#define ETH_DMAOMR_SR_Msk (0x1U << ETH_DMAOMR_SR_Pos) /*!< 0x00000002 */ +#define ETH_DMAOMR_SR ETH_DMAOMR_SR_Msk /* Start/stop receive */ + +/* Bit definition for Ethernet DMA Interrupt Enable Register */ +#define ETH_DMAIER_NISE_Pos (16U) +#define ETH_DMAIER_NISE_Msk (0x1U << ETH_DMAIER_NISE_Pos) /*!< 0x00010000 */ +#define ETH_DMAIER_NISE ETH_DMAIER_NISE_Msk /* Normal interrupt summary enable */ +#define ETH_DMAIER_AISE_Pos (15U) +#define ETH_DMAIER_AISE_Msk (0x1U << ETH_DMAIER_AISE_Pos) /*!< 0x00008000 */ +#define ETH_DMAIER_AISE ETH_DMAIER_AISE_Msk /* Abnormal interrupt summary enable */ +#define ETH_DMAIER_ERIE_Pos (14U) +#define ETH_DMAIER_ERIE_Msk (0x1U << ETH_DMAIER_ERIE_Pos) /*!< 0x00004000 */ +#define ETH_DMAIER_ERIE ETH_DMAIER_ERIE_Msk /* Early receive interrupt enable */ +#define ETH_DMAIER_FBEIE_Pos (13U) +#define ETH_DMAIER_FBEIE_Msk (0x1U << ETH_DMAIER_FBEIE_Pos) /*!< 0x00002000 */ +#define ETH_DMAIER_FBEIE ETH_DMAIER_FBEIE_Msk /* Fatal bus error interrupt enable */ +#define ETH_DMAIER_ETIE_Pos (10U) +#define ETH_DMAIER_ETIE_Msk (0x1U << ETH_DMAIER_ETIE_Pos) /*!< 0x00000400 */ +#define ETH_DMAIER_ETIE ETH_DMAIER_ETIE_Msk /* Early transmit interrupt enable */ +#define ETH_DMAIER_RWTIE_Pos (9U) +#define ETH_DMAIER_RWTIE_Msk (0x1U << ETH_DMAIER_RWTIE_Pos) /*!< 0x00000200 */ +#define ETH_DMAIER_RWTIE ETH_DMAIER_RWTIE_Msk /* Receive watchdog timeout interrupt enable */ +#define ETH_DMAIER_RPSIE_Pos (8U) +#define ETH_DMAIER_RPSIE_Msk (0x1U << ETH_DMAIER_RPSIE_Pos) /*!< 0x00000100 */ +#define ETH_DMAIER_RPSIE ETH_DMAIER_RPSIE_Msk /* Receive process stopped interrupt enable */ +#define ETH_DMAIER_RBUIE_Pos (7U) +#define ETH_DMAIER_RBUIE_Msk (0x1U << ETH_DMAIER_RBUIE_Pos) /*!< 0x00000080 */ +#define ETH_DMAIER_RBUIE ETH_DMAIER_RBUIE_Msk /* Receive buffer unavailable interrupt enable */ +#define ETH_DMAIER_RIE_Pos (6U) +#define ETH_DMAIER_RIE_Msk (0x1U << ETH_DMAIER_RIE_Pos) /*!< 0x00000040 */ +#define ETH_DMAIER_RIE ETH_DMAIER_RIE_Msk /* Receive interrupt enable */ +#define ETH_DMAIER_TUIE_Pos (5U) +#define ETH_DMAIER_TUIE_Msk (0x1U << ETH_DMAIER_TUIE_Pos) /*!< 0x00000020 */ +#define ETH_DMAIER_TUIE ETH_DMAIER_TUIE_Msk /* Transmit Underflow interrupt enable */ +#define ETH_DMAIER_ROIE_Pos (4U) +#define ETH_DMAIER_ROIE_Msk (0x1U << ETH_DMAIER_ROIE_Pos) /*!< 0x00000010 */ +#define ETH_DMAIER_ROIE ETH_DMAIER_ROIE_Msk /* Receive Overflow interrupt enable */ +#define ETH_DMAIER_TJTIE_Pos (3U) +#define ETH_DMAIER_TJTIE_Msk (0x1U << ETH_DMAIER_TJTIE_Pos) /*!< 0x00000008 */ +#define ETH_DMAIER_TJTIE ETH_DMAIER_TJTIE_Msk /* Transmit jabber timeout interrupt enable */ +#define ETH_DMAIER_TBUIE_Pos (2U) +#define ETH_DMAIER_TBUIE_Msk (0x1U << ETH_DMAIER_TBUIE_Pos) /*!< 0x00000004 */ +#define ETH_DMAIER_TBUIE ETH_DMAIER_TBUIE_Msk /* Transmit buffer unavailable interrupt enable */ +#define ETH_DMAIER_TPSIE_Pos (1U) +#define ETH_DMAIER_TPSIE_Msk (0x1U << ETH_DMAIER_TPSIE_Pos) /*!< 0x00000002 */ +#define ETH_DMAIER_TPSIE ETH_DMAIER_TPSIE_Msk /* Transmit process stopped interrupt enable */ +#define ETH_DMAIER_TIE_Pos (0U) +#define ETH_DMAIER_TIE_Msk (0x1U << ETH_DMAIER_TIE_Pos) /*!< 0x00000001 */ +#define ETH_DMAIER_TIE ETH_DMAIER_TIE_Msk /* Transmit interrupt enable */ + +/* Bit definition for Ethernet DMA Missed Frame and Buffer Overflow Counter Register */ +#define ETH_DMAMFBOCR_OFOC_Pos (28U) +#define ETH_DMAMFBOCR_OFOC_Msk (0x1U << ETH_DMAMFBOCR_OFOC_Pos) /*!< 0x10000000 */ +#define ETH_DMAMFBOCR_OFOC ETH_DMAMFBOCR_OFOC_Msk /* Overflow bit for FIFO overflow counter */ +#define ETH_DMAMFBOCR_MFA_Pos (17U) +#define ETH_DMAMFBOCR_MFA_Msk (0x7FFU << ETH_DMAMFBOCR_MFA_Pos) /*!< 0x0FFE0000 */ +#define ETH_DMAMFBOCR_MFA ETH_DMAMFBOCR_MFA_Msk /* Number of frames missed by the application */ +#define ETH_DMAMFBOCR_OMFC_Pos (16U) +#define ETH_DMAMFBOCR_OMFC_Msk (0x1U << ETH_DMAMFBOCR_OMFC_Pos) /*!< 0x00010000 */ +#define ETH_DMAMFBOCR_OMFC ETH_DMAMFBOCR_OMFC_Msk /* Overflow bit for missed frame counter */ +#define ETH_DMAMFBOCR_MFC_Pos (0U) +#define ETH_DMAMFBOCR_MFC_Msk (0xFFFFU << ETH_DMAMFBOCR_MFC_Pos) /*!< 0x0000FFFF */ +#define ETH_DMAMFBOCR_MFC ETH_DMAMFBOCR_MFC_Msk /* Number of frames missed by the controller */ + +/* Bit definition for Ethernet DMA Current Host Transmit Descriptor Register */ +#define ETH_DMACHTDR_HTDAP_Pos (0U) +#define ETH_DMACHTDR_HTDAP_Msk (0xFFFFFFFFU << ETH_DMACHTDR_HTDAP_Pos) /*!< 0xFFFFFFFF */ +#define ETH_DMACHTDR_HTDAP ETH_DMACHTDR_HTDAP_Msk /* Host transmit descriptor address pointer */ + +/* Bit definition for Ethernet DMA Current Host Receive Descriptor Register */ +#define ETH_DMACHRDR_HRDAP_Pos (0U) +#define ETH_DMACHRDR_HRDAP_Msk (0xFFFFFFFFU << ETH_DMACHRDR_HRDAP_Pos) /*!< 0xFFFFFFFF */ +#define ETH_DMACHRDR_HRDAP ETH_DMACHRDR_HRDAP_Msk /* Host receive descriptor address pointer */ + +/* Bit definition for Ethernet DMA Current Host Transmit Buffer Address Register */ +#define ETH_DMACHTBAR_HTBAP_Pos (0U) +#define ETH_DMACHTBAR_HTBAP_Msk (0xFFFFFFFFU << ETH_DMACHTBAR_HTBAP_Pos) /*!< 0xFFFFFFFF */ +#define ETH_DMACHTBAR_HTBAP ETH_DMACHTBAR_HTBAP_Msk /* Host transmit buffer address pointer */ + +/* Bit definition for Ethernet DMA Current Host Receive Buffer Address Register */ +#define ETH_DMACHRBAR_HRBAP_Pos (0U) +#define ETH_DMACHRBAR_HRBAP_Msk (0xFFFFFFFFU << ETH_DMACHRBAR_HRBAP_Pos) /*!< 0xFFFFFFFF */ +#define ETH_DMACHRBAR_HRBAP ETH_DMACHRBAR_HRBAP_Msk /* Host receive buffer address pointer */ + + +//----------------------------------------------------------------------------- +void ethernet_init(void); +void ethernet_deinit(void); +void ethernet_gpio_init(void); + + + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // _ETHERNET_H_ diff --git a/STM32F4/cores/maple/libmaple/exti.h b/STM32F4/cores/maple/libmaple/exti.h index 063f2d7f1..5d234f377 100644 --- a/STM32F4/cores/maple/libmaple/exti.h +++ b/STM32F4/cores/maple/libmaple/exti.h @@ -43,17 +43,25 @@ extern "C"{ /** EXTI register map type */ typedef struct exti_reg_map { - __io uint32 IMR; /**< Interrupt mask register */ - __io uint32 EMR; /**< Event mask register */ - __io uint32 RTSR; /**< Rising trigger selection register */ - __io uint32 FTSR; /**< Falling trigger selection register */ - __io uint32 SWIER; /**< Software interrupt event register */ - __io uint32 PR; /**< Pending register */ + __IO uint32 IMR; /**< Interrupt mask register */ + __IO uint32 EMR; /**< Event mask register */ + __IO uint32 RTSR; /**< Rising trigger selection register */ + __IO uint32 FTSR; /**< Falling trigger selection register */ + __IO uint32 SWIER; /**< Software interrupt event register */ + __IO uint32 PR; /**< Pending register */ } exti_reg_map; /** EXTI register map base pointer */ #define EXTI_BASE ((struct exti_reg_map*)0x40013C00) + +#define EXTI_RTC_ALARM BIT(17) +#define EXTI_RTC_WAKEUP BIT(22) +#define EXTI_RTC_TAMPSTAMP BIT(21) + + + + /** External interrupt trigger mode */ typedef enum exti_trigger_mode { EXTI_RISING, /**< Trigger on the rising edge */ diff --git a/STM32F4/cores/maple/libmaple/flash.c b/STM32F4/cores/maple/libmaple/flash.c deleted file mode 100644 index a22fbd3fc..000000000 --- a/STM32F4/cores/maple/libmaple/flash.c +++ /dev/null @@ -1,60 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file flash.c - * @brief Flash management functions - */ - -#include "libmaple.h" -#include "flash.h" -#include "bitband.h" - -/** - * @brief Turn on the hardware prefetcher. - */ -void flash_enable_prefetch(void) { - *bb_perip(&FLASH_BASE->ACR, FLASH_ACR_PRFTBE_BIT) = 1; -} - -/** - * @brief Set flash wait states - * - * See ST PM0042, section 3.1 for restrictions on the acceptable value - * of wait_states for a given SYSCLK configuration. - * - * @param wait_states number of wait states (one of - * FLASH_WAIT_STATE_0, FLASH_WAIT_STATE_1, - * FLASH_WAIT_STATE_2). - */ -void flash_set_latency(uint32 wait_states) { - uint32 val = FLASH_BASE->ACR; - - val &= ~FLASH_ACR_LATENCY; - val |= wait_states; - - FLASH_BASE->ACR = val; -} diff --git a/STM32F4/cores/maple/libmaple/flash.h b/STM32F4/cores/maple/libmaple/flash.h index 0b4e49b63..ef6d1e099 100644 --- a/STM32F4/cores/maple/libmaple/flash.h +++ b/STM32F4/cores/maple/libmaple/flash.h @@ -31,6 +31,7 @@ */ #include "libmaple_types.h" +#include "util.h" #ifndef _FLASH_H_ #define _FLASH_H_ @@ -41,18 +42,22 @@ extern "C"{ /** Flash register map type */ typedef struct flash_reg_map { - __io uint32 ACR; /**< Access control register */ - __io uint32 KEYR; /**< Key register */ - __io uint32 OPTKEYR; /**< OPTKEY register */ - __io uint32 SR; /**< Status register */ - __io uint32 CR; /**< Control register */ - __io uint32 AR; /**< Address register */ - __io uint32 OBR; /**< Option byte register */ - __io uint32 WRPR; /**< Write protection register */ + __IO uint32 ACR; /**< Access control register, Address offset: 0x00 */ + __IO uint32 KEYR; /**< Key register, offset: 0x04 */ + __IO uint32 OPTKEYR; /**< OPTKEY register, offset: 0x08 */ + __IO uint32 SR; /**< Status register, offset: 0x0c */ + __IO uint32 CR; /**< Control register, offset: 0x10 */ + __IO uint32 OPTCR; /**< Flash option control register, offset: 0x14 */ + __IO uint32 OPTCR1; /**< Flash option control register 1, F42xxx and F43xxx,, offset: 0x18 */ } flash_reg_map; /** Flash register map base pointer */ -#define FLASH_BASE ((struct flash_reg_map*)0x40022000) +#define FLASH ((struct flash_reg_map*)0x40023C00) + +// taken from CMSIS +#define UID_BASE 0x1FFF7A10U // Unique device ID register base address +#define FLASHSIZE_BASE 0x1FFF7A22U // FLASH Size register base address +#define PACKAGE_BASE 0x1FFF7BF0U // Package size register base address /* * Register bit definitions @@ -60,78 +65,194 @@ typedef struct flash_reg_map { /* Access control register */ -#define FLASH_ACR_PRFTBS_BIT 5 -#define FLASH_ACR_PRFTBE_BIT 4 -#define FLASH_ACR_HLFCYA_BIT 3 +#define FLASH_ACR_LATENCY_Pos (0U) +#define FLASH_ACR_LATENCY_Msk BIT_MASK_SHIFT(0xFUL, FLASH_ACR_LATENCY_Pos) +//NOTE: F405, F407, F415, F417 has only 3 bits in latency mask ! +#define FLASH_ACR_LATENCY_0WS 0x00000000U +#define FLASH_ACR_LATENCY_1WS 0x00000001U +#define FLASH_ACR_LATENCY_2WS 0x00000002U +#define FLASH_ACR_LATENCY_3WS 0x00000003U +#define FLASH_ACR_LATENCY_4WS 0x00000004U +#define FLASH_ACR_LATENCY_5WS 0x00000005U +#define FLASH_ACR_LATENCY_6WS 0x00000006U +#define FLASH_ACR_LATENCY_7WS 0x00000007U +//NOTE: only F42xxx, F43xxx +// F401, F411 has 4 bits there, but it is unusual u'd need so many waits ;) +#define FLASH_ACR_LATENCY_8WS 0x00000008U +#define FLASH_ACR_LATENCY_9WS 0x00000009U +#define FLASH_ACR_LATENCY_10WS 0x0000000AU +#define FLASH_ACR_LATENCY_11WS 0x0000000BU +#define FLASH_ACR_LATENCY_12WS 0x0000000CU +#define FLASH_ACR_LATENCY_13WS 0x0000000DU +#define FLASH_ACR_LATENCY_14WS 0x0000000EU +#define FLASH_ACR_LATENCY_15WS 0x0000000FU -#define FLASH_ACR_PRFTBS BIT(FLASH_ACR_PRFTBS_BIT) -#define FLASH_ACR_PRFTBE BIT(FLASH_ACR_PRFTBE_BIT) -#define FLASH_ACR_HLFCYA BIT(FLASH_ACR_HLFCYA_BIT) -#define FLASH_ACR_LATENCY 0x7 -/* Status register */ +#define FLASH_ACR_PRFTEN_Pos (8U) +#define FLASH_ACR_PRFTEN BIT(FLASH_ACR_PRFTEN_Pos) +#define FLASH_ACR_ICEN_Pos (9U) +#define FLASH_ACR_ICEN BIT(FLASH_ACR_ICEN_Pos) +#define FLASH_ACR_DCEN_Pos (10U) +#define FLASH_ACR_DCEN BIT(FLASH_ACR_DCEN_Pos) +#define FLASH_ACR_ICRST_Pos (11U) +#define FLASH_ACR_ICRST BIT(FLASH_ACR_ICRST_Pos) +#define FLASH_ACR_DCRST_Pos (12U) +#define FLASH_ACR_DCRST bit(FLASH_ACR_DCRST_Pos) + +/* Flash KEYR */ + +#define FLASH_KEYR_KEY1 0x45670123 +#define FLASH_KEYR_KEY2 0xCDEF89AB + +/* FLASH_OPTKEYR */ + +#define FLASH_OPTKEYR_KEY1 0x08192A3B +#define FLASH_OPTKEYR_KEY2 0x4C5D6E7F -#define FLASH_SR_EOP_BIT 5 -#define FLASH_SR_WRPRTERR_BIT 4 -#define FLASH_SR_PGERR_BIT 2 -#define FLASH_SR_BSY_BIT 0 +/* Status register */ -#define FLASH_SR_EOP BIT(FLASH_SR_EOP_BIT) -#define FLASH_SR_WRPRTERR BIT(FLASH_SR_WRPRTERR_BIT) -#define FLASH_SR_PGERR BIT(FLASH_SR_PGERR_BIT) -#define FLASH_SR_BSY BIT(FLASH_SR_BSY_BIT) +#define FLASH_SR_EOP_Pos (0U) +#define FLASH_SR_EOP BIT(FLASH_SR_EOP_Pos) +#define FLASH_SR_SOP_Pos (1U) +#define FLASH_SR_SOP BIT(FLASH_SR_SOP_Pos) +#define FLASH_SR_WRPERR_Pos (4U) +#define FLASH_SR_WRPERR BIT(FLASH_SR_WRPERR_Pos) +#define FLASH_SR_PGAERR_Pos (5U) +#define FLASH_SR_PGAERR BIT(FLASH_SR_PGAERR_Pos) +#define FLASH_SR_PGPERR_Pos (6U) +#define FLASH_SR_PGPERR BIT(FLASH_SR_PGPERR_Pos) +#define FLASH_SR_PGSERR_Pos (7U) +#define FLASH_SR_PGSERR BIT(FLASH_SR_PGSERR_Pos) +#define FLASH_SR_RDERR_Pos (8U) +#define FLASH_SR_RDERR BIT(FLASH_SR_RDERR_Pos) +#define FLASH_SR_BSY_Pos (16U) +#define FLASH_SR_BSY BIT(FLASH_SR_BSY_Msk) /* Control register */ -#define FLASH_CR_EOPIE_BIT 12 -#define FLASH_CR_ERRIE_BIT 10 -#define FLASH_CR_OPTWRE_BIT 9 -#define FLASH_CR_LOCK_BIT 7 -#define FLASH_CR_STRT_BIT 6 -#define FLASH_CR_OPTER_BIT 5 -#define FLASH_CR_OPTPG_BIT 4 -#define FLASH_CR_MER_BIT 2 -#define FLASH_CR_PER_BIT 1 -#define FLASH_CR_PG_BIT 0 - -#define FLASH_CR_EOPIE BIT(FLASH_CR_EOPIE_BIT) -#define FLASH_CR_ERRIE BIT(FLASH_CR_ERRIE_BIT) -#define FLASH_CR_OPTWRE BIT(FLASH_CR_OPTWRE_BIT) -#define FLASH_CR_LOCK BIT(FLASH_CR_LOCK_BIT) -#define FLASH_CR_STRT BIT(FLASH_CR_STRT_BIT) -#define FLASH_CR_OPTER BIT(FLASH_CR_OPTER_BIT) -#define FLASH_CR_OPTPG BIT(FLASH_CR_OPTPG_BIT) -#define FLASH_CR_MER BIT(FLASH_CR_MER_BIT) -#define FLASH_CR_PER BIT(FLASH_CR_PER_BIT) -#define FLASH_CR_PG BIT(FLASH_CR_PG_BIT) +#define FLASH_CR_PG_Pos (0U) +#define FLASH_CR_PG BIT(FLASH_CR_PG_Pos) +#define FLASH_CR_SER_Pos (1U) +#define FLASH_CR_SER BIT(FLASH_CR_SER_Pos) +#define FLASH_CR_MER_Pos (2U) +#define FLASH_CR_MER BIT(FLASH_CR_MER_Pos) +#define FLASH_CR_SNB_Pos (3U) +//SNB - sector number +//note: for F401, F405, F411, F417 this is 4 bits, F42xxx, F43xxx 5 bits +//for 4 bits one, 5th bit (i.e. absolute bit 7) must be 0 +#define FLASH_CR_SNB_Msk BIT_MASK_SHIFT(0x1FUL, FLASH_CR_SNB_Pos) +#define FLASH_CR_PSIZE_Pos (8U) +#define FLASH_CR_PSIZE_Msk BIT_MASK_SHIFT(0x3UL, FLASH_CR_PSIZE_Pos) +#define FLASH_CR_PSIZE8X BIT_MASK_SHIFT(0, FLASH_CR_PSIZE_Pos) +#define FLASH_CR_PSIZE16X BIT_MASK_SHIFT(1U, FLASH_CR_PSIZE_Pos) +#define FLASH_CR_PSIZE32X BIT_MASK_SHIFT(2U, FLASH_CR_PSIZE_Pos) +#define FLASH_CR_PSIZE64X BIT_MASK_SHIFT(3U, FLASH_CR_PSIZE_Pos) +#define FLASH_CR_STRT_Pos (16U) +#define FLASH_CR_STRT BIT(FLASH_CR_STRT_Pos) +#define FLASH_CR_EOPIE_Pos (24U) +#define FLASH_CR_EOPIE BIT(FLASH_CR_EOPIE_Pos) +#define FLASH_CR_LOCK_Pos (31U) +#define FLASH_CR_LOCK BIT(FLASH_CR_LOCK_Pos) /* Option byte register */ -#define FLASH_OBR_nRST_STDBY_BIT 4 -#define FLASH_OBR_nRST_STOP_BIT 3 -#define FLASH_OBR_WDG_SW_BIT 2 -#define FLASH_OBR_RDPRT_BIT 1 -#define FLASH_OBR_OPTERR_BIT 0 - -#define FLASH_OBR_DATA1 (0xFF << 18) -#define FLASH_OBR_DATA0 (0xFF << 10) -#define FLASH_OBR_USER 0x3FF -#define FLASH_OBR_nRST_STDBY BIT(FLASH_OBR_nRST_STDBY_BIT) -#define FLASH_OBR_nRST_STOP BIT(FLASH_OBR_nRST_STOP_BIT) -#define FLASH_OBR_WDG_SW BIT(FLASH_OBR_WDG_SW_BIT) -#define FLASH_OBR_RDPRT BIT(FLASH_OBR_RDPRT_BIT) -#define FLASH_OBR_OPTERR BIT(FLASH_OBR_OPTERR_BIT) +#define FLASH_OPTCR_OPTLOCK_Pos (0U) +#define FLASH_OPTCR_OPTLOCK BIT(FLASH_OPTCR_OPTLOCK_Pos) +#define FLASH_OPTCR_OPTSTRT_Pos (1U) +#define FLASH_OPTCR_OPTSTRT BIT(FLASH_OPTCR_OPTSTRT_Pos) +#define FLASH_OPTCR_BOR_LEV_Pos (2U) +#define FLASH_OPTCR_BOR_LEV_Msk BIT_MASK_SHIFT(0x3UL, FLASH_OPTCR_BOR_LEV_Pos) +#define FLASH_OPTCR_BOR_LEVOFF BIT_MASK_SHIFT(0x3UL, FLASH_OPTCR_BOR_LEV_Pos) +#define FLASH_OPTCR_BOR_LEV1 BIT_MASK_SHIFT(2U, FLASH_OPTCR_BOR_LEV_Pos) +#define FLASH_OPTCR_BOR_LEV2 BIT_MASK_SHIFT(1U, FLASH_OPTCR_BOR_LEV_Pos) +#define FLASH_OPTCR_BOR_LEV3 BIT_MASK_SHIFT(0U, FLASH_OPTCR_BOR_LEV_Pos) +//note: only for F42xxx, F43xxx, must be 0 otherwise +#define FLASH_OPTCR_BFB2_Pos (4U) +#define FLASH_OPTCR_BFB2 BIT(FLASH_OPTCR_BFB2_Pos) + +#define FLASH_OBR_USER_Msk BIT_MASK_SHIFT(0x7UL, 5U) +#define FLASH_OPTCR_WDG_SW_Pos (5U) +#define FLASH_OPTCR_WDG_SW BIT(FLASH_OPTCR_WDG_SW_Pos) +#define FLASH_OPTCR_nRST_STOP_Pos (6U) +#define FLASH_OPTCR_nRST_STOP BIT(FLASH_OPTCR_nRST_STOP_Pos) +#define FLASH_OPTCR_nRST_STDBY_Pos (7U) +#define FLASH_OPTCR_nRST_STDBY BIT(FLASH_OPTCR_nRST_STDBY_Pos) +#define FLASH_OPTCR_RDP_Pos (8U) +#define FLASH_OPTCR_RDP_Msk BIT_MASK_SHIFT(0xFFUL, FLASH_OPTCR_RDP_Pos) +#define FLASH_OPTCR_RDP_LVL0 BIT_MASK_SHIFT(0xAAU, FLASH_OPTCR_RDP_Pos) +#define FLASH_OPTCR_RDP_LVL2 BIT_MASK_SHIFT(0xCCU, FLASH_OPTCR_RDP_Pos) +#define FLASH_OPTCR_nWRP_Pos (16U) +#define FLASH_OPTCR_nWRP_Msk BIT_MASK_SHIFT(0xFFFUL, FLASH_OPTCR_nWRP_Pos) +#define FLASH_OPTCR_nWRP_0 0x00010000U +#define FLASH_OPTCR_nWRP_1 0x00020000U +#define FLASH_OPTCR_nWRP_2 0x00040000U +#define FLASH_OPTCR_nWRP_3 0x00080000U +#define FLASH_OPTCR_nWRP_4 0x00100000U +#define FLASH_OPTCR_nWRP_5 0x00200000U +#define FLASH_OPTCR_nWRP_6 0x00400000U +#define FLASH_OPTCR_nWRP_7 0x00800000U +#define FLASH_OPTCR_nWRP_8 0x01000000U +#define FLASH_OPTCR_nWRP_9 0x02000000U +#define FLASH_OPTCR_nWRP_10 0x04000000U +#define FLASH_OPTCR_nWRP_11 0x08000000U + +// only F42xxx, F43xxx +#define FLASH_OPTCR_DB1M_Pos (30U) +#define FLASH_OPTCR_DB1M BIT(FLASH_OPTCR_DB1M_Pos) +#define FLASH_OPTCR_SPRMOD_Pos (31U) +#define FLASH_OPTCR_SPRMOD BIT(FLASH_OPTCR_SPRMOD_Pos) + +/* FLASH_OPTCR1 register, only F42xxx, F43xxx*/ + +#define FLASH_OPTCR1_nWRP_Pos (16U) +#define FLASH_OPTCR1_nWRP_Msk BIT_MASK_SHIFT(0xFFFUL, FLASH_OPTCR1_nWRP_Pos) +#define FLASH_OPTCR1_nWRP_0 (0x001UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x00010000 */ +#define FLASH_OPTCR1_nWRP_1 (0x002UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x00020000 */ +#define FLASH_OPTCR1_nWRP_2 (0x004UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x00040000 */ +#define FLASH_OPTCR1_nWRP_3 (0x008UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x00080000 */ +#define FLASH_OPTCR1_nWRP_4 (0x010UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x00100000 */ +#define FLASH_OPTCR1_nWRP_5 (0x020UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x00200000 */ +#define FLASH_OPTCR1_nWRP_6 (0x040UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x00400000 */ +#define FLASH_OPTCR1_nWRP_7 (0x080UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x00800000 */ +#define FLASH_OPTCR1_nWRP_8 (0x100UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x01000000 */ +#define FLASH_OPTCR1_nWRP_9 (0x200UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x02000000 */ +#define FLASH_OPTCR1_nWRP_10 (0x400UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x04000000 */ +#define FLASH_OPTCR1_nWRP_11 (0x800UL << FLASH_OPTCR1_nWRP_Pos) /*!< 0x08000000 */ + /* * Setup routines */ -#define FLASH_WAIT_STATE_0 0x0 -#define FLASH_WAIT_STATE_1 0x1 -#define FLASH_WAIT_STATE_2 0x2 +// Turn on the hardware 'ART accelerator' i.e. prefetch + data & instruction cache +static inline void flash_init(uint32 acr_latency) { + FLASH->ACR = (FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN) | acr_latency; +} + +// Enable prefetch buffer, instruction cache and data cache +static inline void flash_enable_ART(void) { + FLASH->ACR |= FLASH_ACR_PRFTEN; +} + +// Disable prefetch buffer, instruction cache and data cache +static inline void flash_disable_ART(void) { + FLASH->ACR &= ~(FLASH_ACR_PRFTEN); +} + +/** + * @brief Set flash wait states + * + * See ST PM0042, section 3.1 for restrictions on the acceptable value + * of wait_states for a given SYSCLK configuration. + * + * @param wait_states number of wait states (one of + * FLASH_ACR_LATENCY_0WS .. FLASH_ACR_LATENCY_7WS + */ +static inline void flash_set_latency(uint32 wait_states) { + uint32 val = FLASH->ACR & ~(FLASH_ACR_LATENCY_Msk); + FLASH->ACR = val | wait_states; +} -void flash_enable_prefetch(void); -void flash_set_latency(uint32 wait_states); #ifdef __cplusplus } diff --git a/STM32F3/cores/maple/libmaple/stm32f3/f3_fpu.c b/STM32F4/cores/maple/libmaple/fpu.c similarity index 61% rename from STM32F3/cores/maple/libmaple/stm32f3/f3_fpu.c rename to STM32F4/cores/maple/libmaple/fpu.c index 7ea5277dc..7ca1fd996 100644 --- a/STM32F3/cores/maple/libmaple/stm32f3/f3_fpu.c +++ b/STM32F4/cores/maple/libmaple/fpu.c @@ -28,30 +28,36 @@ * @file libmaple/stm32f3/fpu.c * @author F3-port by Hanspeter Portner * @brief STM32F3 FPU. + * + * revision history: + * added comments making the asm codes more readable - andrew, Jun 2019 */ #include +// Enable the FPU (Cortex-M4 - STM32F4xx and higher) +// http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/BEHBJHIG.html + void fpu_enable(void) { /* * set coprocessor access control registers */ - asm("\tLDR.W R0, =0xE000ED88\n" - "\tLDR R1, [R0]\n" - "\tORR R1, R1, #(0xF << 20)\n" - "\tSTR R1, [R0]\n" - "\tDSB\n" - "\tISB"); + asm("\tLDR.W R0, =0xE000ED88\n" /* The FPU enable bits are in the CPACR. */ + "\tLDR R1, [R0]\n" /* read CAPCR */ + "\tORR R1, R1, #(0xF << 20)\n" /* Set bits 20-23 to enable CP10 and CP11 coprocessors */ + "\tSTR R1, [R0]\n" /* Write back the modified value to the CPACR */ + "\tDSB\n" /* wait for store to complete */ + "\tISB"); /* reset pipeline now the FPU is enabled */ } void fpu_disable(void) { /* * clear coprocessor access control registers */ - asm("\tLDR.W R0, =0xE000ED88\n" - "\tLDR R1, [R0]\n" - "\tORR R1, R1, #(0x0 << 20)\n" - "\tSTR R1, [R0]\n" - "\tDSB\n" - "\tISB"); + asm("\tLDR.W R0, =0xE000ED88\n" /* The FPU enable bits are in the CPACR. */ + "\tLDR R1, [R0]\n" /* read CAPCR */ + "\tORR R1, R1, #(0x0 << 20)\n" /* Set bits 20-23 to enable CP10 and CP11 coprocessors */ + "\tSTR R1, [R0]\n" /* Write back the modified value to the CPACR */ + "\tDSB\n" /* wait for store to complete */ + "\tISB"); /* reset pipeline now the FPU is enabled */ } diff --git a/STM32F3/cores/maple/libmaple/stm32f3/include/series/fpu.h b/STM32F4/cores/maple/libmaple/fpu.h similarity index 83% rename from STM32F3/cores/maple/libmaple/stm32f3/include/series/fpu.h rename to STM32F4/cores/maple/libmaple/fpu.h index dc5d4aba0..7f4a27cae 100644 --- a/STM32F3/cores/maple/libmaple/stm32f3/include/series/fpu.h +++ b/STM32F4/cores/maple/libmaple/fpu.h @@ -46,10 +46,10 @@ extern "C"{ /** FPU register map type */ typedef struct fpu_reg_map { - __io uint32 CPACR; /**< coprocessor access control register */ - __io uint32 FPCCR; /**< floating-point context control register */ - __io uint32 FPCAR; /**< floating-point context address register */ - __io uint32 FPDSCR; /**< floating-point default status control register */ + __IO uint32 CPACR; /**< coprocessor access control register */ + __IO uint32 FPCCR; /**< floating-point context control register */ + __IO uint32 FPCAR; /**< floating-point context address register */ + __IO uint32 FPDSCR; /**< floating-point default status control register */ } fpu_reg_map; #define FPU_BASE ((struct fpu_reg_map*)(SCB_BASE + 0x88)) @@ -58,6 +58,18 @@ typedef struct fpu_reg_map { * give registry bitfields here */ + +/** + * @brief Enable floating point unit. + */ +void fpu_enable(void); + +/** + * @brief Disable floating point unit. + */ +void fpu_disable(void); + + #ifdef __cplusplus } #endif diff --git a/STM32F4/cores/maple/libmaple/fsmc.c b/STM32F4/cores/maple/libmaple/fsmc.c index 1e3691adf..b3759bbe0 100644 --- a/STM32F4/cores/maple/libmaple/fsmc.c +++ b/STM32F4/cores/maple/libmaple/fsmc.c @@ -32,7 +32,7 @@ #include "fsmc.h" #include "gpio.h" -#if defined(STM32_HIGH_DENSITY) && defined(BOARD_generic_f407v) // pins not yet defined for disco F407 +#ifdef FSMC_D0 /** * Configure FSMC GPIOs for use with LCDs. @@ -56,7 +56,7 @@ void fsmc_lcd_init_gpios(void) { for (i=0; iBTR |= addset & 0xF; } -#endif /* STM32_HIGH_DENSITY */ #ifdef __cplusplus } /* extern "C" */ diff --git a/STM32F4/cores/maple/libmaple/gpioF4.c b/STM32F4/cores/maple/libmaple/gpio.c similarity index 54% rename from STM32F4/cores/maple/libmaple/gpioF4.c rename to STM32F4/cores/maple/libmaple/gpio.c index af839ebea..b81a7ace2 100644 --- a/STM32F4/cores/maple/libmaple/gpioF4.c +++ b/STM32F4/cores/maple/libmaple/gpio.c @@ -37,57 +37,63 @@ */ /** GPIO port A device. */ -const gpio_dev GPIOA = { +const gpio_dev gpioa = { .regs = GPIOA_BASE, .clk_id = RCC_GPIOA, .exti_port = AFIO_EXTI_PA, }; /** GPIO port B device. */ -const gpio_dev GPIOB = { +const gpio_dev gpiob = { .regs = GPIOB_BASE, .clk_id = RCC_GPIOB, .exti_port = AFIO_EXTI_PB, }; /** GPIO port C device. */ -const gpio_dev GPIOC = { +const gpio_dev gpioc = { .regs = GPIOC_BASE, .clk_id = RCC_GPIOC, .exti_port = AFIO_EXTI_PC, }; /** GPIO port D device. */ -const gpio_dev GPIOD = { +const gpio_dev gpiod = { .regs = GPIOD_BASE, .clk_id = RCC_GPIOD, .exti_port = AFIO_EXTI_PD, }; -#ifdef STM32_HIGH_DENSITY /** GPIO port E device. */ -const gpio_dev GPIOE = { +const gpio_dev gpioe = { .regs = GPIOE_BASE, .clk_id = RCC_GPIOE, .exti_port = AFIO_EXTI_PE, }; - #if 0 // not available on LQFP 100 package +#if defined(PACKAGE_LQFP144) // not available on LQFP100 package /** GPIO port F device. */ -const gpio_dev GPIOF = { +const gpio_dev gpiof = { .regs = GPIOF_BASE, .clk_id = RCC_GPIOF, .exti_port = AFIO_EXTI_PF, }; /** GPIO port G device. */ -const gpio_dev GPIOG = { +const gpio_dev gpiog = { .regs = GPIOG_BASE, .clk_id = RCC_GPIOG, .exti_port = AFIO_EXTI_PG, }; #endif + + +const gpio_dev * const gpio_devices[] = { + GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, +#ifdef PACKAGE_LQFP144 // not available on LQFP100 package + GPIOF, GPIOG #endif +}; /* * GPIO convenience routines @@ -109,30 +115,15 @@ void gpio_init(const gpio_dev *dev) { * Initialize and reset all available GPIO devices. */ void gpio_init_all(void) { - gpio_init(&GPIOA); - gpio_init(&GPIOB); - gpio_init(&GPIOC); - gpio_init(&GPIOD); - -#ifdef STM32_HIGH_DENSITY - gpio_init(&GPIOE); - #if 0 // not available on LQFP 100 package - gpio_init(GPIOF); - gpio_init(GPIOG); - #endif // not available on LQFP 100 package -#endif - -#ifdef ARDUINO_STM32F4_NETDUINO2PLUS - // PA8 Output the Master Clock MCO1 - gpio_set_af_mode(PA8, 0); - gpio_set_mode(PA8, GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ); - // PB4 as alternate MISO Input - gpio_set_af_mode(PB4, 5); - // PA5 as alternate SCK Output - gpio_set_af_mode(PA5, 5); - // PA7 as alternate MOSI Output - gpio_set_af_mode(PA7, 5); -#endif + gpio_init(GPIOA); + gpio_init(GPIOB); + gpio_init(GPIOC); + gpio_init(GPIOD); + gpio_init(GPIOE); +#if defined(PACKAGE_LQFP144) // not available on LQFP 100 package + gpio_init(GPIOF); + gpio_init(GPIOG); +#endif // not available on LQFP 100 package } /** @@ -144,16 +135,13 @@ void gpio_init_all(void) { * @see gpio_pin_mode */ void gpio_set_mode(uint8_t io_pin, gpio_pin_mode mode) { - gpio_reg_map *regs = (PIN_MAP[io_pin].gpio_device)->regs; - uint8_t pin = io_pin&0x0f; - - //regs->AFR[pin/8] = (regs->AFR[pin/8] & ~(15 << (4*(pin&7)))) | (((mode >> 8) & 15) << (4*(pin&7))); - //gpio_set_af_mode(dev, pin, mode>>8); + gpio_reg_map *regs = digitalPinToPort(io_pin)->regs; + uint8_t pin = io_pin&0x0f; - regs->MODER = (regs->MODER & ~( 3 << (pin<<1))) | (((mode >> 0) & 3) << (pin<<1)); - regs->PUPDR = (regs->PUPDR & ~( 3 << (pin<<1))) | (((mode >> 2) & 3) << (pin<<1)); - regs->OSPEEDR = (regs->OSPEEDR & ~( 3 << (pin<<1))) | (((mode >> 4) & 3) << (pin<<1)); - regs->OTYPER = (regs->OTYPER & ~( 1 << (pin<<0))) | (((mode >> 6) & 1) << (pin<<0)); + regs->MODER = (regs->MODER & ~( 3 << (pin<<1))) | (((mode >> 0) & 3) << (pin<<1)); + regs->PUPDR = (regs->PUPDR & ~( 3 << (pin<<1))) | (((mode >> 2) & 3) << (pin<<1)); + regs->OSPEEDR = (regs->OSPEEDR & ~( 3 << (pin<<1))) | (((mode >> 4) & 3) << (pin<<1)); + regs->OTYPER = (regs->OTYPER & ~( 1 << (pin<<0))) | (((mode >> 6) & 1) << (pin<<0)); } /** @@ -164,23 +152,51 @@ void gpio_set_mode(uint8_t io_pin, gpio_pin_mode mode) { * @param mode alternate function mode to set the pin to. * @see gpio_pin_mode */ -void gpio_set_af_mode(uint8_t io_pin, int mode) { - gpio_reg_map *regs = (PIN_MAP[io_pin].gpio_device)->regs; - uint8_t pin = io_pin&0x0F; +void gpio_set_af_mode(uint8_t io_pin, gpio_af_mode mode) { + gpio_reg_map *regs = digitalPinToPort(io_pin)->regs; + uint8_t pin = io_pin&0x0F; - regs->AFR[pin>>3] = (regs->AFR[pin>>3] & ~(15 << ((pin&7)<<2))) | (((mode >> 0) & 15) << ((pin&7)<<2)); + regs->AFR[pin>>3] = (regs->AFR[pin>>3] & ~(15 << ((pin&7)<<2))) | (((mode >> 0) & 15) << ((pin&7)<<2)); } -/* - * AFIO - */ - /** - * @brief Initialize the AFIO clock, and reset the AFIO registers. + * @brief Enable or disable the JTAG and SW debug ports. + * @param config Desired debug port configuration + * @see gpio_debug_cfg */ -void afio_init(void) { - //rcc_clk_enable(RCC_AFIO); - //rcc_reset_dev(RCC_AFIO); +void gpio_cfg_debug_ports(gpio_debug_cfg config) { + switch ( config ) { + case GPIO_DEBUG_FULL_SWJ: + gpio_set_af_mode(PA13, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(PA14, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(PA15, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(PB3, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(PB4, GPIO_AFMODE_SYSTEM); + break; + case GPIO_DEBUG_FULL_SWJ_NO_NJRST: + gpio_set_af_mode(PA13, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(PA14, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(PA15, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(PB3, GPIO_AFMODE_SYSTEM); + gpio_set_mode(PB4, GPIO_INPUT_FLOATING); + break; + case GPIO_DEBUG_SW_ONLY: + gpio_set_af_mode(PA13, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(PA14, GPIO_AFMODE_SYSTEM); + gpio_set_mode(PA15, GPIO_INPUT_FLOATING); + gpio_set_mode(PB3, GPIO_INPUT_FLOATING); + gpio_set_mode(PB4, GPIO_INPUT_FLOATING); + break; + case GPIO_DEBUG_NONE: + gpio_set_mode(PA13, GPIO_INPUT_FLOATING); + gpio_set_mode(PA14, GPIO_INPUT_FLOATING); + gpio_set_mode(PA15, GPIO_INPUT_FLOATING); + gpio_set_mode(PB3, GPIO_INPUT_FLOATING); + gpio_set_mode(PB4, GPIO_INPUT_FLOATING); + break; + default: + break; + } } #define AFIO_EXTI_SEL_MASK 0xF @@ -194,7 +210,7 @@ void afio_init(void) { * @see afio_exti_port */ void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) { - __io uint32 *exti_cr = &SYSCFG_BASE->EXTICR1 + exti / 4; + __IO uint32 *exti_cr = &SYSCFG->EXTICR1 + exti / 4; uint32 shift = 4 * (exti % 4); uint32 cr = *exti_cr; @@ -202,18 +218,3 @@ void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) { cr |= gpio_port << shift; *exti_cr = cr; } - -/** - * @brief Perform an alternate function remap. - * @param remapping Remapping to perform. - */ -#if 0 -void afio_remap(afio_remap_peripheral remapping) { - if (remapping & AFIO_REMAP_USE_MAPR2) { - remapping &= ~AFIO_REMAP_USE_MAPR2; - AFIO_BASE->MAPR2 |= remapping; - } else { - AFIO_BASE->MAPR |= remapping; - } -} -#endif diff --git a/STM32F4/cores/maple/libmaple/gpio.h b/STM32F4/cores/maple/libmaple/gpio.h index f1a141fee..5d676e5ff 100644 --- a/STM32F4/cores/maple/libmaple/gpio.h +++ b/STM32F4/cores/maple/libmaple/gpio.h @@ -34,6 +34,7 @@ #ifndef _GPIO_H_ #define _GPIO_H_ +#include #include "libmaple.h" #include "boards.h" @@ -41,6 +42,20 @@ extern "C"{ #endif + +extern const gpio_dev * const gpio_devices[]; +//static inline const gpio_dev * digitalPinToPort(uint8_t pin) { return gpio_devices[pin/16]; } +#define digitalPinToPort(P) ( gpio_devices[P/16] ) +#define digitalPinToBit(P) ( (P&0x0F) ) +#define digitalPinToBitMask(P) ( BIT(P&0x0F) ) +#define portOutputRegister(port) ( &(port->regs->ODR) ) +#define portInputRegister(port) ( &(port->regs->IDR) ) + +#define portSetRegister(pin) ( &(digitalPinToPort(pin)->regs->BSRR) ) +#define portClearRegister(pin) ( &(digitalPinToPort(pin)->regs->BSRR) ) + +#define portConfigRegister(pin) ( &(digitalPinToPort(pin)->regs->CRL) ) + /** * @brief Get a GPIO port's corresponding afio_exti_port. @@ -59,22 +74,51 @@ static inline afio_exti_port gpio_exti_port(const gpio_dev *dev) { * @param pin Pin on to set or reset * @param val If true, set the pin. If false, reset the pin. */ -static inline void gpio_write_pin(uint8_t pin, uint8 val) { - if (val) { - (PIN_MAP[pin].gpio_device)->regs->BSRRL = BIT(pin&0x0F); - } else { - (PIN_MAP[pin].gpio_device)->regs->BSRRH = BIT(pin&0x0F); - } +static inline void gpio_write_bit(gpio_dev *dev, uint8 bit, uint8 val) { + val = !val; /* "set" bits are lower than "reset" bits */ + dev->regs->BSRR = (1U << bit) << (16 * val); +} + +/** + * Determine whether or not a GPIO pin is set. + * + * Pin must have previously been configured to input mode. + * + * @param dev GPIO device whose pin to test. + * @param pin Pin on dev to test. + * @return True if the pin is set, false otherwise. + */ +static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 bit) { + return dev->regs->IDR & (1U << bit); } +/** + * Toggle a pin configured as output push-pull. + * @param dev GPIO device. + * @param pin Pin on dev to toggle. + */ +static inline void gpio_toggle_bit(gpio_dev *dev, uint8 bit) { + dev->regs->ODR = dev->regs->ODR ^ (1U << bit); +} +/** + * Set or reset a GPIO pin. + * + * Pin must have previously been configured to output mode. + * + * @param dev GPIO device whose pin to set. + * @param pin Pin on to set or reset + * @param val If true, set the pin. If false, reset the pin. + */ static inline void gpio_set_pin(uint8_t pin) { - (PIN_MAP[pin].gpio_device)->regs->BSRRL = BIT(pin&0x0F); + (digitalPinToPort(pin))->regs->BSRR = (uint32_t)BIT(pin&0x0F); } static inline void gpio_clear_pin(uint8_t pin) { - (PIN_MAP[pin].gpio_device)->regs->BSRRH = BIT(pin&0x0F); + (digitalPinToPort(pin))->regs->BSRR = (uint32_t)BIT(pin&0x0F)<<16; } +#define gpio_write_pin(pin,val) { if (val) gpio_set_pin(pin); else gpio_clear_pin(pin); } + /** * Determine whether or not a GPIO pin is set. * @@ -85,7 +129,7 @@ static inline void gpio_clear_pin(uint8_t pin) { * @return True if the pin is set, false otherwise. */ static inline uint32 gpio_read_pin(uint8_t pin) { - return (PIN_MAP[pin].gpio_device)->regs->IDR & BIT(pin&0x0F); + return (digitalPinToPort(pin))->regs->IDR & BIT(pin&0x0F); } /** @@ -94,7 +138,7 @@ static inline uint32 gpio_read_pin(uint8_t pin) { * @param pin Pin on dev to toggle. */ static inline void gpio_toggle_pin(uint8_t pin) { - (PIN_MAP[pin].gpio_device)->regs->ODR = (PIN_MAP[pin].gpio_device)->regs->ODR ^ BIT(pin&0x0F); + (digitalPinToPort(pin))->regs->ODR = (digitalPinToPort(pin))->regs->ODR ^ BIT(pin&0x0F); } /* @@ -104,25 +148,11 @@ static inline void gpio_toggle_pin(uint8_t pin) { extern void gpio_init(const gpio_dev *dev); extern void gpio_init_all(void); extern void gpio_set_mode(uint8_t pin, gpio_pin_mode mode); -extern void gpio_set_af_mode(uint8_t pin, int mode); +extern void gpio_set_af_mode(uint8_t pin, gpio_af_mode mode); +extern void gpio_cfg_debug_ports(gpio_debug_cfg config); -/* - * AFIO convenience routines - */ - -extern void afio_init(void); extern void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port); -extern void afio_remap(afio_remap_peripheral p); -/** - * @brief Enable or disable the JTAG and SW debug ports. - * @param config Desired debug port configuration - * @see afio_debug_cfg - */ -static inline void afio_cfg_debug_ports(afio_debug_cfg config) { - //__io uint32 *mapr = &AFIO_BASE->MAPR; - //*mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config; -} #ifdef __cplusplus } diff --git a/STM32F4/cores/maple/libmaple/gpio_def.h b/STM32F4/cores/maple/libmaple/gpio_def.h index 4a8e61e26..1f26e8160 100644 --- a/STM32F4/cores/maple/libmaple/gpio_def.h +++ b/STM32F4/cores/maple/libmaple/gpio_def.h @@ -47,20 +47,18 @@ extern "C"{ /** GPIO register map type */ typedef struct gpio_reg_map { - __io uint32 MODER; /*!< GPIO port mode register, Address offset: 0x00 */ - __io uint32 OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ - __io uint32 OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ - __io uint32 PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ - __io uint32 IDR; /*!< GPIO port input data register, Address offset: 0x10 */ - __io uint32 ODR; /*!< GPIO port output data register, Address offset: 0x14 */ - __io uint16 BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ - __io uint16 BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ - __io uint32 LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ - __io uint32 AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x24-0x28 */ + __IO uint32 MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32 OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32 OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32 PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32 IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32 ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint32 BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ + __IO uint32 LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32 AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x24-0x28 */ } gpio_reg_map; - /** * @brief External interrupt line port selector. * @@ -72,13 +70,11 @@ typedef enum afio_exti_port { AFIO_EXTI_PB, /**< Use port B (PBx) pin. */ AFIO_EXTI_PC, /**< Use port C (PCx) pin. */ AFIO_EXTI_PD, /**< Use port D (PDx) pin. */ -#ifdef STM32_HIGH_DENSITY AFIO_EXTI_PE, /**< Use port E (PEx) pin. */ - #if 0 // not available on LQFP 100 package +#if defined(PACKAGE_LQFP144) AFIO_EXTI_PF, /**< Use port F (PFx) pin. */ AFIO_EXTI_PG, /**< Use port G (PGx) pin. */ - #endif // not available on LQFP 100 package -#endif +#endif // PACKAGE_LQFP144 } afio_exti_port; @@ -89,32 +85,33 @@ typedef struct gpio_dev { afio_exti_port exti_port; /**< AFIO external interrupt port value */ } gpio_dev; -extern const gpio_dev GPIOA; -extern const gpio_dev GPIOB; -extern const gpio_dev GPIOC; -extern const gpio_dev GPIOD; -#ifdef STM32_HIGH_DENSITY -extern const gpio_dev GPIOE; - #if 0 // not available on LQFP 100 package -extern gpio_dev gpiof; -extern gpio_dev* const GPIOF; -extern gpio_dev gpiog; -extern gpio_dev* const GPIOG; - #endif // not available on LQFP 100 package -#endif +extern const gpio_dev gpioa; +extern const gpio_dev gpiob; +extern const gpio_dev gpioc; +extern const gpio_dev gpiod; +extern const gpio_dev gpioe; +#define GPIOA (&gpioa) +#define GPIOB (&gpiob) +#define GPIOC (&gpioc) +#define GPIOD (&gpiod) +#define GPIOE (&gpioe) +#if defined(PACKAGE_LQFP144) +extern const gpio_dev gpiof; +extern const gpio_dev gpiog; +#define GPIOF (&gpiof) +#define GPIOG (&gpiog) +#endif // PACKAGE_LQFP144 /** GPIO port register map base pointer */ #define GPIOA_BASE ((struct gpio_reg_map*)0x40020000) #define GPIOB_BASE ((struct gpio_reg_map*)0x40020400) #define GPIOC_BASE ((struct gpio_reg_map*)0x40020800) #define GPIOD_BASE ((struct gpio_reg_map*)0x40020C00) -#ifdef STM32_HIGH_DENSITY #define GPIOE_BASE ((struct gpio_reg_map*)0x40021000) - #if 0 // not available on LQFP 100 package +#if defined(PACKAGE_LQFP144) #define GPIOF_BASE ((struct gpio_reg_map*)0x40021400) #define GPIOG_BASE ((struct gpio_reg_map*)0x40021800) - #endif // not available on LQFP 100 package -#endif +#endif // PACKAGE_LQFP144 /* * GPIO register bit definitions @@ -170,27 +167,20 @@ AFRH 4 bit AF00-AF15 * use direct register access. */ typedef enum gpio_pin_mode { - GPIO_OUTPUT_PP = (GPIO_MODE_OUTPUT | GPIO_OTYPE_PP | - GPIO_OSPEED_50MHZ), /**< Output push-pull. */ - GPIO_OUTPUT_OD = (GPIO_MODE_OUTPUT | GPIO_OTYPE_OD | - GPIO_OSPEED_50MHZ), /**< Output open-drain. */ - GPIO_AF_OUTPUT_PP = (GPIO_MODE_AF | GPIO_OTYPE_PP | - GPIO_OSPEED_50MHZ), /**< Alternate function - output push-pull. */ - GPIO_AF_OUTPUT_PP_PU = (GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_PUPD_PU | - GPIO_OSPEED_50MHZ), /**< Alternate function - output push-pull. */ - GPIO_AF_OUTPUT_OD = (GPIO_MODE_AF | GPIO_OTYPE_OD | - GPIO_OSPEED_50MHZ), /**< Alternate function - output open drain. */ - GPIO_INPUT_ANALOG = (GPIO_MODE_ANALOG), /**< Analog input. */ - GPIO_INPUT_FLOATING = (GPIO_MODE_INPUT | - GPIO_PUPD_NONE), /**< Input floating. */ - GPIO_INPUT_PU = (GPIO_MODE_INPUT | GPIO_PUPD_PU), /**< Input pull-up. */ - GPIO_INPUT_PD = (GPIO_MODE_INPUT | GPIO_PUPD_PD), /**< Input pull-down. */ - GPIO_AF_INPUT_PU = (GPIO_MODE_AF | GPIO_PUPD_PU), /**< Alternate input pull-up. */ - GPIO_AF_INPUT_PD = (GPIO_MODE_AF | GPIO_PUPD_PD), /**< Alternate input pull-down. */ - GPIO_BIGNUMBER = 0xfff + GPIO_OUTPUT_PP = (GPIO_MODE_OUTPUT | GPIO_OTYPE_PP | GPIO_OSPEED_50MHZ), + GPIO_OUTPUT_OD = (GPIO_MODE_OUTPUT | GPIO_OTYPE_OD | GPIO_OSPEED_50MHZ), + GPIO_OUTPUT_OD_PU = (GPIO_MODE_OUTPUT | GPIO_OTYPE_OD | GPIO_PUPD_PU | GPIO_OSPEED_50MHZ), + GPIO_AF_OUTPUT_PP = (GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_50MHZ), + GPIO_AF_OUTPUT_PP_PU= (GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_PUPD_PU | GPIO_OSPEED_50MHZ), + GPIO_AF_OUTPUT_OD = (GPIO_MODE_AF | GPIO_OTYPE_OD | GPIO_OSPEED_50MHZ), + GPIO_INPUT_ANALOG = (GPIO_MODE_ANALOG), + GPIO_INPUT_FLOATING = (GPIO_MODE_INPUT | GPIO_PUPD_NONE), + GPIO_INPUT_PU = (GPIO_MODE_INPUT | GPIO_PUPD_PU), + GPIO_INPUT_PD = (GPIO_MODE_INPUT | GPIO_PUPD_PD), + GPIO_AF_INPUT = (GPIO_MODE_AF | GPIO_PUPD_NONE), + GPIO_AF_INPUT_PU = (GPIO_MODE_AF | GPIO_PUPD_PU), + GPIO_AF_INPUT_PD = (GPIO_MODE_AF | GPIO_PUPD_PD), + GPIO_BIGNUMBER = 0xfff } gpio_pin_mode; @@ -200,172 +190,15 @@ typedef enum gpio_pin_mode { /** AFIO register map */ typedef struct syscfg_reg_map { - __io uint32 MEMRM; /**< memory remap register */ - __io uint32 PMC; /**< peripheral mode configuration register */ - __io uint32 EXTICR1; /**< External interrupt configuration register 1. */ - __io uint32 EXTICR2; /**< External interrupt configuration register 2. */ - __io uint32 EXTICR3; /**< External interrupt configuration register 3. */ - __io uint32 EXTICR4; /**< External interrupt configuration register 4. */ - __io uint32 CMPCR; /**< Compensation cell control register */ + __IO uint32 MEMRMP; /**< memory remap register */ + __IO uint32 PMC; /**< peripheral mode configuration register */ + __IO uint32 EXTICR1; /**< External interrupt configuration register 1. */ + __IO uint32 EXTICR2; /**< External interrupt configuration register 2. */ + __IO uint32 EXTICR3; /**< External interrupt configuration register 3. */ + __IO uint32 EXTICR4; /**< External interrupt configuration register 4. */ + __IO uint32 CMPCR; /**< Compensation cell control register */ } syscfg_reg_map; -/** AFIO register map base pointer. */ -#define SYSCFG_BASE ((struct syscfg_reg_map *)0x40013800) - -/* - * AFIO register bit definitions - */ - -/* Event control register */ - -#define AFIO_EVCR_EVOE (0x1 << 7) -#define AFIO_EVCR_PORT_PA (0x0 << 4) -#define AFIO_EVCR_PORT_PB (0x1 << 4) -#define AFIO_EVCR_PORT_PC (0x2 << 4) -#define AFIO_EVCR_PORT_PD (0x3 << 4) -#define AFIO_EVCR_PORT_PE (0x4 << 4) -#define AFIO_EVCR_PIN_0 0x0 -#define AFIO_EVCR_PIN_1 0x1 -#define AFIO_EVCR_PIN_2 0x2 -#define AFIO_EVCR_PIN_3 0x3 -#define AFIO_EVCR_PIN_4 0x4 -#define AFIO_EVCR_PIN_5 0x5 -#define AFIO_EVCR_PIN_6 0x6 -#define AFIO_EVCR_PIN_7 0x7 -#define AFIO_EVCR_PIN_8 0x8 -#define AFIO_EVCR_PIN_9 0x9 -#define AFIO_EVCR_PIN_10 0xA -#define AFIO_EVCR_PIN_11 0xB -#define AFIO_EVCR_PIN_12 0xC -#define AFIO_EVCR_PIN_13 0xD -#define AFIO_EVCR_PIN_14 0xE -#define AFIO_EVCR_PIN_15 0xF - -/* AF remap and debug I/O configuration register */ - -#define AFIO_MAPR_SWJ_CFG (0x7 << 24) -#define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24) -#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24) -#define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW (0x2 << 24) -#define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW (0x4 << 24) -#define AFIO_MAPR_ADC2_ETRGREG_REMAP BIT(20) -#define AFIO_MAPR_ADC2_ETRGINJ_REMAP BIT(19) -#define AFIO_MAPR_ADC1_ETRGREG_REMAP BIT(18) -#define AFIO_MAPR_ADC1_ETRGINJ_REMAP BIT(17) -#define AFIO_MAPR_TIM5CH4_IREMAP BIT(16) -#define AFIO_MAPR_PD01_REMAP BIT(15) -#define AFIO_MAPR_CAN_REMAP (0x3 << 13) -#define AFIO_MAPR_CAN_REMAP_NONE (0x0 << 13) -#define AFIO_MAPR_CAN_REMAP_PB8_PB9 (0x2 << 13) -#define AFIO_MAPR_CAN_REMAP_PD0_PD1 (0x3 << 13) -#define AFIO_MAPR_TIM4_REMAP BIT(12) -#define AFIO_MAPR_TIM3_REMAP (0x3 << 10) -#define AFIO_MAPR_TIM3_REMAP_NONE (0x0 << 10) -#define AFIO_MAPR_TIM3_REMAP_PARTIAL (0x2 << 10) -#define AFIO_MAPR_TIM3_REMAP_FULL (0x3 << 10) -#define AFIO_MAPR_TIM2_REMAP (0x3 << 8) -#define AFIO_MAPR_TIM2_REMAP_NONE (0x0 << 8) -#define AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 (0x1 << 8) -#define AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11 (0x2 << 8) -#define AFIO_MAPR_TIM2_REMAP_FULL (0x3 << 8) -#define AFIO_MAPR_TIM1_REMAP (0x3 << 6) -#define AFIO_MAPR_TIM1_REMAP_NONE (0x0 << 6) -#define AFIO_MAPR_TIM1_REMAP_PARTIAL (0x1 << 6) -#define AFIO_MAPR_TIM1_REMAP_FULL (0x3 << 6) -#define AFIO_MAPR_USART3_REMAP (0x3 << 4) -#define AFIO_MAPR_USART3_REMAP_NONE (0x0 << 4) -#define AFIO_MAPR_USART3_REMAP_PARTIAL (0x1 << 4) -#define AFIO_MAPR_USART3_REMAP_FULL (0x3 << 4) -#define AFIO_MAPR_USART2_REMAP BIT(3) -#define AFIO_MAPR_USART1_REMAP BIT(2) -#define AFIO_MAPR_I2C1_REMAP BIT(1) -#define AFIO_MAPR_SPI1_REMAP BIT(0) - -/* External interrupt configuration register 1 */ - -#define AFIO_EXTICR1_EXTI3 (0xF << 12) -#define AFIO_EXTICR1_EXTI3_PA (0x0 << 12) -#define AFIO_EXTICR1_EXTI3_PB (0x1 << 12) -#define AFIO_EXTICR1_EXTI3_PC (0x2 << 12) -#define AFIO_EXTICR1_EXTI3_PD (0x3 << 12) -#define AFIO_EXTICR1_EXTI3_PE (0x4 << 12) -#define AFIO_EXTICR1_EXTI3_PF (0x5 << 12) -#define AFIO_EXTICR1_EXTI3_PG (0x6 << 12) -#define AFIO_EXTICR1_EXTI2 (0xF << 8) -#define AFIO_EXTICR1_EXTI2_PA (0x0 << 8) -#define AFIO_EXTICR1_EXTI2_PB (0x1 << 8) -#define AFIO_EXTICR1_EXTI2_PC (0x2 << 8) -#define AFIO_EXTICR1_EXTI2_PD (0x3 << 8) -#define AFIO_EXTICR1_EXTI2_PE (0x4 << 8) -#define AFIO_EXTICR1_EXTI2_PF (0x5 << 8) -#define AFIO_EXTICR1_EXTI2_PG (0x6 << 8) -#define AFIO_EXTICR1_EXTI1 (0xF << 4) -#define AFIO_EXTICR1_EXTI1_PA (0x0 << 4) -#define AFIO_EXTICR1_EXTI1_PB (0x1 << 4) -#define AFIO_EXTICR1_EXTI1_PC (0x2 << 4) -#define AFIO_EXTICR1_EXTI1_PD (0x3 << 4) -#define AFIO_EXTICR1_EXTI1_PE (0x4 << 4) -#define AFIO_EXTICR1_EXTI1_PF (0x5 << 4) -#define AFIO_EXTICR1_EXTI1_PG (0x6 << 4) -#define AFIO_EXTICR1_EXTI0 0xF -#define AFIO_EXTICR1_EXTI0_PA 0x0 -#define AFIO_EXTICR1_EXTI0_PB 0x1 -#define AFIO_EXTICR1_EXTI0_PC 0x2 -#define AFIO_EXTICR1_EXTI0_PD 0x3 -#define AFIO_EXTICR1_EXTI0_PE 0x4 -#define AFIO_EXTICR1_EXTI0_PF 0x5 -#define AFIO_EXTICR1_EXTI0_PG 0x6 - -/* External interrupt configuration register 2 */ - -#define AFIO_EXTICR2_EXTI7 (0xF << 12) -#define AFIO_EXTICR2_EXTI7_PA (0x0 << 12) -#define AFIO_EXTICR2_EXTI7_PB (0x1 << 12) -#define AFIO_EXTICR2_EXTI7_PC (0x2 << 12) -#define AFIO_EXTICR2_EXTI7_PD (0x3 << 12) -#define AFIO_EXTICR2_EXTI7_PE (0x4 << 12) -#define AFIO_EXTICR2_EXTI7_PF (0x5 << 12) -#define AFIO_EXTICR2_EXTI7_PG (0x6 << 12) -#define AFIO_EXTICR2_EXTI6 (0xF << 8) -#define AFIO_EXTICR2_EXTI6_PA (0x0 << 8) -#define AFIO_EXTICR2_EXTI6_PB (0x1 << 8) -#define AFIO_EXTICR2_EXTI6_PC (0x2 << 8) -#define AFIO_EXTICR2_EXTI6_PD (0x3 << 8) -#define AFIO_EXTICR2_EXTI6_PE (0x4 << 8) -#define AFIO_EXTICR2_EXTI6_PF (0x5 << 8) -#define AFIO_EXTICR2_EXTI6_PG (0x6 << 8) -#define AFIO_EXTICR2_EXTI5 (0xF << 4) -#define AFIO_EXTICR2_EXTI5_PA (0x0 << 4) -#define AFIO_EXTICR2_EXTI5_PB (0x1 << 4) -#define AFIO_EXTICR2_EXTI5_PC (0x2 << 4) -#define AFIO_EXTICR2_EXTI5_PD (0x3 << 4) -#define AFIO_EXTICR2_EXTI5_PE (0x4 << 4) -#define AFIO_EXTICR2_EXTI5_PF (0x5 << 4) -#define AFIO_EXTICR2_EXTI5_PG (0x6 << 4) -#define AFIO_EXTICR2_EXTI4 0xF -#define AFIO_EXTICR2_EXTI4_PA 0x0 -#define AFIO_EXTICR2_EXTI4_PB 0x1 -#define AFIO_EXTICR2_EXTI4_PC 0x2 -#define AFIO_EXTICR2_EXTI4_PD 0x3 -#define AFIO_EXTICR2_EXTI4_PE 0x4 -#define AFIO_EXTICR2_EXTI4_PF 0x5 -#define AFIO_EXTICR2_EXTI4_PG 0x6 - -/* AF remap and debug I/O configuration register 2 */ - -#define AFIO_MAPR2_FSMC_NADV BIT(10) -#define AFIO_MAPR2_TIM14_REMAP BIT(9) -#define AFIO_MAPR2_TIM13_REMAP BIT(8) -#define AFIO_MAPR2_TIM11_REMAP BIT(7) -#define AFIO_MAPR2_TIM10_REMAP BIT(6) -#define AFIO_MAPR2_TIM9_REMAP BIT(5) - -/* - * AFIO convenience routines - */ - -void afio_init(void); - /** * External interrupt line numbers. */ @@ -398,66 +231,28 @@ void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port); * @brief Available peripheral remaps. * @see afio_remap() */ -typedef enum afio_remap_peripheral { - AFIO_REMAP_ADC2_ETRGREG = AFIO_MAPR_ADC2_ETRGREG_REMAP, /**< - ADC 2 external trigger regular conversion remapping */ - AFIO_REMAP_ADC2_ETRGINJ = AFIO_MAPR_ADC2_ETRGINJ_REMAP, /**< - ADC 2 external trigger injected conversion remapping */ - AFIO_REMAP_ADC1_ETRGREG = AFIO_MAPR_ADC1_ETRGREG_REMAP, /**< - ADC 1 external trigger regular conversion remapping */ - AFIO_REMAP_ADC1_ETRGINJ = AFIO_MAPR_ADC1_ETRGINJ_REMAP, /**< - ADC 1 external trigger injected conversion remapping */ - AFIO_REMAP_TIM5CH4_I = AFIO_MAPR_TIM5CH4_IREMAP, /**< - Timer 5 channel 4 internal remapping */ - AFIO_REMAP_PD01 = AFIO_MAPR_PD01_REMAP, /**< - Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ - AFIO_REMAP_CAN_1 = AFIO_MAPR_CAN_REMAP_PB8_PB9, /**< - CAN alternate function remapping 1 (RX on PB8, TX on PB9) */ - AFIO_REMAP_CAN_2 = AFIO_MAPR_CAN_REMAP_PD0_PD1, /**< - CAN alternate function remapping 2 (RX on PD0, TX on PD1) */ - AFIO_REMAP_TIM4 = AFIO_MAPR_TIM4_REMAP, /**< - Timer 4 remapping */ - AFIO_REMAP_TIM3_PARTIAL = AFIO_MAPR_TIM3_REMAP_PARTIAL, /**< - Timer 3 partial remapping */ - AFIO_REMAP_TIM3_FULL = AFIO_MAPR_TIM3_REMAP_FULL, /**< - Timer 3 full remapping */ - AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3, /**< - Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3, CH3 - on PA2, CH4 on PA3) */ - AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11, /**< - Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1, CH3 - on PB10, CH4 on PB11) */ - AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL, /**< - Timer 2 full remapping */ - AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP, /**< - USART 2 remapping */ - AFIO_REMAP_USART1 = AFIO_MAPR_USART1_REMAP, /**< - USART 1 remapping */ - AFIO_REMAP_I2C1 = AFIO_MAPR_I2C1_REMAP, /**< - I2C 1 remapping */ - AFIO_REMAP_SPI1 = AFIO_MAPR_SPI1_REMAP, /**< - SPI 1 remapping */ - AFIO_REMAP_FSMC_NADV = (AFIO_MAPR2_FSMC_NADV | - AFIO_REMAP_USE_MAPR2), /**< - NADV signal not connected */ - AFIO_REMAP_TIM14 = (AFIO_MAPR2_TIM14_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 14 remapping */ - AFIO_REMAP_TIM13 = (AFIO_MAPR2_TIM13_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 13 remapping */ - AFIO_REMAP_TIM11 = (AFIO_MAPR2_TIM11_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 11 remapping */ - AFIO_REMAP_TIM10 = (AFIO_MAPR2_TIM10_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 10 remapping */ - AFIO_REMAP_TIM9 = (AFIO_MAPR2_TIM9_REMAP | - AFIO_REMAP_USE_MAPR2) /**< - Timer 9 */ -} afio_remap_peripheral; - -void afio_remap(afio_remap_peripheral p); +typedef enum { + GPIO_AFMODE_SYSTEM = 0, + GPIO_AFMODE_TIM1_2 = 1, + GPIO_AFMODE_TIM3_5 = 2, + GPIO_AFMODE_TIM8_11 = 3, + GPIO_AFMODE_I2C1_3 = 4, + GPIO_AFMODE_SPI1_4 = 5, + GPIO_AFMODE_SPI3_5 = 6, + GPIO_AFMODE_USART1_3 = 7, + GPIO_AFMODE_USART4_6 = 8, + GPIO_AFMODE_CAN1_2 = 9, + GPIO_AFMODE_TIM12_14 = 9, + GPIO_AFMODE_I2C2_3 = 9, + GPIO_AFMODE_OTG_FS = 10, + GPIO_AFMODE_ETH = 11, + GPIO_AFMODE_FSMC = 12, + GPIO_AFMODE_SDIO = 12, + GPIO_AFMODE_OTG_HS = 12, + GPIO_AFMODE_DCMI = 13, + GPIO_AFMODE_14 = 14, + GPIO_AFMODE_EVENTOUT = 15, +} gpio_af_mode; /** * @brief Debug port configuration @@ -467,18 +262,302 @@ void afio_remap(afio_remap_peripheral p); * * @see afio_cfg_debug_ports() */ -typedef enum afio_debug_cfg { - AFIO_DEBUG_FULL_SWJ = AFIO_MAPR_SWJ_CFG_FULL_SWJ, /**< - Full Serial Wire and JTAG debug */ - AFIO_DEBUG_FULL_SWJ_NO_NJRST = AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST, /**< - Full Serial Wire and JTAG, but no NJTRST. */ - AFIO_DEBUG_SW_ONLY = AFIO_MAPR_SWJ_CFG_NO_JTAG_SW, /**< - Serial Wire debug only (JTAG-DP disabled, - SW-DP enabled) */ - AFIO_DEBUG_NONE = AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW /**< - No debug; all JTAG and SW pins are free - for use as GPIOs. */ -} afio_debug_cfg; +typedef enum { + GPIO_DEBUG_FULL_SWJ = 0, // Full Serial Wire and JTAG debug + GPIO_DEBUG_FULL_SWJ_NO_NJRST = 1, // Full Serial Wire and JTAG, but no NJTRST. + GPIO_DEBUG_SW_ONLY = 2, // Serial Wire debug only (JTAG-DP disabled, SW-DP enabled) + GPIO_DEBUG_NONE = 3, // No debug; all JTAG and SW pins are free for use as GPIOs. +} gpio_debug_cfg; + +/******************************************************************************/ +/* */ +/* SYSCFG */ +/* */ +/******************************************************************************/ + +#define SYSCFG_BASE (0x40013800) + +#define SYSCFG ((syscfg_reg_map*)SYSCFG_BASE) + +/****************** Bit definition for SYSCFG_MEMRMP register ***************/ +#define SYSCFG_MEMRMP_MEM_MODE_Pos (0U) +#define SYSCFG_MEMRMP_MEM_MODE_Msk (0x3U << SYSCFG_MEMRMP_MEM_MODE_Pos) /*!< 0x00000003 */ +#define SYSCFG_MEMRMP_MEM_MODE SYSCFG_MEMRMP_MEM_MODE_Msk /*!< SYSCFG_Memory Remap Config */ +#define SYSCFG_MEMRMP_MEM_MODE_0 (0x1U << SYSCFG_MEMRMP_MEM_MODE_Pos) /*!< 0x00000001 */ +#define SYSCFG_MEMRMP_MEM_MODE_1 (0x2U << SYSCFG_MEMRMP_MEM_MODE_Pos) /*!< 0x00000002 */ +/****************** Bit definition for SYSCFG_PMC register ******************/ +#define SYSCFG_PMC_MII_RMII_SEL_Pos (23U) +#define SYSCFG_PMC_MII_RMII_SEL_Msk (0x1U << SYSCFG_PMC_MII_RMII_SEL_Pos) /*!< 0x00800000 */ +#define SYSCFG_PMC_MII_RMII_SEL SYSCFG_PMC_MII_RMII_SEL_Msk /*! * @brief Inter-Integrated Circuit (I2C) support. * * Currently, only master mode is supported. @@ -39,35 +40,71 @@ #include "string.h" #include "systick.h" -static i2c_dev i2c_dev1 = { +/** I2C1 device */ +i2c_dev i2c_dev1 = { .regs = I2C1_BASE, - //.gpio_port = &gpiob, - .sda_pin = PB7, +#ifdef BOARD_I2C1_SDA_PIN + .sda_pin = BOARD_I2C1_SDA_PIN, +#else + .sda_pin = PB7, +#endif +#ifdef BOARD_I2C1_SCL_PIN + .scl_pin = BOARD_I2C1_SCL_PIN, +#else .scl_pin = PB6, +#endif .clk_id = RCC_I2C1, .ev_nvic_line = NVIC_I2C1_EV, .er_nvic_line = NVIC_I2C1_ER, .state = I2C_STATE_DISABLED }; -/** I2C1 device */ -i2c_dev* const I2C1 = &i2c_dev1; -static i2c_dev i2c_dev2 = { +#if BOARD_NR_I2C>1 +/** I2C2 device */ +i2c_dev i2c_dev2 = { .regs = I2C2_BASE, - //.gpio_port = &gpiob, - .sda_pin = PB11, +#ifdef BOARD_I2C2_SDA_PIN + .sda_pin = BOARD_I2C2_SDA_PIN, +#else + .sda_pin = PB11, +#endif +#ifdef BOARD_I2C2_SCL_PIN + .scl_pin = BOARD_I2C2_SCL_PIN, +#else .scl_pin = PB10, +#endif .clk_id = RCC_I2C2, .ev_nvic_line = NVIC_I2C2_EV, .er_nvic_line = NVIC_I2C2_ER, .state = I2C_STATE_DISABLED }; +#endif + +#if BOARD_NR_I2C>2 /** I2C2 device */ -i2c_dev* const I2C2 = &i2c_dev2; +i2c_dev i2c_dev3 = { + .regs = I2C3_BASE, +#ifdef BOARD_I2C3_SDA_PIN + .sda_pin = BOARD_I2C3_SDA_PIN, +#else + .sda_pin = PC9, +#endif +#ifdef BOARD_I2C3_SCL_PIN + .scl_pin = BOARD_I2C3_SCL_PIN, +#else + .scl_pin = PA8, +#endif + .clk_id = RCC_I2C3, + .ev_nvic_line = NVIC_I2C3_EV, + .er_nvic_line = NVIC_I2C3_ER, + .state = I2C_STATE_DISABLED +}; +#endif static inline int32 wait_for_state_change(i2c_dev *dev, i2c_state state, uint32 timeout); +static void set_ccr_trise(i2c_dev *dev, uint32 flags); /** * @brief Fill data register with slave address @@ -124,6 +161,218 @@ enum { ERROR_ENTRY = 13, }; +/** + * @brief Reset an I2C bus. + * + * Reset is accomplished by clocking out pulses until any hung slaves + * release SDA and SCL, then generating a START condition, then a STOP + * condition. + * + * @param dev I2C device + */ +void i2c_bus_reset(const i2c_dev *dev) { + /* Release both lines */ + gpio_set_pin(dev->scl_pin); + gpio_set_pin(dev->sda_pin); + gpio_set_mode(dev->scl_pin, GPIO_OUTPUT_OD); + gpio_set_mode(dev->sda_pin, GPIO_OUTPUT_OD); + + /* + * Make sure the bus is free by clocking it until any slaves release the + * bus. + */ + while (!gpio_read_pin(dev->sda_pin)) { + /* Wait for any clock stretching to finish */ + while (!gpio_read_pin(dev->scl_pin)) + ; + delay_us(10); + + /* Pull low */ + gpio_clear_pin(dev->scl_pin); + delay_us(10); + + /* Release high again */ + gpio_set_pin(dev->scl_pin); + delay_us(10); + } + + /* Generate start then stop condition */ + gpio_clear_pin(dev->sda_pin); + delay_us(10); + gpio_clear_pin(dev->scl_pin); + delay_us(10); + gpio_set_pin(dev->scl_pin); + delay_us(10); + gpio_set_pin(dev->sda_pin); +} + +/** + * @brief Initialize an I2C device and reset its registers to their + * default values. + * @param dev Device to initialize. + */ +void i2c_init(i2c_dev *dev) { + rcc_clk_enable(dev->clk_id); + rcc_reset_dev(dev->clk_id); +} + +/** + * @brief Initialize an I2C device as bus master + * @param dev Device to enable + * @param flags Bitwise or of the following I2C options: + * I2C_FAST_MODE: 400 khz operation, + * I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for + * fast mode), + * I2C_BUS_RESET: Reset the bus and clock out any hung slaves on + * initialization, + * I2C_10BIT_ADDRESSING: Enable 10-bit addressing, + */ +void i2c_master_enable(i2c_dev *dev, uint32 flags) { + /* PE must be disabled to configure the device */ + i2c_disable(dev); + + /* Reset the bus. Clock out any hung slaves. */ + if (flags & I2C_BUS_RESET) { + i2c_bus_reset(dev); + } + + /* Set GPIO modes and turn on clock */ + gpio_set_mode(dev->sda_pin, GPIO_AF_OUTPUT_OD); + delay_us(2); + gpio_set_mode(dev->scl_pin, GPIO_AF_OUTPUT_OD); + delay_us(2); + gpio_set_af_mode(dev->scl_pin, GPIO_AFMODE_I2C1_3); + delay_us(2); + /* specific SDA pin remap for I2C2 on F4xx mcu*/ + if ((dev->sda_pin == PB3) || (dev->sda_pin == PB4)) { + gpio_set_af_mode(dev->sda_pin, GPIO_AFMODE_I2C2_3); + } + else { + gpio_set_af_mode(dev->sda_pin, GPIO_AFMODE_I2C1_3); + } + + + i2c_init(dev); + + /* Configure clock and rise time */ + set_ccr_trise(dev, flags); + + /* Enable event and buffer interrupts */ + nvic_irq_enable(dev->ev_nvic_line); + nvic_irq_enable(dev->er_nvic_line); + //i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_BUFFER | I2C_IRQ_ERROR); + + /* + * Important STM32 Errata: + * + * See STM32F10xx8 and STM32F10xxB Errata sheet (Doc ID 14574 Rev 8), + * Section 2.11.1, 2.11.2. + * + * 2.11.1: + * When the EV7, EV7_1, EV6_1, EV6_3, EV2, EV8, and EV3 events are not + * managed before the current byte is being transferred, problems may be + * encountered such as receiving an extra byte, reading the same data twice + * or missing data. + * + * 2.11.2: + * In Master Receiver mode, when closing the communication using + * method 2, the content of the last read data can be corrupted. + * + * If the user software is not able to read the data N-1 before the STOP + * condition is generated on the bus, the content of the shift register + * (data N) will be corrupted. (data N is shifted 1-bit to the left). + * + * ---------------------------------------------------------------------- + * + * In order to ensure that events are not missed, the i2c interrupt must + * not be preempted. We set the i2c interrupt priority to be the highest + * interrupt in the system (priority level 0). All other interrupts have + * been initialized to priority level 16. See nvic_init(). + */ + nvic_irq_set_priority(dev->ev_nvic_line, 0); + nvic_irq_set_priority(dev->er_nvic_line, 0); + + /* Make it go! */ + i2c_peripheral_enable(dev); + + dev->state = I2C_STATE_IDLE; +} + +/** + * @brief Process an i2c transaction. + * + * Transactions are composed of one or more i2c_msg's, and may be read + * or write tranfers. Multiple i2c_msg's will generate a repeated + * start in between messages. + * + * @param dev I2C device + * @param msgs Messages to send/receive + * @param num Number of messages to send/receive + * @param timeout Bus idle timeout in milliseconds before aborting the + * transfer. 0 denotes no timeout. + * @return 0 on success, + * I2C_ERROR_PROTOCOL if there was a protocol error, + * I2C_ERROR_TIMEOUT if the transfer timed out. + */ +int32 i2c_master_xfer(i2c_dev *dev, + i2c_msg *msgs, + uint16 num, + uint32 timeout) { + int32 rc; + + ASSERT(dev->state == I2C_STATE_IDLE); + + dev->msg = msgs; + dev->msgs_left = num; + dev->timestamp = systick_uptime(); + dev->state = I2C_STATE_BUSY; + + i2c_enable_irq(dev, (I2C_IRQ_BUFFER | I2C_IRQ_EVENT | I2C_IRQ_ERROR)); + i2c_start_condition(dev); + + rc = wait_for_state_change(dev, I2C_STATE_XFER_DONE, timeout); + if (rc < 0) { + goto out; + } + + dev->state = I2C_STATE_IDLE; +out: + return rc; +} + +/** + * @brief Wait for an I2C event, or time out in case of error. + * @param dev I2C device + * @param state I2C_state state to wait for + * @param timeout Timeout, in milliseconds + * @return 0 if target state is reached, a negative value on error. + */ +static inline int32 wait_for_state_change(i2c_dev *dev, + i2c_state state, + uint32 timeout) { + i2c_state tmp; + + while (1) { + tmp = dev->state; + + if (tmp == I2C_STATE_ERROR) { + return I2C_STATE_ERROR; + } + + if (tmp == state) { + return 0; + } + + if (timeout) { + if (systick_uptime() > (dev->timestamp + timeout)) { + /* TODO: overflow? */ + /* TODO: racy? */ + return I2C_ERROR_TIMEOUT; + } + } + } +} + /** * @brief IRQ handler for I2C master. Handles transmission/reception. * @param dev I2C device @@ -186,9 +435,20 @@ static void i2c_irq_handler(i2c_dev *dev) { * register. We should get another TXE interrupt * immediately to fill DR again. */ - if (msg->length != 1) { + if (msg->length > 1) { i2c_write(dev, msg->data[msg->xferred++]); - } + } else if (msg->length == 0) { /* We're just sending an address */ + i2c_stop_condition(dev); + /* + * Turn off event interrupts to keep BTF from firing until + * the end of the stop condition. Why on earth they didn't + * have a start/stop condition request clear BTF is beyond + * me. + */ + i2c_disable_irq(dev, I2C_IRQ_EVENT); + I2C_CRUMB(STOP_SENT, 0, 0); + dev->state = I2C_STATE_XFER_DONE; + } /* else we're just sending one byte */ } sr1 = sr2 = 0; } @@ -214,7 +474,7 @@ static void i2c_irq_handler(i2c_dev *dev) { /* * This should be impossible... */ - throb(); + ASSERT(0); } sr1 = sr2 = 0; } @@ -291,11 +551,16 @@ static void i2c_irq_handler(i2c_dev *dev) { void __irq_i2c1_ev(void) { i2c_irq_handler(&i2c_dev1); } - +#if BOARD_NR_I2C>1 void __irq_i2c2_ev(void) { i2c_irq_handler(&i2c_dev2); } - +#endif +#if BOARD_NR_I2C>2 +void __irq_i2c3_ev(void) { + i2c_irq_handler(&i2c_dev3); +} +#endif /** * @brief Interrupt handler for I2C error conditions * @param dev I2C device @@ -304,7 +569,7 @@ void __irq_i2c2_ev(void) { static void i2c_irq_error_handler(i2c_dev *dev) { I2C_CRUMB(ERROR_ENTRY, dev->regs->SR1, dev->regs->SR2); - dev->error_flags = dev->regs->SR2 & (I2C_SR1_BERR | + dev->error_flags = dev->regs->SR1 & (I2C_SR1_BERR | I2C_SR1_ARLO | I2C_SR1_AF | I2C_SR1_OVR); @@ -313,111 +578,33 @@ static void i2c_irq_error_handler(i2c_dev *dev) { dev->regs->SR2 = 0; i2c_stop_condition(dev); - i2c_disable_irq(dev, I2C_IRQ_BUFFER | I2C_IRQ_EVENT | I2C_IRQ_ERROR); + i2c_disable_irq(dev, (I2C_IRQ_BUFFER | I2C_IRQ_EVENT | I2C_IRQ_ERROR)); dev->state = I2C_STATE_ERROR; } void __irq_i2c1_er(void) { i2c_irq_error_handler(&i2c_dev1); } - +#if BOARD_NR_I2C>1 void __irq_i2c2_er(void) { i2c_irq_error_handler(&i2c_dev2); } - -/** - * @brief Reset an I2C bus. - * - * Reset is accomplished by clocking out pulses until any hung slaves - * release SDA and SCL, then generating a START condition, then a STOP - * condition. - * - * @param dev I2C device - */ -void i2c_bus_reset(const i2c_dev *dev) { - /* Release both lines */ - gpio_set_pin(dev->scl_pin); - gpio_set_pin(dev->sda_pin); - gpio_set_mode(dev->scl_pin, GPIO_OUTPUT_OD); - gpio_set_mode(dev->sda_pin, GPIO_OUTPUT_OD); - - /* - * Make sure the bus is free by clocking it until any slaves release the - * bus. - */ - while (!gpio_read_pin(dev->sda_pin)) { - /* Wait for any clock stretching to finish */ - while (!gpio_read_pin(dev->scl_pin)) - ; - delay_us(10); - - /* Pull low */ - gpio_clear_pin(dev->scl_pin); - delay_us(10); - - /* Release high again */ - gpio_set_pin(dev->scl_pin); - delay_us(10); - } - - /* Generate start then stop condition */ - gpio_clear_pin(dev->sda_pin); - delay_us(10); - gpio_clear_pin(dev->scl_pin); - delay_us(10); - gpio_set_pin(dev->scl_pin); - delay_us(10); - gpio_set_pin(dev->sda_pin); -} - -/** - * @brief Initialize an I2C device and reset its registers to their - * default values. - * @param dev Device to initialize. - */ -void i2c_init(i2c_dev *dev) { - rcc_reset_dev(dev->clk_id); - rcc_clk_enable(dev->clk_id); +#endif +#if BOARD_NR_I2C>2 +void __irq_i2c3_er(void) { + i2c_irq_error_handler(&i2c_dev3); } - -/** - * @brief Initialize an I2C device as bus master - * @param dev Device to enable - * @param flags Bitwise or of the following I2C options: - * I2C_FAST_MODE: 400 khz operation, - * I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for - * fast mode), - * I2C_BUS_RESET: Reset the bus and clock out any hung slaves on - * initialization, - * I2C_10BIT_ADDRESSING: Enable 10-bit addressing, - * I2C_REMAP: Remap I2C1 to SCL/PB8 SDA/PB9. +#endif +/* + * CCR/TRISE configuration helper */ -void i2c_master_enable(i2c_dev *dev, uint32 flags) { -#define I2C_CLK (STM32_PCLK1/1000000) - uint32 ccr = 0; - uint32 trise = 0; - - /* PE must be disabled to configure the device */ - ASSERT(!(dev->regs->CR1 & I2C_CR1_PE)); - - if ((dev == I2C1) && (flags & I2C_REMAP)) { - afio_remap(AFIO_REMAP_I2C1); - I2C1->sda_pin = 9; - I2C1->scl_pin = 8; - } - - /* Reset the bus. Clock out any hung slaves. */ - if (flags & I2C_BUS_RESET) { - i2c_bus_reset(dev); - } - - /* Turn on clock and set GPIO modes */ - i2c_init(dev); - gpio_set_mode(dev->sda_pin, GPIO_AF_OUTPUT_OD); - gpio_set_mode(dev->scl_pin, GPIO_AF_OUTPUT_OD); +static void set_ccr_trise(i2c_dev *dev, uint32 flags) { + uint32 ccr = 0; + uint32 trise = 0; + uint32 clk_hz = STM32_PCLK1; + uint32 clk_mhz = clk_hz / (1000 * 1000); - /* I2C1 and I2C2 are fed from APB1, clocked at 36MHz */ - i2c_set_input_clk(dev, I2C_CLK); + i2c_set_input_clk(dev, clk_mhz); if (flags & I2C_FAST_MODE) { ccr |= I2C_CCR_FS; @@ -425,17 +612,17 @@ void i2c_master_enable(i2c_dev *dev, uint32 flags) { if (flags & I2C_DUTY_16_9) { /* Tlow/Thigh = 16/9 */ ccr |= I2C_CCR_DUTY; - ccr |= STM32_PCLK1/(400000 * 25); + ccr |= clk_hz / (400000 * 25); } else { /* Tlow/Thigh = 2 */ - ccr |= STM32_PCLK1/(400000 * 3); + ccr |= clk_hz / (400000 * 3); } - trise = (300 * (I2C_CLK)/1000) + 1; + trise = (300 * clk_mhz / 1000) + 1; } else { /* Tlow/Thigh = 1 */ - ccr = STM32_PCLK1/(100000 * 2); - trise = I2C_CLK + 1; + ccr = clk_hz / (100000 * 2); + trise = clk_mhz + 1; } /* Set minimum required value if CCR < 1*/ @@ -445,121 +632,4 @@ void i2c_master_enable(i2c_dev *dev, uint32 flags) { i2c_set_clk_control(dev, ccr); i2c_set_trise(dev, trise); - - /* Enable event and buffer interrupts */ - nvic_irq_enable(dev->ev_nvic_line); - nvic_irq_enable(dev->er_nvic_line); - i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_BUFFER | I2C_IRQ_ERROR); - - /* - * Important STM32 Errata: - * - * See STM32F10xx8 and STM32F10xxB Errata sheet (Doc ID 14574 Rev 8), - * Section 2.11.1, 2.11.2. - * - * 2.11.1: - * When the EV7, EV7_1, EV6_1, EV6_3, EV2, EV8, and EV3 events are not - * managed before the current byte is being transferred, problems may be - * encountered such as receiving an extra byte, reading the same data twice - * or missing data. - * - * 2.11.2: - * In Master Receiver mode, when closing the communication using - * method 2, the content of the last read data can be corrupted. - * - * If the user software is not able to read the data N-1 before the STOP - * condition is generated on the bus, the content of the shift register - * (data N) will be corrupted. (data N is shifted 1-bit to the left). - * - * ---------------------------------------------------------------------- - * - * In order to ensure that events are not missed, the i2c interrupt must - * not be preempted. We set the i2c interrupt priority to be the highest - * interrupt in the system (priority level 0). All other interrupts have - * been initialized to priority level 16. See nvic_init(). - */ - nvic_irq_set_priority(dev->ev_nvic_line, 0); - nvic_irq_set_priority(dev->er_nvic_line, 0); - - /* Make it go! */ - i2c_peripheral_enable(dev); - - dev->state = I2C_STATE_IDLE; -} - - -/** - * @brief Process an i2c transaction. - * - * Transactions are composed of one or more i2c_msg's, and may be read - * or write tranfers. Multiple i2c_msg's will generate a repeated - * start in between messages. - * - * @param dev I2C device - * @param msgs Messages to send/receive - * @param num Number of messages to send/receive - * @param timeout Bus idle timeout in milliseconds before aborting the - * transfer. 0 denotes no timeout. - * @return 0 on success, - * I2C_ERROR_PROTOCOL if there was a protocol error, - * I2C_ERROR_TIMEOUT if the transfer timed out. - */ -int32 i2c_master_xfer(i2c_dev *dev, - i2c_msg *msgs, - uint16 num, - uint32 timeout) { - int32 rc; - - ASSERT(dev->state == I2C_STATE_IDLE); - - dev->msg = msgs; - dev->msgs_left = num; - dev->timestamp = systick_uptime(); - dev->state = I2C_STATE_BUSY; - - i2c_enable_irq(dev, I2C_IRQ_EVENT); - i2c_start_condition(dev); - - rc = wait_for_state_change(dev, I2C_STATE_XFER_DONE, timeout); - if (rc < 0) { - goto out; - } - - dev->state = I2C_STATE_IDLE; -out: - return rc; -} - - -/** - * @brief Wait for an I2C event, or time out in case of error. - * @param dev I2C device - * @param state I2C_state state to wait for - * @param timeout Timeout, in milliseconds - * @return 0 if target state is reached, a negative value on error. - */ -static inline int32 wait_for_state_change(i2c_dev *dev, - i2c_state state, - uint32 timeout) { - i2c_state tmp; - - while (1) { - tmp = dev->state; - - if (tmp == I2C_STATE_ERROR) { - return I2C_STATE_ERROR; - } - - if (tmp == state) { - return 0; - } - - if (timeout) { - if (systick_uptime() > (dev->timestamp + timeout)) { - /* TODO: overflow? */ - /* TODO: racy? */ - return I2C_ERROR_TIMEOUT; - } - } - } } diff --git a/STM32F4/cores/maple/libmaple/i2c.h b/STM32F4/cores/maple/libmaple/i2c.h index 28819a35b..cc36a161e 100644 --- a/STM32F4/cores/maple/libmaple/i2c.h +++ b/STM32F4/cores/maple/libmaple/i2c.h @@ -39,15 +39,15 @@ /** I2C register map type */ typedef struct i2c_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 OAR1; /**< Own address register 1 */ - __io uint32 OAR2; /**< Own address register 2 */ - __io uint32 DR; /**< Data register */ - __io uint32 SR1; /**< Status register 1 */ - __io uint32 SR2; /**< Status register 2 */ - __io uint32 CCR; /**< Clock control register */ - __io uint32 TRISE; /**< TRISE (rise time) register */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ + __IO uint32 OAR1; /**< Own address register 1 */ + __IO uint32 OAR2; /**< Own address register 2 */ + __IO uint32 DR; /**< Data register */ + __IO uint32 SR1; /**< Status register 1 */ + __IO uint32 SR2; /**< Status register 2 */ + __IO uint32 CCR; /**< Clock control register */ + __IO uint32 TRISE; /**< TRISE (rise time) register */ } i2c_reg_map; /** I2C device states */ @@ -78,7 +78,6 @@ typedef struct i2c_msg { */ typedef struct i2c_dev { i2c_reg_map *regs; /**< Register map */ - //gpio_dev *gpio_port; /**< SDA, SCL pins' GPIO port */ uint8 sda_pin; /**< SDA bit on gpio_port */ uint8 scl_pin; /**< SCL bit on gpio_port */ rcc_clk_id clk_id; /**< RCC clock information */ @@ -95,8 +94,16 @@ typedef struct i2c_dev { * Devices */ -extern i2c_dev* const I2C1; -extern i2c_dev* const I2C2; +extern i2c_dev i2c_dev1; +#define I2C1 (&i2c_dev1) +#if BOARD_NR_I2C>1 +extern i2c_dev i2c_dev2; +#define I2C2 (&i2c_dev2) +#endif +#if BOARD_NR_I2C>2 +extern i2c_dev i2c_dev3; +#define I2C3 (&i2c_dev3) +#endif /* * Register map base pointers @@ -106,6 +113,8 @@ extern i2c_dev* const I2C2; #define I2C1_BASE ((struct i2c_reg_map*)0x40005400) /** I2C2 register map base pointer */ #define I2C2_BASE ((struct i2c_reg_map*)0x40005800) +/** I2C3 register map base pointer */ +#define I2C3_BASE ((struct i2c_reg_map*)0x40005C00) /* * Register bit definitions @@ -118,8 +127,8 @@ extern i2c_dev* const I2C2; #define I2C_CR1_PEC BIT(12) // Packet error checking #define I2C_CR1_POS BIT(11) // Acknowledge/PEC position #define I2C_CR1_ACK BIT(10) // Acknowledge enable -#define I2C_CR1_START BIT(8) // Start generation #define I2C_CR1_STOP BIT(9) // Stop generation +#define I2C_CR1_START BIT(8) // Start generation #define I2C_CR1_PE BIT(0) // Peripheral Enable /* Control register 2 */ @@ -129,7 +138,7 @@ extern i2c_dev* const I2C2; #define I2C_CR2_ITBUFEN BIT(10) // Buffer interrupt enable #define I2C_CR2_ITEVTEN BIT(9) // Event interupt enable #define I2C_CR2_ITERREN BIT(8) // Error interupt enable -#define I2C_CR2_FREQ 0xFFF // Peripheral input frequency +#define I2C_CR2_FREQ 0x003F // Peripheral input frequency /* Clock control register */ @@ -188,19 +197,6 @@ int32 i2c_master_xfer(i2c_dev *dev, i2c_msg *msgs, uint16 num, uint32 timeout); void i2c_bus_reset(const i2c_dev *dev); -/** - * @brief Disable an I2C device - * - * This function disables the corresponding peripheral and marks dev's - * state as I2C_STATE_DISABLED. - * - * @param dev Device to disable. - */ -static inline void i2c_disable(i2c_dev *dev) { - dev->regs->CR1 &= ~I2C_CR1_PE; - dev->state = I2C_STATE_DISABLED; -} - /** * @brief Turn on an I2C peripheral * @param dev Device to enable @@ -217,6 +213,19 @@ static inline void i2c_peripheral_disable(i2c_dev *dev) { dev->regs->CR1 &= ~I2C_CR1_PE; } +/** + * @brief Disable an I2C device + * + * This function disables the corresponding peripheral and marks dev's + * state as I2C_STATE_DISABLED. + * + * @param dev Device to disable. + */ +static inline void i2c_disable(i2c_dev *dev) { + i2c_peripheral_disable(dev); + dev->state = I2C_STATE_DISABLED; +} + /** * @brief Fill transmit register * @param dev I2C device diff --git a/STM32F4/cores/maple/libmaple/iwdg.h b/STM32F4/cores/maple/libmaple/iwdg.h index 59e8e18f1..3673e6959 100644 --- a/STM32F4/cores/maple/libmaple/iwdg.h +++ b/STM32F4/cores/maple/libmaple/iwdg.h @@ -54,10 +54,10 @@ extern "C"{ /** Independent watchdog register map type. */ typedef struct iwdg_reg_map { - __io uint32 KR; /**< Key register. */ - __io uint32 PR; /**< Prescaler register. */ - __io uint32 RLR; /**< Reload register. */ - __io uint32 SR; /**< Status register */ + __IO uint32 KR; /**< Key register. */ + __IO uint32 PR; /**< Prescaler register. */ + __IO uint32 RLR; /**< Reload register. */ + __IO uint32 SR; /**< Status register */ } iwdg_reg_map; /** Independent watchdog base pointer */ diff --git a/STM32F4/cores/maple/libmaple/libc_repl.c b/STM32F4/cores/maple/libmaple/libc_repl.c new file mode 100644 index 000000000..8c49d5355 --- /dev/null +++ b/STM32F4/cores/maple/libmaple/libc_repl.c @@ -0,0 +1,7 @@ +#include + +int __wrap_atexit(void (*function)(void) __attribute__((unused))) { return 0; } + +int __wrap___cxa_atexit(void (*func) (void *) __attribute__((unused)), void * arg __attribute__((unused)), void * dso_handle __attribute__((unused))) { return 0; } + +__attribute__((noreturn)) void __wrap_exit(int status __attribute__((unused))) { while(1); } diff --git a/STM32F4/cores/maple/libmaple/libmaple.h b/STM32F4/cores/maple/libmaple/libmaple.h index 2ec0b2836..816274441 100644 --- a/STM32F4/cores/maple/libmaple/libmaple.h +++ b/STM32F4/cores/maple/libmaple/libmaple.h @@ -40,25 +40,10 @@ * FIXME this has no business being here */ /* -#if defined(MCU_STM32F103VE) || defined(MCU_STM32F205VE) || defined(MCU_STM32F406VG) - // e.g., Aeroquad32 - #define USER_ADDR_ROM 0x08010000 // ala42 - #define USER_ADDR_RAM 0x20000C00 - #define STACK_TOP 0x20000800 -#elif defined(BOARD_freeflight) */ #ifndef USER_ADDR_ROM #define USER_ADDR_ROM 0x08000000 #endif -#define USER_ADDR_RAM 0x20000C00 -#define STACK_TOP 0x20000800 -/* -#else -#define USER_ADDR_ROM 0x08005000 -#define USER_ADDR_RAM 0x20000C00 -#define STACK_TOP 0x20000800 -#endif -*/ #endif diff --git a/STM32F4/cores/maple/libmaple/libmaple_types.h b/STM32F4/cores/maple/libmaple/libmaple_types.h index 8e765b435..a4a4b1e80 100644 --- a/STM32F4/cores/maple/libmaple/libmaple_types.h +++ b/STM32F4/cores/maple/libmaple/libmaple_types.h @@ -47,17 +47,33 @@ typedef long long int64; typedef void (*voidFuncPtr)(void); -#define __io volatile #define __IO volatile + #ifndef __attr_flash #define __attr_flash __attribute__((section (".USER_FLASH"))) #endif -#ifndef __always_inline - #define __always_inline inline __attribute__((always_inline)) +#ifndef NO_CCMRAM +#ifndef __attr_ccmram + #define __attr_ccmram __attribute__((section (".ccmdata"))) +#endif +#endif +#ifdef __always_inline + #undef __always_inline #endif + #define __always_inline inline __attribute__((always_inline)) #ifndef NULL #define NULL 0 #endif +// Variable attributes, instructs the linker to place the marked +// variable in FLASH or CCRAM instead of RAM. +#define __FLASH__ __attr_flash +#ifndef NO_CCMRAM +#define __CCMRAM__ __attr_ccmram +#else +#define __CCMRAM__ +#endif + + #endif diff --git a/STM32F4/cores/maple/libmaple/nvic.c b/STM32F4/cores/maple/libmaple/nvic.c index 3be5a5ae2..911d9ea91 100644 --- a/STM32F4/cores/maple/libmaple/nvic.c +++ b/STM32F4/cores/maple/libmaple/nvic.c @@ -60,16 +60,15 @@ void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority) { * apply to the use of nonzero offsets; see ST RM0008 * and the ARM Cortex M3 Technical Reference Manual. */ -void nvic_init(uint32 vector_table_address, uint32 offset) { - uint32 i; - +void nvic_init(uint32 vector_table_address, uint32 offset) +{ nvic_set_vector_table(vector_table_address, offset); /* * Lower priority level for all peripheral interrupts to lowest * possible. */ - for (i = 0; i < STM32_NR_INTERRUPTS; i++) { + for (uint32 i = 0; i < NVIC_LAST_IRQ_NUM; i++) { nvic_irq_set_priority((nvic_irq_num)i, 0xF); } diff --git a/STM32F4/cores/maple/libmaple/nvic.h b/STM32F4/cores/maple/libmaple/nvic.h index e3b052d5d..946c55f04 100644 --- a/STM32F4/cores/maple/libmaple/nvic.h +++ b/STM32F4/cores/maple/libmaple/nvic.h @@ -55,19 +55,19 @@ extern "C"{ /** NVIC register map type. */ typedef struct nvic_reg_map { - __io uint32 ISER[8]; /**< Interrupt Set Enable Registers */ - uint32 RESERVED0[24]; /**< Reserved */ - __io uint32 ICER[8]; /**< Interrupt Clear Enable Registers */ - uint32 RSERVED1[24]; /**< Reserved */ - __io uint32 ISPR[8]; /**< Interrupt Set Pending Registers */ - uint32 RESERVED2[24]; /**< Reserved */ - __io uint32 ICPR[8]; /**< Interrupt Clear Pending Registers */ - uint32 RESERVED3[24]; /**< Reserved */ - __io uint32 IABR[8]; /**< Interrupt Active bit Registers */ - uint32 RESERVED4[56]; /**< Reserved */ - __io uint8 IP[240]; /**< Interrupt Priority Registers */ - uint32 RESERVED5[644]; /**< Reserved */ - __io uint32 STIR; /**< Software Trigger Interrupt Registers */ + __IO uint32 ISER[3]; /**< Interrupt Set Enable Registers */ + uint32 RESERVED0[29]; /**< Reserved */ + __IO uint32 ICER[3]; /**< Interrupt Clear Enable Registers */ + uint32 RSERVED1[29]; /**< Reserved */ + __IO uint32 ISPR[3]; /**< Interrupt Set Pending Registers */ + uint32 RESERVED2[29]; /**< Reserved */ + __IO uint32 ICPR[3]; /**< Interrupt Clear Pending Registers */ + uint32 RESERVED3[29]; /**< Reserved */ + __IO uint32 IABR[3]; /**< Interrupt Active bit Registers */ + uint32 RESERVED4[61]; /**< Reserved */ + __IO uint8 IP[84]; /**< Interrupt Priority Registers */ + uint32 RESERVED5[683]; /**< Reserved */ + __IO uint32 STIR; /**< Software Trigger Interrupt Registers */ } nvic_reg_map; /** NVIC register map base pointer. */ @@ -97,7 +97,7 @@ typedef enum nvic_irq_num { NVIC_SYSTICK = -1, /**< System tick timer */ NVIC_WWDG = 0, /**< Window watchdog interrupt */ NVIC_PVD = 1, /**< PVD through EXTI line detection */ - NVIC_TAMPER = 2, /**< Tamper */ + NVIC_TAMPSTAMP = 2, /**< Tamper and TimeStamp */ NVIC_RTC = 3, /**< Real-time clock */ NVIC_FLASH = 4, /**< Flash */ NVIC_RCC = 5, /**< Reset and clock control */ @@ -106,18 +106,18 @@ typedef enum nvic_irq_num { NVIC_EXTI2 = 8, /**< EXTI line 2 */ NVIC_EXTI3 = 9, /**< EXTI line 3 */ NVIC_EXTI4 = 10, /**< EXTI line 4 */ - NVIC_DMA_CH1 = 11, /**< DMA1 channel 1 */ - NVIC_DMA_CH2 = 12, /**< DMA1 channel 2 */ - NVIC_DMA_CH3 = 13, /**< DMA1 channel 3 */ - NVIC_DMA_CH4 = 14, /**< DMA1 channel 4 */ - NVIC_DMA_CH5 = 15, /**< DMA1 channel 5 */ - NVIC_DMA_CH6 = 16, /**< DMA1 channel 6 */ - NVIC_DMA_CH7 = 17, /**< DMA1 channel 7 */ - NVIC_ADC_1_2 = 18, /**< ADC1 and ADC2 */ - NVIC_USB_HP_CAN_TX = 19, /**< USB high priority or CAN TX */ - NVIC_USB_LP_CAN_RX0 = 20, /**< USB low priority or CAN RX0 */ - NVIC_CAN_RX1 = 21, /**< CAN RX1 */ - NVIC_CAN_SCE = 22, /**< CAN SCE */ + NVIC_DMA1_STREAM0 = 11, /**< DMA1 stream 0 */ + NVIC_DMA1_STREAM1 = 12, /**< DMA1 stream 1 */ + NVIC_DMA1_STREAM2 = 13, /**< DMA1 stream 2 */ + NVIC_DMA1_STREAM3 = 14, /**< DMA1 stream 3 */ + NVIC_DMA1_STREAM4 = 15, /**< DMA1 stream 4 */ + NVIC_DMA1_STREAM5 = 16, /**< DMA1 stream 5 */ + NVIC_DMA1_STREAM6 = 17, /**< DMA1 stream 6 */ + NVIC_ADC_1_2_3 = 18, /**< ADC 1-3 */ + NVIC_CAN1_TX = 19, /**< CAN1 TX */ + NVIC_CAN1_RX0 = 20, /**< CAN1 RX0 */ + NVIC_CAN1_RX1 = 21, /**< CAN1 RX1 */ + NVIC_CAN1_SCE = 22, /**< CAN1 SCE */ NVIC_EXTI_9_5 = 23, /**< EXTI line [9:5] */ NVIC_TIMER1_BRK = 24, /**< Timer 1 break */ NVIC_TIMER1_UP = 25, /**< Timer 1 update */ @@ -137,27 +137,54 @@ typedef enum nvic_irq_num { NVIC_USART3 = 39, /**< USART3 */ NVIC_EXTI_15_10 = 40, /**< EXTI line [15:10] */ NVIC_RTCALARM = 41, /**< RTC alarm through EXTI line */ - NVIC_USBWAKEUP = 42, /**< USB wakeup from suspend through - EXTI line */ + NVIC_USB_FS_WKUP = 42, /**< USB FS wakeup through EXTI line */ NVIC_TIMER8_BRK = 43, /**< Timer 8 break */ NVIC_TIMER8_UP = 44, /**< Timer 8 update */ NVIC_TIMER8_TRG_COM = 45, /**< Timer 8 trigger and commutation */ NVIC_TIMER8_CC = 46, /**< Timer 8 capture/compare */ -#ifdef STM32_HIGH_DENSITY - NVIC_ADC3 = 47, /**< ADC3 */ + NVIC_DMA1_STREAM7 = 47, /**< DMA1 stream 7 */ NVIC_FSMC = 48, /**< FSMC */ NVIC_SDIO = 49, /**< SDIO */ NVIC_TIMER5 = 50, /**< Timer 5 */ NVIC_SPI3 = 51, /**< SPI3 */ NVIC_UART4 = 52, /**< UART4 */ NVIC_UART5 = 53, /**< UART5 */ - NVIC_TIMER6 = 54, /**< Timer 6 */ + NVIC_TIMER6_DAC = 54, /**< Timer 6 & DAC */ NVIC_TIMER7 = 55, /**< Timer 7 */ - NVIC_DMA2_CH1 = 56, /**< DMA2 channel 1 */ - NVIC_DMA2_CH2 = 57, /**< DMA2 channel 2 */ - NVIC_DMA2_CH3 = 58, /**< DMA2 channel 3 */ - NVIC_DMA2_CH_4_5 = 59, /**< DMA2 channels 4 and 5 */ -#endif + NVIC_DMA2_STREAM0 = 56, /**< DMA2 stream 0 */ + NVIC_DMA2_STREAM1 = 57, /**< DMA2 stream 1 */ + NVIC_DMA2_STREAM2 = 58, /**< DMA2 stream 2 */ + NVIC_DMA2_STREAM3 = 59, /**< DMA2 stream 3 */ + NVIC_DMA2_STREAM4 = 60, /**< DMA2 stream 4 */ + NVIC_ETH = 61, /**< Ethernet */ + NVIC_ETH_WKUP = 62, /**< Ethernet Wakeup through EXTI line */ + NVIC_CAN2_TX = 63, /**< CAN2 TX */ + NVIC_CAN2_RX0 = 64, /**< CAN2 RX0 */ + NVIC_CAN2_RX1 = 65, /**< CAN2 RX1 */ + NVIC_CAN2_SCE = 66, /**< CAN2 SCE */ + NVIC_USB_FS = 67, /**< USB FS global interrupt */ + NVIC_DMA2_STREAM5 = 68, /**< DMA2 stream 5 */ + NVIC_DMA2_STREAM6 = 69, /**< DMA2 stream 6 */ + NVIC_DMA2_STREAM7 = 70, /**< DMA2 stream 7 */ + NVIC_USART6 = 71, /**< USART6 */ + NVIC_I2C3_EV = 72, /**< I2C3 event */ + NVIC_I2C3_ER = 73, /**< I2C3 error */ + NVIC_USB_HS_EP1_OUT = 74, + NVIC_USB_HS_EP1_IN = 75, + NVIC_USB_HS_WKUP = 76, + NVIC_USB_HS = 77, + NVIC_DCMI = 78, + NVIC_CRYPT = 79, + NVIC_HASH_RNG = 80, + NVIC_FPU = 81, + NVIC_UART7 = 82, + NVIC_UART8 = 83, + NVIC_SPI4 = 84, + NVIC_SPI5 = 85, + NVIC_UART9 = 88, + NVIC_UART10 = 89, + NVIC_QUAD_SPI = 92, + NVIC_LAST_IRQ_NUM, } nvic_irq_num; /* @@ -221,16 +248,9 @@ static inline void nvic_irq_disable(nvic_irq_num irq_num) { * nvic_irq_disable() in a loop. */ static inline void nvic_irq_disable_all(void) { - /* Note: This only works up to XL density. The fix for - * connectivity line is: - * - * NVIC_BASE->ICER[2] = 0xF; - * - * We don't support connectivity line devices (yet), so leave it - * alone for now. - */ NVIC_BASE->ICER[0] = 0xFFFFFFFF; NVIC_BASE->ICER[1] = 0xFFFFFFFF; + NVIC_BASE->ICER[2] = 0x0001FFFF; } #ifdef __cplusplus diff --git a/STM32F4/cores/maple/libmaple/pwr.h b/STM32F4/cores/maple/libmaple/pwr.h index 88b49c046..d62c7b166 100644 --- a/STM32F4/cores/maple/libmaple/pwr.h +++ b/STM32F4/cores/maple/libmaple/pwr.h @@ -37,12 +37,12 @@ extern "C" { /** Power interface register map. */ typedef struct pwr_reg_map { - __io uint32 CR; /**< Control register */ - __io uint32 CSR; /**< Control and status register */ + __IO uint32 CR; /**< Control register */ + __IO uint32 CSR; /**< Control and status register */ } pwr_reg_map; /** Power peripheral register map base pointer. */ -#define PWR_BASE ((struct pwr_reg_map*)0x40007000) +#define PWR ((struct pwr_reg_map*)0x40007000) /* * Register bit definitions @@ -51,28 +51,34 @@ typedef struct pwr_reg_map { /* Control register */ /** Disable backup domain write protection bit */ -#define PWR_CR_DBP 8 +#define PWR_CR_VOS_BIT 14 +/** Disable backup domain write protection bit */ +#define PWR_CR_DBP_BIT 8 /** Power voltage detector enable bit */ -#define PWR_CR_PVDE 4 +#define PWR_CR_PVDE_BIT 4 /** Clear standby flag bit */ -#define PWR_CR_CSBF 3 +#define PWR_CR_CSBF_BIT 3 /** Clear wakeup flag bit */ -#define PWR_CR_CWUF 2 +#define PWR_CR_CWUF_BIT 2 /** Power down deepsleep bit */ -#define PWR_CR_PDDS 1 +#define PWR_CR_PDDS_BIT 1 /** Low-power deepsleep bit */ -#define PWR_CR_LPDS 0 +#define PWR_CR_LPDS_BIT 0 /* Control and status register */ +/** Backup regulator enable bit */ +#define PWR_CSR_BRE BIT(9) /** Enable wakeup pin bit */ -#define PWR_CSR_EWUP 8 +#define PWR_CSR_EWUP_BIT 8 +/** Backup regulator ready bit */ +#define PWR_CSR_BRR BIT(3) /** PVD output bit */ -#define PWR_CSR_PVDO 2 +#define PWR_CSR_PVDO_BIT 2 /** Standby flag bit */ -#define PWR_CSR_SBF 1 +#define PWR_CSR_SBF_BIT 1 /** Wakeup flag bit */ -#define PWR_CSR_WUF 0 +#define PWR_CSR_WUF_BIT 0 /* * Convenience functions diff --git a/STM32F4/cores/maple/libmaple/rccF4.c b/STM32F4/cores/maple/libmaple/rccF4.c index c4ff30dc4..e1d62ee1f 100644 --- a/STM32F4/cores/maple/libmaple/rccF4.c +++ b/STM32F4/cores/maple/libmaple/rccF4.c @@ -24,8 +24,6 @@ * SOFTWARE. *****************************************************************************/ -#ifdef STM32F4 - /** * @file rcc.c * @brief Implements pretty much only the basic clock setup on the @@ -37,6 +35,7 @@ #include "gpio.h" #include "rcc.h" #include "bitband.h" +#include "pwr.h" #define APB1 RCC_APB1 #define APB2 RCC_APB2 @@ -44,6 +43,7 @@ #define AHB2 RCC_AHB2 #define AHB3 RCC_AHB3 + struct rcc_dev_info { const rcc_clk_domain clk_domain; const uint8 line_num; @@ -58,52 +58,72 @@ static const struct rcc_dev_info rcc_dev_table[] = { [RCC_GPIOB] = { .clk_domain = AHB1, .line_num = 1 }, //* [RCC_GPIOC] = { .clk_domain = AHB1, .line_num = 2 }, //* [RCC_GPIOD] = { .clk_domain = AHB1, .line_num = 3 }, //* + [RCC_GPIOE] = { .clk_domain = AHB1, .line_num = 4 }, //* + [RCC_GPIOF] = { .clk_domain = AHB1, .line_num = 5 }, //* + [RCC_GPIOG] = { .clk_domain = AHB1, .line_num = 6 }, //* + [RCC_GPIOH] = { .clk_domain = AHB1, .line_num = 7 }, //* + [RCC_GPIOI] = { .clk_domain = AHB1, .line_num = 8 }, //* + + [RCC_CRC] = { .clk_domain = AHB1, .line_num = 12}, //* +// [RCC_FLITF] = { .clk_domain = AHB1, .line_num = 15}, +// [RCC_SRAM1] = { .clk_domain = AHB1, .line_num = 16}, +// [RCC_SRAM2] = { .clk_domain = AHB1, .line_num = 17}, +// [RCC_BKPSRAM] = { .clk_domain = AHB1, .line_num = 18}, //* +#ifdef __CCMRAM__ + [RCC_CCMRAM] = { .clk_domain = AHB1, .line_num = 20 }, //? +#endif + [RCC_DMA1] = { .clk_domain = AHB1, .line_num = 21 }, //* + [RCC_DMA2] = { .clk_domain = AHB1, .line_num = 22 }, //* + [RCC_ETHMAC] = { .clk_domain = AHB1, .line_num = 25 }, + [RCC_ETHMACTX]= { .clk_domain = AHB1, .line_num = 26 }, + [RCC_ETHMACRX]= { .clk_domain = AHB1, .line_num = 27 }, + [RCC_ETHMACPTP]={ .clk_domain = AHB1, .line_num = 28 }, + + [RCC_DCMI] = { .clk_domain = AHB2, .line_num = 0 }, //* + [RCC_USBFS] = { .clk_domain = AHB2, .line_num = 7 }, //* + + [RCC_FSMC] = { .clk_domain = AHB3, .line_num = 0 }, //* -// [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 }, - [RCC_ADC1] = { .clk_domain = APB2, .line_num = 8 }, //* - [RCC_ADC2] = { .clk_domain = APB2, .line_num = 9 }, //* - [RCC_ADC3] = { .clk_domain = APB2, .line_num = 10 }, //* - [RCC_USART1] = { .clk_domain = APB2, .line_num = 4 }, //* - [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, //unchanged - [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, //unchanged [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 0 }, //* [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 }, //unchanged [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 }, //unchanged [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 }, //unchanged - [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 }, //unchanged - [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 }, //unchanged - [RCC_DMA1] = { .clk_domain = AHB1, .line_num = 21 }, //* - [RCC_PWR] = { .clk_domain = APB1, .line_num = 28}, //unchanged - [RCC_BKP] = { .clk_domain = AHB1, .line_num = 18}, //* - [RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 }, //unchanged - [RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 }, //unchanged - [RCC_CRC] = { .clk_domain = AHB1, .line_num = 12}, //* -// [RCC_FLITF] = { .clk_domain = AHB, .line_num = 4}, -// [RCC_SRAM] = { .clk_domain = AHB, .line_num = 2}, - - [RCC_GPIOE] = { .clk_domain = AHB1, .line_num = 4 }, //* - [RCC_GPIOF] = { .clk_domain = AHB1, .line_num = 5 }, //* - [RCC_GPIOG] = { .clk_domain = AHB1, .line_num = 6 }, //* - [RCC_UART4] = { .clk_domain = APB1, .line_num = 19 }, //unchanged - [RCC_UART5] = { .clk_domain = APB1, .line_num = 20 }, //unchanged [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, //unchanged [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, //unchanged [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, //unchanged [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 1 }, //* - [RCC_FSMC] = { .clk_domain = AHB3, .line_num = 0 }, //* - [RCC_DAC] = { .clk_domain = APB1, .line_num = 29 }, //unchanged - [RCC_DMA2] = { .clk_domain = AHB1, .line_num = 22 }, //* - [RCC_SDIO] = { .clk_domain = APB2, .line_num = 11 }, //* - [RCC_SPI3] = { .clk_domain = APB1, .line_num = 15 }, //unchanged [RCC_TIMER9] = { .clk_domain = APB2, .line_num = 16 }, //* [RCC_TIMER10] = { .clk_domain = APB2, .line_num = 17 }, //* [RCC_TIMER11] = { .clk_domain = APB2, .line_num = 18 }, //* [RCC_TIMER12] = { .clk_domain = APB1, .line_num = 6 }, //unchanged [RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 }, //unchanged [RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 }, //unchanged - [RCC_USBFS] = { .clk_domain = AHB2, .line_num = 7 }, //* - [RCC_SYSCFG] = { .clk_domain = APB2, .line_num = 14 }, //* - [RCC_SPI4] = { .clk_domain = APB1, .line_num = 15 }, + [RCC_WDG] = { .clk_domain = APB1, .line_num = 11}, //? + [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 }, //unchanged + [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 }, //unchanged + [RCC_SPI3] = { .clk_domain = APB1, .line_num = 15 }, //unchanged + [RCC_SPI4] = { .clk_domain = APB2, .line_num = 13 }, + [RCC_SPI5] = { .clk_domain = APB2, .line_num = 20 }, + + [RCC_USART1] = { .clk_domain = APB2, .line_num = 4 }, //* + [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, //unchanged + [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, //unchanged + [RCC_UART4] = { .clk_domain = APB1, .line_num = 19 }, //unchanged + [RCC_UART5] = { .clk_domain = APB1, .line_num = 20 }, //unchanged + [RCC_USART6] = { .clk_domain = APB2, .line_num = 5 }, //* + [RCC_ADC1] = { .clk_domain = APB2, .line_num = 8 }, //* + [RCC_ADC2] = { .clk_domain = APB2, .line_num = 9 }, //* + [RCC_ADC3] = { .clk_domain = APB2, .line_num = 10 }, //* + [RCC_SDIO] = { .clk_domain = APB2, .line_num = 11 }, //* + [RCC_SYSCFG] = { .clk_domain = APB2, .line_num = 14 }, //* + + [RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 }, //unchanged + [RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 }, //unchanged + [RCC_I2C3] = { .clk_domain = APB1, .line_num = 23 }, //? + [RCC_CAN1] = { .clk_domain = APB1, .line_num = 25 }, //? + [RCC_CAN2] = { .clk_domain = APB1, .line_num = 26 }, //? + [RCC_PWR] = { .clk_domain = APB1, .line_num = 28 }, //unchanged + [RCC_DAC] = { .clk_domain = APB1, .line_num = 29 }, //unchanged }; /** @@ -114,500 +134,127 @@ static const struct rcc_dev_info rcc_dev_table[] = { * @param pll_mul pll multiplier */ -#define HSE_STARTUP_TIMEOUT ((uint16)0x0500) /*!< Time out for HSE start up */ -#define RCC_CFGR_HPRE_DIV1 ((uint32)0x00000000) /*!< SYSCLK not divided */ -#define RCC_CFGR_PPRE1_DIV2 ((uint32)0x00001000) /*!< HCLK divided by 2 */ -#define RCC_CFGR_PPRE1_DIV4 ((uint32)0x00001400) /*!< HCLK divided by 4 */ -#define RCC_CFGR_PPRE2_DIV1 ((uint32)0x00000000) /*!< HCLK not divided */ -#define RCC_CFGR_PPRE2_DIV2 ((uint32)0x00008000) /*!< HCLK divided by 2 */ - -#define RCC_PLLCFGR_PLLSRC_HSE ((uint32)0x00400000) - -/******************* Bits definition for FLASH_ACR register *****************/ -//#define FLASH_ACR_LATENCY ((uint32_t)0x00000007) -#define FLASH_ACR_LATENCY_0WS ((uint32)0x00000000) -#define FLASH_ACR_LATENCY_1WS ((uint32)0x00000001) -#define FLASH_ACR_LATENCY_2WS ((uint32)0x00000002) -#define FLASH_ACR_LATENCY_3WS ((uint32)0x00000003) -#define FLASH_ACR_LATENCY_4WS ((uint32)0x00000004) -#define FLASH_ACR_LATENCY_5WS ((uint32)0x00000005) -#define FLASH_ACR_LATENCY_6WS ((uint32)0x00000006) -#define FLASH_ACR_LATENCY_7WS ((uint32)0x00000007) - -#define FLASH_ACR_PRFTEN ((uint32)0x00000100) -#define FLASH_ACR_ICEN ((uint32)0x00000200) -#define FLASH_ACR_DCEN ((uint32)0x00000400) -#define FLASH_ACR_ICRST ((uint32)0x00000800) -#define FLASH_ACR_DCRST ((uint32)0x00001000) -#define FLASH_ACR_BYTE0_ADDRESS ((uint32)0x40023C00) -#define FLASH_ACR_BYTE2_ADDRESS ((uint32)0x40023C03) - -typedef struct -{ - __io uint32 CR; /*!< PWR power control register, Address offset: 0x00 */ - __io uint32 CSR; /*!< PWR power control/status register, Address offset: 0x04 */ -} PWR_TypeDef; - -#define PWR_BASE (0x40007000) -#define PWR ((PWR_TypeDef *) PWR_BASE) -#define PWR_CR_VOS ((uint16)0x4000) /*!< Regulator voltage scaling output selection */ - -typedef struct -{ - __io uint32 ACR; /*!< FLASH access control register, Address offset: 0x00 */ - __io uint32 KEYR; /*!< FLASH key register, Address offset: 0x04 */ - __io uint32 OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ - __io uint32 SR; /*!< FLASH status register, Address offset: 0x0C */ - __io uint32 CR; /*!< FLASH control register, Address offset: 0x10 */ - __io uint32 OPTCR; /*!< FLASH option control register, Address offset: 0x14 */ -} FLASH_TypeDef; - -#define FLASH_R_BASE (0x40023C00) -#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) -#define RESET 0 - +//----------------------------------------------------------------------------- void InitMCO1() { - rcc_reg_map *RCC = RCC_BASE; // Turn MCO1 Master Clock Output mode RCC->CFGR &= RCC_CFGR_MCO1_RESET_MASK; RCC->CFGR |= RCC_CFGR_MCO1Source_HSE | RCC_CFGR_MCO1Div_1; // PA8 Output the Master Clock MCO1 - gpio_set_af_mode(PA8, 0); + gpio_set_af_mode(PA8, GPIO_AFMODE_SYSTEM); gpio_set_mode(PA8, GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ); } +#ifdef USE_CUSTOM_RCC_CLK +typedef struct { + int pll_n; // Internal system clock: PLL_N = (PLL_P * CLOCK_SPEED_MHZ), must be between 100..432 + int pll_p; // PLL_P = [2, 4, 6] + int pll_q; // PLL_Q = (PLL_N / 48) - if USB wanted, then this must be an integer between 1..10 + int apb2_div; + int flash_ws; +} clk_cfg_t; -void SetupClock72MHz() -{ - uint32_t SystemCoreClock = 72000000; - - /******************************************************************************/ - /* PLL (clocked by HSE) used as System clock source */ - /******************************************************************************/ - /************************* PLL Parameters *************************************/ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ - int PLL_M = 4; - int PLL_N = 216; - - /* SYSCLK = PLL_VCO / PLL_P */ - int PLL_P = 6; - - /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ - int PLL_Q = 9; - - - uint32 StartUpCounter = 0, HSEStatus = 0; - rcc_reg_map *RCC = RCC_BASE; - - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Select regulator voltage output Scale 2 mode, System frequency up to 144 MHz */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR &= (uint32_t)~(PWR_CR_VOS); - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 1*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; - - /* PCLK1 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; - - // save bus clock values - rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1); - rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/1); - rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/2); - - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; +clk_cfg_t clock_config = { 336, 2, 7, 2, 5}; // set here your custom values - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} - - -void SetupClock120MHz() +#endif + +const uint32_t SystemCoreClock = CLOCK_SPEED_HZ; +uint32 PLL_M, PLL_N, PLL_P, PLL_Q; +const uint32 multiples_of_48[] = {0,48,96,144,192,240,288,336,384,432}; +const uint32 flash_ws[] = {2,3,5}; +//----------------------------------------------------------------------------- +void rcc_clk_init(void) { - uint32_t SystemCoreClock = 120000000; - - /******************************************************************************/ - /* PLL (clocked by HSE) used as System clock source */ - /******************************************************************************/ - /************************* PLL Parameters *************************************/ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ - int PLL_M = 8; - int PLL_N = 240; - - /* SYSCLK = PLL_VCO / PLL_P */ - int PLL_P = 2; - - /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ - int PLL_Q = 5; - - - uint32 StartUpCounter = 0, HSEStatus = 0; - rcc_reg_map *RCC = RCC_BASE; - - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } +#ifdef CRYSTAL_FREQ + PLL_M = CRYSTAL_FREQ; +#else + #error Please define CRYSTAL_FREQ! +#endif - if (HSEStatus == (uint32_t)0x01) +#ifdef USE_CUSTOM_RCC_CLK + PLL_N = clock_config.pll_n; + PLL_P = clock_config.pll_p; + PLL_Q = clock_config.pll_q; +#else + uint32 found = 0; + for (PLL_Q=3; PLL_Q<9; PLL_Q++) { - /* Select regulator voltage output Scale 2 mode, System frequency up to 144 MHz */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR &= (uint32_t)~(PWR_CR_VOS); - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; - - /* PCLK1 = HCLK / 4*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; - - // save bus clock values - rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1); - rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/2); - rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/4); - - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) + PLL_N = multiples_of_48[PLL_Q]; + for (PLL_P = 2; PLL_P<7; PLL_P+=2) { + if ( (CLOCK_SPEED_MHZ*PLL_P)==PLL_N ) { + found = 1; + break; + } } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS; - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ + if ( found ) break; } -} - - -void SetupClock168MHz() -{ - uint32_t SystemCoreClock = 168000000; - - /******************************************************************************/ - /* PLL (clocked by HSE) used as System clock source */ - /******************************************************************************/ - /************************* PLL Parameters *************************************/ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ -#ifdef ARDUINO_STM32F4_NETDUINO2PLUS - int PLL_M = 25; // The NETDUINO has a 25MHz external oscillator -#else - int PLL_M = 8; #endif - int PLL_N = 336; - /* SYSCLK = PLL_VCO / PLL_P */ - int PLL_P = 2; - - /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ - int PLL_Q = 7; - - - uint32 StartUpCounter = 0, HSEStatus = 0; - rcc_reg_map *RCC = RCC_BASE; - -#ifdef ARDUINO_STM32F4_NETDUINO2PLUS - InitMCO1(); -#endif - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); + RCC->CR |= (uint32_t)(RCC_CR_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } + while (!(RCC->CR & RCC_CR_HSERDY)); - if (HSEStatus == (uint32_t)0x01) - { - /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR |= PWR_CR_VOS; - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; + /* Select regulator voltage output Scale 2 mode, System frequency up to 144 MHz */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + //*bb_perip(&PWR->CR, PWR_CR_VOS_BIT) = 0; - /* PCLK1 = HCLK / 4*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; + /* HCLK = SYSCLK / 1*/ + rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); - // save bus clock values - rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1); - rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/2); - rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/4); + /* PCLK2 = HCLK / 1*/ + rcc_set_prescaler(RCC_PRESCALER_APB2, (CLOCK_SPEED_MHZ>100) ? RCC_APB2_HCLK_DIV_2 : RCC_APB2_HCLK_DIV_1); - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} + /* PCLK1 = HCLK / 2*/ + rcc_set_prescaler(RCC_PRESCALER_APB1, (CLOCK_SPEED_MHZ>100) ? RCC_APB1_HCLK_DIV_4 : RCC_APB1_HCLK_DIV_2); + uint32 apb2_clk = CLOCK_SPEED_HZ / (1+(CLOCK_SPEED_MHZ/100)); + // save bus clock values + rcc_dev_clk_speed_table[RCC_AHB1] = CLOCK_SPEED_HZ; + rcc_dev_clk_speed_table[RCC_APB2] = apb2_clk; + rcc_dev_clk_speed_table[RCC_APB1] = apb2_clk/2; -void rcc_clk_init(rcc_sysclk_src sysclk_src, - rcc_pllsrc pll_src, - rcc_pll_multiplier pll_mul) { + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - //SetupClock72MHz(); -#if STM32_TICKS_PER_US == 168 - SetupClock168MHz(); -#endif -#if STM32_TICKS_PER_US == 120 - SetupClock120MHz(); -#endif -#if STM32_TICKS_PER_US == 72 - SetupClock72MHz(); -#endif -} + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0); + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + flash_init(flash_ws[(CLOCK_SPEED_MHZ/80)]); + /* Select the main PLL as system clock source */ + RCC->CFGR &= ~(RCC_CFGR_SW_MASK); + RCC->CFGR |= RCC_CFGR_SW_PLL; -#define PLL_M 8 -#define PLL_N 240 -/* SYSCLK = PLL_VCO / PLL_P */ -#define PLL_P 2 - -/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ -#define PLL_Q 5 - - -void rcc_clk_init2(rcc_sysclk_src sysclk_src, - rcc_pllsrc pll_src, - rcc_pll_multiplier pll_mul) { - -/******************************************************************************/ -/* PLL (clocked by HSE) used as System clock source */ -/******************************************************************************/ - uint32 StartUpCounter = 0, HSEStatus = 0; - rcc_reg_map *pRCC = RCC_BASE; - - /* Enable HSE */ - pRCC->CR |= RCC_CR_HSEON; - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = pRCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((pRCC->CR & RCC_CR_HSERDY) != 0) - { - HSEStatus = 0x01; - } - else - { - HSEStatus = 0x00; - } - - if (HSEStatus == 0x01) - { - /* HCLK = SYSCLK / 1*/ - pRCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - pRCC->CFGR |= RCC_CFGR_PPRE2_DIV2; - - /* PCLK1 = HCLK / 4*/ - pRCC->CFGR |= RCC_CFGR_PPRE1_DIV4; - - /* Configure the main PLL */ - pRCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - pRCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((pRCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - ((FLASH_TypeDef*)FLASH)->ACR = FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS; - - /* Select the main PLL as system clock source */ - pRCC->CFGR &= ~RCC_CFGR_SW; - pRCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((pRCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } - -#if 0 - uint32 cfgr = 0; - uint32 cr; - - /* Assume that we're going to clock the chip off the PLL, fed by - * the HSE */ - ASSERT(sysclk_src == RCC_CLKSRC_PLL && - pll_src == RCC_PLLSRC_HSE); - - RCC_BASE->CFGR = pll_src | pll_mul; - - /* Turn on the HSE */ - cr = RCC_BASE->CR; - cr |= RCC_CR_HSEON; - RCC_BASE->CR = cr; - while (!(RCC_BASE->CR & RCC_CR_HSERDY)) - ; - - /* Now the PLL */ - cr |= RCC_CR_PLLON; - RCC_BASE->CR = cr; - while (!(RCC_BASE->CR & RCC_CR_PLLRDY)) - ; - - /* Finally, let's switch over to the PLL */ - cfgr &= ~RCC_CFGR_SW; - cfgr |= RCC_CFGR_SW_PLL; - RCC_BASE->CFGR = cfgr; - while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) - ; -#endif + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & RCC_CFGR_SWS_MASK ) != RCC_CFGR_SWS_PLL); } - + + +//----------------------------------------------------------------------------- +static const __IO uint32* enable_regs[] = { + [APB1] = &RCC->APB1ENR, + [APB2] = &RCC->APB2ENR, + [AHB1] = &RCC->AHB1ENR, + [AHB2] = &RCC->AHB2ENR, + [AHB3] = &RCC->AHB3ENR, +}; /** * @brief Turn on the clock line on a peripheral * @param id Clock ID of the peripheral to turn on. */ -void rcc_clk_enable(rcc_clk_id id) { - static const __io uint32* enable_regs[] = { - [APB1] = &RCC_BASE->APB1ENR, - [APB2] = &RCC_BASE->APB2ENR, - [AHB1] = &RCC_BASE->AHB1ENR, - [AHB2] = &RCC_BASE->AHB2ENR, - [AHB3] = &RCC_BASE->AHB3ENR, - }; - +void rcc_clk_enable(rcc_clk_id id) +{ rcc_clk_domain clk_domain = rcc_dev_clk(id); - __io uint32* enr = (__io uint32*)enable_regs[clk_domain]; + __IO uint32* enr = (__IO uint32*)enable_regs[clk_domain]; uint8 lnum = rcc_dev_table[id].line_num; bb_peri_set_bit(enr, lnum, 1); @@ -617,37 +264,30 @@ void rcc_clk_enable(rcc_clk_id id) { * @brief Turn on the clock line on a peripheral * @param id Clock ID of the peripheral to turn on. */ -void rcc_clk_disable(rcc_clk_id id) { - static const __io uint32* enable_regs[] = { - [APB1] = &RCC_BASE->APB1ENR, - [APB2] = &RCC_BASE->APB2ENR, - [AHB1] = &RCC_BASE->AHB1ENR, - [AHB2] = &RCC_BASE->AHB2ENR, - [AHB3] = &RCC_BASE->AHB3ENR, - }; - +void rcc_clk_disable(rcc_clk_id id) +{ rcc_clk_domain clk_domain = rcc_dev_clk(id); - __io uint32* enr = (__io uint32*)enable_regs[clk_domain]; + __IO uint32* enr = (__IO uint32*)enable_regs[clk_domain]; uint8 lnum = rcc_dev_table[id].line_num; bb_peri_set_bit(enr, lnum, 0); } +static const __IO uint32* reset_regs[] = { + [APB1] = &RCC->APB1RSTR, + [APB2] = &RCC->APB2RSTR, + [AHB1] = &RCC->AHB1RSTR, + [AHB2] = &RCC->AHB2RSTR, + [AHB3] = &RCC->AHB3RSTR, +}; /** * @brief Reset a peripheral. * @param id Clock ID of the peripheral to reset. */ -void rcc_reset_dev(rcc_clk_id id) { - static const __io uint32* reset_regs[] = { - [APB1] = &RCC_BASE->APB1RSTR, - [APB2] = &RCC_BASE->APB2RSTR, - [AHB1] = &RCC_BASE->AHB1RSTR, - [AHB2] = &RCC_BASE->AHB2RSTR, - [AHB3] = &RCC_BASE->AHB3RSTR, - }; - +void rcc_reset_dev(rcc_clk_id id) +{ rcc_clk_domain clk_domain = rcc_dev_clk(id); - __io void* addr = (__io void*)reset_regs[clk_domain]; + __IO void* addr = (__IO void*)reset_regs[clk_domain]; uint8 lnum = rcc_dev_table[id].line_num; bb_peri_set_bit(addr, lnum, 1); @@ -686,21 +326,8 @@ uint32 rcc_dev_timer_clk_speed(rcc_clk_id id) { * @param prescaler prescaler to set * @param divider prescaler divider */ -void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { -#if 0 - static const uint32 masks[] = { - [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE, - [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1, - [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2, - [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE, - [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE, - }; - - uint32 cfgr = RCC_BASE->CFGR; - cfgr &= ~masks[prescaler]; - cfgr |= divider; - RCC_BASE->CFGR = cfgr; -#endif +void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) +{ + uint32 cfgr = RCC->CFGR & ~(prescaler); + RCC->CFGR = cfgr | divider; } - -#endif diff --git a/STM32F4/cores/maple/libmaple/rccF4.h b/STM32F4/cores/maple/libmaple/rccF4.h index 99c5ff25d..67452b602 100644 --- a/STM32F4/cores/maple/libmaple/rccF4.h +++ b/STM32F4/cores/maple/libmaple/rccF4.h @@ -42,41 +42,42 @@ extern "C"{ /** RCC register map type */ typedef struct { - __io uint32 CR; /*!< RCC clock control register, Address offset: 0x00 */ - __io uint32 PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ - __io uint32 CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ - __io uint32 CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ - __io uint32 AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ - __io uint32 AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ - __io uint32 AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ + __IO uint32 CR; /*!< RCC clock control register, Address offset: 0x00 */ + __IO uint32 PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ + __IO uint32 CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ + __IO uint32 CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ + __IO uint32 AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ + __IO uint32 AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ + __IO uint32 AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ uint32 RESERVED0; /*!< Reserved, 0x1C */ - __io uint32 APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ - __io uint32 APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ + __IO uint32 APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ + __IO uint32 APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ uint32 RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ - __io uint32 AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ - __io uint32 AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ - __io uint32 AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ + __IO uint32 AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ + __IO uint32 AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ + __IO uint32 AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ uint32 RESERVED2; /*!< Reserved, 0x3C */ - __io uint32 APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ - __io uint32 APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ + __IO uint32 APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ + __IO uint32 APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ uint32 RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ - __io uint32 AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ - __io uint32 AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ - __io uint32 AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ + __IO uint32 AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ + __IO uint32 AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ + __IO uint32 AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ uint32 RESERVED4; /*!< Reserved, 0x5C */ - __io uint32 APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ - __io uint32 APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ + __IO uint32 APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ + __IO uint32 APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ uint32 RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ - __io uint32 BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ - __io uint32 CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ + __IO uint32 BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ + __IO uint32 CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ uint32 RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ - __io uint32 SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ - __io uint32 PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ + __IO uint32 SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ + __IO uint32 PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ } rcc_reg_map; /** RCC register map base pointer */ -//#define RCC_BASE ((struct rcc_reg_map*)0x40021000) -#define RCC_BASE ((rcc_reg_map*)0x40023800) +#define RCC ((rcc_reg_map*)0x40023800) + +//extern rcc_reg_map * const RCC; /* * Register bit definitions @@ -84,6 +85,7 @@ typedef struct /* Clock control register */ +#define RCC_CR_PLLI2SON_BIT 26 #define RCC_CR_PLLRDY_BIT 25 #define RCC_CR_PLLON_BIT 24 #define RCC_CR_CSSON_BIT 19 @@ -93,6 +95,7 @@ typedef struct #define RCC_CR_HSIRDY_BIT 1 #define RCC_CR_HSION_BIT 0 +#define RCC_CR_PLLI2SON BIT(RCC_CR_PLLI2SON_BIT) #define RCC_CR_PLLRDY BIT(RCC_CR_PLLRDY_BIT) #define RCC_CR_PLLON BIT(RCC_CR_PLLON_BIT) #define RCC_CR_CSSON BIT(RCC_CR_CSSON_BIT) @@ -104,27 +107,83 @@ typedef struct #define RCC_CR_HSIRDY BIT(RCC_CR_HSIRDY_BIT) #define RCC_CR_HSION BIT(RCC_CR_HSION_BIT) +#define RCC_CR_HSITRIM_4 (0x04 << 3) + +/******************** Bit definition for RCC_PLLCFGR register ***************/ +#define RCC_PLLCFGR_PLLM ((uint32_t)0x0000003FU) +#define RCC_PLLCFGR_PLLM_0 ((uint32_t)0x00000001U) +#define RCC_PLLCFGR_PLLM_1 ((uint32_t)0x00000002U) +#define RCC_PLLCFGR_PLLM_2 ((uint32_t)0x00000004U) +#define RCC_PLLCFGR_PLLM_3 ((uint32_t)0x00000008U) +#define RCC_PLLCFGR_PLLM_4 ((uint32_t)0x00000010U) +#define RCC_PLLCFGR_PLLM_5 ((uint32_t)0x00000020U) + +#define RCC_PLLCFGR_PLLN ((uint32_t)0x00007FC0U) +#define RCC_PLLCFGR_PLLN_0 ((uint32_t)0x00000040U) +#define RCC_PLLCFGR_PLLN_1 ((uint32_t)0x00000080U) +#define RCC_PLLCFGR_PLLN_2 ((uint32_t)0x00000100U) +#define RCC_PLLCFGR_PLLN_3 ((uint32_t)0x00000200U) +#define RCC_PLLCFGR_PLLN_4 ((uint32_t)0x00000400U) +#define RCC_PLLCFGR_PLLN_5 ((uint32_t)0x00000800U) +#define RCC_PLLCFGR_PLLN_6 ((uint32_t)0x00001000U) +#define RCC_PLLCFGR_PLLN_7 ((uint32_t)0x00002000U) +#define RCC_PLLCFGR_PLLN_8 ((uint32_t)0x00004000U) + +#define RCC_PLLCFGR_PLLP ((uint32_t)0x00030000U) +#define RCC_PLLCFGR_PLLP_0 ((uint32_t)0x00010000U) +#define RCC_PLLCFGR_PLLP_1 ((uint32_t)0x00020000U) + +#define RCC_PLLCFGR_PLLSRC ((uint32_t)0x00400000U) +#define RCC_PLLCFGR_PLLSRC_HSE ((uint32_t)0x00400000U) +#define RCC_PLLCFGR_PLLSRC_HSI ((uint32_t)0x00000000U) + +#define RCC_PLLCFGR_PLLQ ((uint32_t)0x0F000000U) +#define RCC_PLLCFGR_PLLQ_0 ((uint32_t)0x01000000U) +#define RCC_PLLCFGR_PLLQ_1 ((uint32_t)0x02000000U) +#define RCC_PLLCFGR_PLLQ_2 ((uint32_t)0x04000000U) +#define RCC_PLLCFGR_PLLQ_3 ((uint32_t)0x08000000U) + /* Clock configuration register */ -#define RCC_CFGR_USBPRE_BIT 22 -#define RCC_CFGR_PLLXTPRE_BIT 17 -#define RCC_CFGR_PLLSRC_BIT 16 - -#define RCC_CFGR_MCO (0x3 << 24) -#define RCC_CFGR_USBPRE BIT(RCC_CFGR_USBPRE_BIT) -#define RCC_CFGR_PLLMUL (0xF << 18) -#define RCC_CFGR_PLLXTPRE BIT(RCC_CFGR_PLLXTPRE_BIT) -#define RCC_CFGR_PLLSRC BIT(RCC_CFGR_PLLSRC_BIT) -#define RCC_CFGR_ADCPRE (0x3 << 14) -#define RCC_CFGR_PPRE2 (0x7 << 11) -#define RCC_CFGR_PPRE1 (0x7 << 8) -#define RCC_CFGR_HPRE (0xF << 4) -#define RCC_CFGR_SWS (0x3 << 2) -#define RCC_CFGR_SWS_PLL (0x2 << 2) -#define RCC_CFGR_SWS_HSE (0x1 << 2) -#define RCC_CFGR_SW 0x3 -#define RCC_CFGR_SW_PLL 0x2 -#define RCC_CFGR_SW_HSE 0x1 +#define RCC_CFGR_MCO2_BIT 30 +#define RCC_CFGR_MCO2PRE_BIT 27 +#define RCC_CFGR_MCO1PRE_BIT 24 +#define RCC_CFGR_I2SSC_BIT 23 +#define RCC_CFGR_MCO1_BIT 21 +#define RCC_CFGR_RTCPRE_BIT 16 +#define RCC_CFGR_PPRE2_BIT 13 +#define RCC_CFGR_PPRE1_BIT 10 +#define RCC_CFGR_HPRE_BIT 4 +#define RCC_CFGR_SWS_BIT 2 +#define RCC_CFGR_SW_BIT 0 + +#define RCC_CFGR_MCO2 (0x3 << RCC_CFGR_MCO2_BIT) +#define RCC_CFGR_MCO2PRE_MASK (0x7 << RCC_CFGR_MCO2PRE_BIT) +#define RCC_CFGR_MCO2PRE_DIV1 (0x0 << RCC_CFGR_MCO2PRE_BIT) +#define RCC_CFGR_MCO2PRE_DIV2 (0x4 << RCC_CFGR_MCO2PRE_BIT) +#define RCC_CFGR_MCO2PRE_DIV3 (0x5 << RCC_CFGR_MCO2PRE_BIT) +#define RCC_CFGR_MCO2PRE_DIV4 (0x6 << RCC_CFGR_MCO2PRE_BIT) +#define RCC_CFGR_MCO2PRE_DIV5 (0x7 << RCC_CFGR_MCO2PRE_BIT) +#define RCC_CFGR_MCO1PRE_MASK (0x7 << RCC_CFGR_MCO1PRE_BIT) +#define RCC_CFGR_MCO1PRE_DIV1 (0x0 << RCC_CFGR_MCO1PRE_BIT) +#define RCC_CFGR_MCO1PRE_DIV2 (0x4 << RCC_CFGR_MCO1PRE_BIT) +#define RCC_CFGR_MCO1PRE_DIV3 (0x5 << RCC_CFGR_MCO1PRE_BIT) +#define RCC_CFGR_MCO1PRE_DIV4 (0x6 << RCC_CFGR_MCO1PRE_BIT) +#define RCC_CFGR_MCO1PRE_DIV5 (0x7 << RCC_CFGR_MCO1PRE_BIT) +#define RCC_CFGR_I2SSC (0x1 << RCC_CFGR_I2SSC_BIT) +#define RCC_CFGR_MCO1_MASK (0x3 << RCC_CFGR_MCO1_BIT) +#define RCC_CFGR_RTCPRE_MASK (0x1F << RCC_CFGR_RTCPRE_BIT) +#define RCC_CFGR_PPRE2_MASK (0x7 << RCC_CFGR_PPRE2_BIT) +#define RCC_CFGR_PPRE1_MASK (0x7 << RCC_CFGR_PPRE1_BIT) +#define RCC_CFGR_HPRE_MASK (0xF << RCC_CFGR_HPRE_BIT) +#define RCC_CFGR_SWS_MASK (0x3 << RCC_CFGR_SWS_BIT) +#define RCC_CFGR_SWS_PLL (0x2 << RCC_CFGR_SWS_BIT) +#define RCC_CFGR_SWS_HSE (0x1 << RCC_CFGR_SWS_BIT) +#define RCC_CFGR_SWS_HSI (0x0 << RCC_CFGR_SWS_BIT) +#define RCC_CFGR_SW_MASK (0x3 << RCC_CFGR_SW_BIT) +#define RCC_CFGR_SW_PLL (0x2 << RCC_CFGR_SW_BIT) +#define RCC_CFGR_SW_HSE (0x1 << RCC_CFGR_SW_BIT) +#define RCC_CFGR_SW_HSI (0x0 << RCC_CFGR_SW_BIT) #define RCC_CFGR_MCO1Source_HSI ((uint32_t)0x00000000) #define RCC_CFGR_MCO1Source_LSE ((uint32_t)0x00200000) @@ -267,6 +326,7 @@ typedef struct /* AHB peripheral clock enable register */ +#define RCC_AHB1ENR_BKPSRAMEN_BIT 18 #define RCC_AHBENR_SDIOEN_BIT 10 #define RCC_AHBENR_FSMCEN_BIT 8 #define RCC_AHBENR_CRCEN_BIT 7 @@ -275,6 +335,7 @@ typedef struct #define RCC_AHBENR_DMA2EN_BIT 1 #define RCC_AHBENR_DMA1EN_BIT 0 +#define RCC_AHB1ENR_BKPSRAMEN BIT(RCC_AHB1ENR_BKPSRAMEN_BIT) #define RCC_AHBENR_SDIOEN BIT(RCC_AHBENR_SDIOEN_BIT) #define RCC_AHBENR_FSMCEN BIT(RCC_AHBENR_FSMCEN_BIT) #define RCC_AHBENR_CRCEN BIT(RCC_AHBENR_CRCEN_BIT) @@ -377,17 +438,18 @@ typedef struct #define RCC_BDCR_BDRST_BIT 16 #define RCC_BDCR_RTCEN_BIT 15 +#define RCC_BDCR_RTCSEL_BIT 8 #define RCC_BDCR_LSEBYP_BIT 2 #define RCC_BDCR_LSERDY_BIT 1 #define RCC_BDCR_LSEON_BIT 0 #define RCC_BDCR_BDRST BIT(RCC_BDCR_BDRST_BIT) -#define RCC_BDCR_RTCEN BIT(RCC_BDCR_RTC_BIT) -#define RCC_BDCR_RTCSEL (0x3 << 8) -#define RCC_BDCR_RTCSEL_NONE (0x0 << 8) -#define RCC_BDCR_RTCSEL_LSE (0x1 << 8) -#define RCC_BDCR_RTCSEL_LSI (0x2 << 8) -#define RCC_BDCR_RTCSEL_HSE (0x3 << 8) +#define RCC_BDCR_RTCEN BIT(RCC_BDCR_RTCEN_BIT) +#define RCC_BDCR_RTCSEL_MASK (0x3 << RCC_BDCR_RTCSEL_BIT) +#define RCC_BDCR_RTCSEL_NONE (0x0 << RCC_BDCR_RTCSEL_BIT) +#define RCC_BDCR_RTCSEL_LSE (0x1 << RCC_BDCR_RTCSEL_BIT) +#define RCC_BDCR_RTCSEL_LSI (0x2 << RCC_BDCR_RTCSEL_BIT) +#define RCC_BDCR_RTCSEL_HSE (0x3 << RCC_BDCR_RTCSEL_BIT) #define RCC_BDCR_LSEBYP BIT(RCC_BDCR_LSEBYP_BIT) #define RCC_BDCR_LSERDY BIT(RCC_BDCR_LSERDY_BIT) #define RCC_BDCR_LSEON BIT(RCC_BDCR_LSEON_BIT) @@ -414,6 +476,23 @@ typedef struct #define RCC_CSR_LSIRDY BIT(RCC_CSR_LSIRDY_BIT) #define RCC_CSR_LSION BIT(RCC_CSR_LSION_BIT) +/******************** Bit definition for RCC_PLLI2SCFGR register ************/ +#define RCC_PLLI2SCFGR_PLLI2SN ((uint32_t)0x00007FC0U) +#define RCC_PLLI2SCFGR_PLLI2SN_0 ((uint32_t)0x00000040U) +#define RCC_PLLI2SCFGR_PLLI2SN_1 ((uint32_t)0x00000080U) +#define RCC_PLLI2SCFGR_PLLI2SN_2 ((uint32_t)0x00000100U) +#define RCC_PLLI2SCFGR_PLLI2SN_3 ((uint32_t)0x00000200U) +#define RCC_PLLI2SCFGR_PLLI2SN_4 ((uint32_t)0x00000400U) +#define RCC_PLLI2SCFGR_PLLI2SN_5 ((uint32_t)0x00000800U) +#define RCC_PLLI2SCFGR_PLLI2SN_6 ((uint32_t)0x00001000U) +#define RCC_PLLI2SCFGR_PLLI2SN_7 ((uint32_t)0x00002000U) +#define RCC_PLLI2SCFGR_PLLI2SN_8 ((uint32_t)0x00004000U) + +#define RCC_PLLI2SCFGR_PLLI2SR ((uint32_t)0x70000000U) +#define RCC_PLLI2SCFGR_PLLI2SR_0 ((uint32_t)0x10000000U) +#define RCC_PLLI2SCFGR_PLLI2SR_1 ((uint32_t)0x20000000U) +#define RCC_PLLI2SCFGR_PLLI2SR_2 ((uint32_t)0x40000000U) + /* * Convenience routines */ @@ -470,62 +549,80 @@ typedef enum rcc_clk_id { RCC_GPIOB, RCC_GPIOC, RCC_GPIOD, -// RCC_AFIO, - RCC_ADC1, - RCC_ADC2, - RCC_ADC3, - RCC_USART1, - RCC_USART2, - RCC_USART3, + RCC_GPIOE, + RCC_GPIOF, + RCC_GPIOG, + RCC_GPIOH, + RCC_GPIOI, + + RCC_CRC, +// RCC_FLITF, +// RCC_SRAM1, +// RCC_SRAM2, +// RCC_BKPSRAM, +#ifdef __CCMRAM__ + RCC_CCMRAM, +#endif + RCC_DMA1, + RCC_DMA2, + RCC_ETHMAC, + RCC_ETHMACTX, + RCC_ETHMACRX, + RCC_ETHMACPTP, + + RCC_DCMI, + RCC_USBFS, + + RCC_FSMC, + RCC_TIMER1, RCC_TIMER2, RCC_TIMER3, RCC_TIMER4, - RCC_SPI1, - RCC_SPI2, - RCC_DMA1, - RCC_PWR, - RCC_BKP, - RCC_I2C1, - RCC_I2C2, - RCC_CRC, -// RCC_FLITF, -// RCC_SRAM, - RCC_GPIOE, - RCC_GPIOF, - RCC_GPIOG, - RCC_UART4, - RCC_UART5, RCC_TIMER5, RCC_TIMER6, RCC_TIMER7, RCC_TIMER8, - RCC_FSMC, - RCC_DAC, - RCC_DMA2, - RCC_SDIO, - RCC_SPI3, RCC_TIMER9, RCC_TIMER10, RCC_TIMER11, RCC_TIMER12, RCC_TIMER13, RCC_TIMER14, - RCC_USBFS, - RCC_SYSCFG, - RCC_SPI4 + RCC_WDG, + RCC_SPI1, + RCC_SPI2, + RCC_SPI3, + RCC_SPI4, + RCC_SPI5, + + RCC_USART1, + RCC_USART2, + RCC_USART3, + RCC_UART4, + RCC_UART5, + RCC_USART6, + RCC_ADC1, + RCC_ADC2, + RCC_ADC3, + RCC_SDIO, + RCC_SYSCFG, + + RCC_I2C1, + RCC_I2C2, + RCC_I2C3, + RCC_CAN1, + RCC_CAN2, + RCC_PWR, + RCC_DAC, + } rcc_clk_id; -void rcc_clk_init(rcc_sysclk_src sysclk_src, - rcc_pllsrc pll_src, - rcc_pll_multiplier pll_mul); +void rcc_clk_init(void); void rcc_clk_disable(rcc_clk_id device); void rcc_clk_enable(rcc_clk_id device); void rcc_reset_dev(rcc_clk_id device); -void SetupClock72MHz(); -void SetupClock120MHz(); -void SetupClock168MHz(); typedef enum rcc_clk_domain { RCC_APB1, @@ -544,35 +641,23 @@ uint32 rcc_dev_timer_clk_speed(rcc_clk_id id); * Prescaler identifiers * @see rcc_set_prescaler() */ -typedef enum rcc_prescaler { - RCC_PRESCALER_AHB, - RCC_PRESCALER_APB1, - RCC_PRESCALER_APB2, - RCC_PRESCALER_USB, - RCC_PRESCALER_ADC +typedef enum { + RCC_PRESCALER_AHB = RCC_CFGR_HPRE_MASK, + RCC_PRESCALER_APB1 = RCC_CFGR_PPRE1_MASK, + RCC_PRESCALER_APB2 = RCC_CFGR_PPRE2_MASK, + RCC_PRESCALER_RTC = RCC_CFGR_RTCPRE_MASK, } rcc_prescaler; -/** - * ADC prescaler dividers - * @see rcc_set_prescaler() - */ -typedef enum rcc_adc_divider { - RCC_ADCPRE_PCLK_DIV_2 = 0x0 << 14, - RCC_ADCPRE_PCLK_DIV_4 = 0x1 << 14, - RCC_ADCPRE_PCLK_DIV_6 = 0x2 << 14, - RCC_ADCPRE_PCLK_DIV_8 = 0x3 << 14, -} rcc_adc_divider; - /** * APB1 prescaler dividers * @see rcc_set_prescaler() */ typedef enum rcc_apb1_divider { - RCC_APB1_HCLK_DIV_1 = 0x0 << 8, - RCC_APB1_HCLK_DIV_2 = 0x4 << 8, - RCC_APB1_HCLK_DIV_4 = 0x5 << 8, - RCC_APB1_HCLK_DIV_8 = 0x6 << 8, - RCC_APB1_HCLK_DIV_16 = 0x7 << 8, + RCC_APB1_HCLK_DIV_1 = (0x0 << RCC_CFGR_PPRE1_BIT), + RCC_APB1_HCLK_DIV_2 = (0x4 << RCC_CFGR_PPRE1_BIT), + RCC_APB1_HCLK_DIV_4 = (0x5 << RCC_CFGR_PPRE1_BIT), + RCC_APB1_HCLK_DIV_8 = (0x6 << RCC_CFGR_PPRE1_BIT), + RCC_APB1_HCLK_DIV_16 = (0x7 << RCC_CFGR_PPRE1_BIT), } rcc_apb1_divider; /** @@ -580,11 +665,11 @@ typedef enum rcc_apb1_divider { * @see rcc_set_prescaler() */ typedef enum rcc_apb2_divider { - RCC_APB2_HCLK_DIV_1 = 0x0 << 11, - RCC_APB2_HCLK_DIV_2 = 0x4 << 11, - RCC_APB2_HCLK_DIV_4 = 0x5 << 11, - RCC_APB2_HCLK_DIV_8 = 0x6 << 11, - RCC_APB2_HCLK_DIV_16 = 0x7 << 11, + RCC_APB2_HCLK_DIV_1 = (0x0 << RCC_CFGR_PPRE2_BIT), + RCC_APB2_HCLK_DIV_2 = (0x4 << RCC_CFGR_PPRE2_BIT), + RCC_APB2_HCLK_DIV_4 = (0x5 << RCC_CFGR_PPRE2_BIT), + RCC_APB2_HCLK_DIV_8 = (0x6 << RCC_CFGR_PPRE2_BIT), + RCC_APB2_HCLK_DIV_16 = (0x7 << RCC_CFGR_PPRE2_BIT), } rcc_apb2_divider; /** @@ -592,27 +677,29 @@ typedef enum rcc_apb2_divider { * @see rcc_set_prescaler() */ typedef enum rcc_ahb_divider { - RCC_AHB_SYSCLK_DIV_1 = 0x0 << 4, - RCC_AHB_SYSCLK_DIV_2 = 0x8 << 4, - RCC_AHB_SYSCLK_DIV_4 = 0x9 << 4, - RCC_AHB_SYSCLK_DIV_8 = 0xA << 4, - RCC_AHB_SYSCLK_DIV_16 = 0xB << 4, - RCC_AHB_SYSCLK_DIV_32 = 0xC << 4, - RCC_AHB_SYSCLK_DIV_64 = 0xD << 4, - RCC_AHB_SYSCLK_DIV_128 = 0xD << 4, - RCC_AHB_SYSCLK_DIV_256 = 0xE << 4, - RCC_AHB_SYSCLK_DIV_512 = 0xF << 4, + RCC_AHB_SYSCLK_DIV_1 = (0x0 << RCC_CFGR_HPRE_BIT), + RCC_AHB_SYSCLK_DIV_2 = (0x8 << RCC_CFGR_HPRE_BIT), + RCC_AHB_SYSCLK_DIV_4 = (0x9 << RCC_CFGR_HPRE_BIT), + RCC_AHB_SYSCLK_DIV_8 = (0xA << RCC_CFGR_HPRE_BIT), + RCC_AHB_SYSCLK_DIV_16 = (0xB << RCC_CFGR_HPRE_BIT), + RCC_AHB_SYSCLK_DIV_32 = (0xC << RCC_CFGR_HPRE_BIT), + RCC_AHB_SYSCLK_DIV_64 = (0xD << RCC_CFGR_HPRE_BIT), + RCC_AHB_SYSCLK_DIV_128 = (0xD << RCC_CFGR_HPRE_BIT), + RCC_AHB_SYSCLK_DIV_256 = (0xE << RCC_CFGR_HPRE_BIT), + RCC_AHB_SYSCLK_DIV_512 = (0xF << RCC_CFGR_HPRE_BIT), } rcc_ahb_divider; -void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider); +#define RCC_RTCCLK_DIV(i) ((i)<CSR, RCC_CSR_LSION_BIT) = 1; - while (*bb_perip(&RCC_BASE->CSR, RCC_CSR_LSIRDY_BIT) == 0); + *bb_perip(&RCC->CSR, RCC_CSR_LSION_BIT) = 1; + while (*bb_perip(&RCC->CSR, RCC_CSR_LSIRDY_BIT) == 0); } /* FIXME [0.0.13] Just have data point to an rcc_pll_multiplier! */ @@ -620,19 +707,19 @@ static inline void rcc_start_lsi(void) { * @brief Start the low speed external oscillatior */ static inline void rcc_start_lse(void) { - bb_peri_set_bit(&RCC_BASE->BDCR, RCC_BDCR_LSEBYP_BIT, 0); - bb_peri_set_bit(&RCC_BASE->BDCR, RCC_BDCR_LSEON_BIT, 1); - while (bb_peri_get_bit(&RCC_BASE->BDCR, RCC_BDCR_LSERDY_BIT ) == 0); + bb_peri_set_bit(&RCC->BDCR, RCC_BDCR_LSEBYP_BIT, 0); + bb_peri_set_bit(&RCC->BDCR, RCC_BDCR_LSEON_BIT, 1); + while (bb_peri_get_bit(&RCC->BDCR, RCC_BDCR_LSERDY_BIT ) == 0); } /* * Deprecated bits. */ static inline void rcc_start_hse(void) { // Added to support RTClock -// *bb_perip(&RCC_BASE->CR, RCC_CR_HSEON_BIT) = 1; - while (bb_peri_get_bit(&RCC_BASE->CR, RCC_CR_HSERDY_BIT) == 0); +// *bb_perip(&RCC->CR, RCC_CR_HSEON_BIT) = 1; + while (bb_peri_get_bit(&RCC->CR, RCC_CR_HSERDY_BIT) == 0); } - +#endif #ifdef __cplusplus diff --git a/STM32F4/cores/maple/libmaple/ring_buffer.h b/STM32F4/cores/maple/libmaple/ring_buffer.h index b0185223a..0c09dbd42 100644 --- a/STM32F4/cores/maple/libmaple/ring_buffer.h +++ b/STM32F4/cores/maple/libmaple/ring_buffer.h @@ -52,9 +52,9 @@ extern "C"{ * One byte is left free to distinguish empty from full. */ typedef struct ring_buffer { volatile uint8 *buf; /**< Buffer items are stored into */ - uint16 head; /**< Index of the next item to remove */ - uint16 tail; /**< Index where the next item will get inserted */ - uint16 size; /**< Buffer capacity minus one */ + volatile uint16 head; /**< Index of the next item to remove */ + volatile uint16 tail; /**< Index where the next item will get inserted */ + volatile uint16 size; /**< Buffer capacity minus one */ } ring_buffer; /** @@ -81,12 +81,8 @@ static inline void rb_init(ring_buffer *rb, uint16 size, uint8 *buf) { * @param rb Buffer whose elements to count. */ static inline uint16 rb_full_count(ring_buffer *rb) { - __io ring_buffer *arb = rb; - int32 size = arb->tail - arb->head; - if (arb->tail < arb->head) { - size += arb->size + 1; - } - return (uint16)size; + int32 size = rb->tail - rb->head; + return ( size<0 ) ? (uint16)(size + rb->size + 1) : (uint16)size; } /** @@ -102,7 +98,7 @@ static inline int rb_is_full(ring_buffer *rb) { * @brief Returns true if and only if the ring buffer is empty. * @param rb Buffer to test. */ -static inline int rb_is_empty(ring_buffer *rb) { +static inline int16 rb_is_empty(ring_buffer *rb) { return rb->head == rb->tail; } @@ -112,8 +108,8 @@ static inline int rb_is_empty(ring_buffer *rb) { * @param element Value to append. */ static inline void rb_insert(ring_buffer *rb, uint8 element) { - rb->buf[rb->tail] = element; - rb->tail = (rb->tail == rb->size) ? 0 : rb->tail + 1; + rb->buf[rb->tail++] = element; + if (rb->tail > rb->size) rb->tail = 0; } /** @@ -121,8 +117,8 @@ static inline void rb_insert(ring_buffer *rb, uint8 element) { * @param rb Buffer to remove from, must contain at least one element. */ static inline uint8 rb_remove(ring_buffer *rb) { - uint8 ch = rb->buf[rb->head]; - rb->head = (rb->head == rb->size) ? 0 : rb->head + 1; + uint8 ch = rb->buf[rb->head++]; + if (rb->head > rb->size) rb->head = 0; return ch; } @@ -132,7 +128,7 @@ static inline uint8 rb_remove(ring_buffer *rb) { * @brief Return the first item from a ring buffer, without removing it * @param rb Buffer to remove from, must contain at least one element. */ -static inline int rb_peek(ring_buffer *rb) +static inline int16 rb_peek(ring_buffer *rb) { if (rb->head == rb->tail) { @@ -140,7 +136,7 @@ static inline int rb_peek(ring_buffer *rb) } else { - return rb->buf[rb->head]; + return rb->buf[rb->head]; } } @@ -164,7 +160,7 @@ static inline int16 rb_safe_remove(ring_buffer *rb) { * @param element Value to insert into rb. * @sideeffect If rb is not full, appends element onto buffer. * @return If element was appended, then true; otherwise, false. */ -static inline int rb_safe_insert(ring_buffer *rb, uint8 element) { +static inline int16 rb_safe_insert(ring_buffer *rb, uint8 element) { if (rb_is_full(rb)) { return 0; } @@ -183,7 +179,7 @@ static inline int rb_safe_insert(ring_buffer *rb, uint8 element) { * @return On success, returns -1. If an element was popped, returns * the popped value. */ -static inline int rb_push_insert(ring_buffer *rb, uint8 element) { +static inline int16 rb_push_insert(ring_buffer *rb, uint8 element) { int ret = -1; if (rb_is_full(rb)) { ret = rb_remove(rb); diff --git a/STM32F4/cores/maple/libmaple/rtc.c b/STM32F4/cores/maple/libmaple/rtc.c new file mode 100644 index 000000000..fec6e5e6a --- /dev/null +++ b/STM32F4/cores/maple/libmaple/rtc.c @@ -0,0 +1,261 @@ + +#include "rtc.h" + + +uint32_t rtc_tr, rtc_dr; + +//----------------------------------------------------------------------------- +uint8_t _year(uint32_t dr) { return bcd2bin( (dr>>RTC_DR_YEAR_BIT) & RTC_DR_YEAR_MASK ); } +uint8_t _month(uint32_t dr) { return bcd2bin( (dr>>RTC_DR_MONTH_BIT) & RTC_DR_MONTH_MASK ); } +uint8_t _day(uint32_t dr) { return bcd2bin( (dr>>RTC_DR_DAY_BIT) & RTC_DR_DAY_MASK ); } +uint8_t _weekday(uint32_t dr) { return bcd2bin( (dr>>RTC_DR_WEEKDAY_BIT) & RTC_DR_WEEKDAY_MASK ); } +uint8_t _pm(uint32_t tr) { return ( (tr>>RTC_TR_PM_BIT) & RTC_TR_PM_MASK ); } +uint8_t _hour(uint32_t tr) { return bcd2bin( (tr>>RTC_TR_HOUR_BIT) & RTC_TR_HOUR_MASK ); } +uint8_t _minute(uint32_t tr) { return bcd2bin( (tr>>RTC_TR_MINUTE_BIT) & RTC_TR_MINUTE_MASK ); } +uint8_t _second(uint32_t tr) { return bcd2bin( (tr>>RTC_TR_SECOND_BIT) & RTC_TR_SECOND_MASK ); } + +//----------------------------------------------------------------------------- +void getTimeStamp(void) +{ + rtc_tr = RTC->TR; + (void)RTC->DR; + rtc_dr = RTC->DR; +} + +//----------------------------------------------------------------------------- +void _getTime(tm_t *tm) +{ + uint32 tr; + do { // read multiple time till both readings are equal + getTimeStamp(); + tr = rtc_tr; + getTimeStamp(); + } while ( tr!=rtc_tr ); + tm->year = _year(rtc_dr); + tm->month = _month(rtc_dr); + tm->day = _day(rtc_dr); + tm->weekday = _weekday(rtc_dr); + tm->pm = _pm(rtc_tr); + tm->hour = _hour(rtc_tr); + tm->minute = _minute(rtc_tr); + tm->second = _second(rtc_tr); +} + +//----------------------------------------------------------------------------- +void _setTime(tm_t *tm) +{ + if (tm->year > 99) + tm->year = tm->year % 100; + rtc_dr = BUILD_DATE_REGISTER(tm->year, tm->month, tm->day, tm->weekday); + rtc_tr = BUILD_TIME_REGISTER(tm->hour, tm->minute, tm->second); + rtc_enter_config_mode(); + RTC->TR = rtc_tr; + RTC->DR = rtc_dr; + rtc_exit_config_mode(); + //getTimeStamp(); // fix wrong first read +} + +//----------------------------------------------------------------------------- +#define SECS_PER_MIN (60UL) +#define SECS_PER_HOUR (3600UL) +#define SECS_PER_DAY (SECS_PER_HOUR * 24UL) +#define DAYS_PER_WEEK (7UL) +#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK) +#define SECS_PER_YEAR (SECS_PER_WEEK * 52UL) +#define SECS_YR_2000 (946684800UL) // the time at the start of y2k + +#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) ) +static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0 +//----------------------------------------------------------------------------- +time_t _makeTime(tm_t * tm) +{ +// assemble time elements into time_t +// note year argument is offset from 1970 (see macros in time.h to convert to other formats) +// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 + + // seconds from 1970 till 1 jan 00:00:00 of the given year + uint32_t seconds = tm->year*(SECS_PER_DAY * 365); + for (uint16_t i = 0; i < tm->year; i++) { + if (LEAP_YEAR(i)) { + seconds += SECS_PER_DAY; // add extra days for leap years + } + } + + // add days for this year, months start from 1 + for (uint16_t i = 1; i < tm->month; i++) { + if ( (i == 2) && LEAP_YEAR(tm->year)) { + seconds += SECS_PER_DAY * 29; + } else { + seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0 + } + } + seconds+= (tm->day-1) * SECS_PER_DAY; + seconds+= tm->hour * SECS_PER_HOUR; + seconds+= tm->minute * SECS_PER_MIN; + seconds+= tm->second; + return (time_t)seconds; +} +//----------------------------------------------------------------------------- +void _breakTime(time_t epoch_time, tm_t * tm) +{ +// break the given time_t into time components +// this is a more compact version of the C library localtime function +// note that year is offset from 1970 !!! + + uint32_t time = (uint32_t)epoch_time; + tm->second = time % 60; + time /= 60; // now it is minutes + tm->minute = time % 60; + time /= 60; // now it is hours + tm->hour = time % 24; + time /= 24; // now it is days + tm->weekday = ((time + 4) % 7); // Monday is day 1 // (time + 4): Sunday is day 1 + + uint8_t year = 0; + uint32_t days = 0; + while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { + year++; + } + tm->year = year; // year is offset from 1970 + + days -= LEAP_YEAR(year) ? 366 : 365; + time -= days; // now it is days in this year, starting at 0 + + uint8_t month = 0; + uint8_t monthLength = 0; + for (month=0; month<12; month++) + { + if (month==1) { // february + if (LEAP_YEAR(year)) { + monthLength=29; + } else { + monthLength=28; + } + } else { + monthLength = monthDays[month]; + } + + if (time >= monthLength) { + time -= monthLength; + } else { + break; + } + } + tm->month = month + 1; // jan is month 1 + tm->day = time + 1; // day of month +} + +#if 0 +//----------------------------------------------------------------------------- +// Check (wait if necessary) to see RTC registers are synchronized. +//----------------------------------------------------------------------------- +void rtc_wait_sync() +{ + PRINTF("> rtc_wait_sync\n"); + uint32 t = millis(); + while ( !(RTC->ISR & BIT(RTC_ISR_RSF_BIT)) ) + { + if ( (millis()-t)>1500) { + PRINTF("Sync Timeout ! ISR = %08X\n", RTC->ISR); + break; + } + } + PRINTF("< rtc_wait_sync\n"); +} +#endif + +//----------------------------------------------------------------------------- +// Enable an RTC alarm event. Enabling this event allows waking up from deep sleep via WFE. +//----------------------------------------------------------------------------- +void rtc_enable_alarm_event() +{ + EXTI_BASE->IMR |= EXTI_RTC_ALARM; + EXTI_BASE->EMR |= EXTI_RTC_ALARM; + EXTI_BASE->RTSR |= EXTI_RTC_ALARM; +} + +//----------------------------------------------------------------------------- +// Disable the RTC alarm event. +//----------------------------------------------------------------------------- +void rtc_disable_alarm_event() +{ + EXTI_BASE->EMR &= ~(EXTI_RTC_ALARM); + EXTI_BASE->RTSR &= ~(EXTI_RTC_ALARM); +} + +//----------------------------------------------------------------------------- +// @brief Enable an RTC Wakeup event. +//----------------------------------------------------------------------------- +void rtc_enable_wakeup_event() +{ + EXTI_BASE->IMR |= EXTI_RTC_WAKEUP; + EXTI_BASE->EMR |= EXTI_RTC_WAKEUP; + EXTI_BASE->RTSR |= EXTI_RTC_WAKEUP; +} + +//----------------------------------------------------------------------------- +// Enter configuration mode. +//----------------------------------------------------------------------------- +void rtc_enter_config_mode() +{ + //PRINTF("> rtc_enter_config_mode\n"); + noInterrupts(); + // Unlock Write Protect + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + //PRINTF("RTC->ISR(1) = %08X\n", RTC->ISR); + //*bb_perip(&RTC->ISR, RTC_ISR_INIT_BIT) = 1; + RTC->ISR = 0x1FFFF; + //PRINTF("RTC->ISR(2) = %08X\n", RTC->ISR); + uint32 t = 0; + while (!(RTC->ISR & RTC_ISR_INITF)) + { + if (++t > 10000000) { + //PRINTF("RTC->ISR.INITF Timeout ! ISR = %08X\n", RTC->ISR); + break;; + } + } + //PRINTF("< rtc_enter_config_mode\n"); +} + + +voidFuncPtr handlerAlarmA; +voidFuncPtr handlerAlarmB; +voidFuncPtr handlerPeriodicWakeup; + +//----------------------------------------------------------------------------- +void __irq_rtc(void) +{ + rtc_enter_config_mode(); + *bb_perip(&RTC->ISR, RTC_ISR_WUTF_BIT) = 0; + rtc_exit_config_mode(); + EXTI_BASE->PR = EXTI_RTC_WAKEUP; + if (handlerPeriodicWakeup != NULL) { + handlerPeriodicWakeup(); + } +} + +//----------------------------------------------------------------------------- +void __irq_rtcalarm(void) +{ + bool isAlarmA = false; + bool isAlarmB = false; + rtc_enter_config_mode(); + if (RTC->ISR & BIT(RTC_ISR_ALRAF_BIT)) { + isAlarmA = true; + *bb_perip(&RTC->ISR, RTC_ISR_ALRAF_BIT) = 0; + } + if (RTC->ISR & BIT(RTC_ISR_ALRBF_BIT)) { + isAlarmB = true; + *bb_perip(&RTC->ISR, RTC_ISR_ALRBF_BIT) = 0; + } + rtc_exit_config_mode(); + EXTI_BASE->PR = EXTI_RTC_ALARM; + if (isAlarmA && handlerAlarmA != NULL) { + handlerAlarmA(); + } + if (isAlarmB && handlerAlarmB != NULL) { + handlerAlarmB(); + } +} + diff --git a/STM32F4/cores/maple/libmaple/rtc.h b/STM32F4/cores/maple/libmaple/rtc.h new file mode 100644 index 000000000..7af8ee1ab --- /dev/null +++ b/STM32F4/cores/maple/libmaple/rtc.h @@ -0,0 +1,214 @@ + +#ifndef _LIBMAPLE_RTC_H_ +#define _LIBMAPLE_RTC_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +#include // for __time_t_defined +#include +#include +#include + +//#define RTC_DEBUG 1 + + +#if !defined(__time_t_defined) // avoid conflict with newlib or other posix libc + #warning "Using private time_t definintion" + typedef uint32_t time_t; +#endif + + +typedef struct rtc_reg_map { + __IO uint32 TR; /**< Time register */ + __IO uint32 DR; /**< Date register */ + __IO uint32 CR; /**< Control register */ + __IO uint32 ISR; /**< Init Status register */ + __IO uint32 PRER; /**< Prescaler register */ + __IO uint32 WUTR; /**< Wakeup Timer register */ + __IO uint32 CALIBR; /**< Calibration register */ + __IO uint32 ALRMAR; /**< Alarm A register */ + __IO uint32 ALRMBR; /**< Alarm B register */ + __IO uint32 WPR; /**< Write Protect register */ + __IO uint32 SSR; /**< SubSecond register */ + __IO uint32 SHIFTR; /**< Shift Control register */ + __IO uint32 TSTR; /**< TimeStamp Time register */ + __IO uint32 TSDR; /**< TimeStamp Date register */ + __IO uint32 TSSSR; /**< TimeStamp SubSecond register */ + __IO uint32 CALR; /**< Calibration register */ + __IO uint32 TAFCR; /**< Tamper and Alternate Function Config register */ + __IO uint32 ALRMASSR; /**< Alarm A subSecond register */ + __IO uint32 ALRMBSSR; /**< Alarm B subSecond register */ + __IO uint32 BKPxR; /**< Backup registers */ +} rtc_reg_map; + +/** RTC register map base pointer */ +#define RTC ((struct rtc_reg_map*)0x40002800) + +//#define NR_RTC_HANDLERS 4 +//voidFuncPtr rtc_handlers[NR_RTC_HANDLERS]; /**< User IRQ handlers */ + + +/** + * @brief RTC clock source. + * + */ +typedef enum rtc_clk_src { + RTCSEL_NONE = 0, + RTCSEL_LSE = 1, + RTCSEL_LSI = 2, + RTCSEL_HSE = 3, +} rtc_clk_src; + +// Time register +#define RTC_TR_PM_BIT 22 +#define RTC_TR_HOUR_BIT 16 +#define RTC_TR_MINUTE_BIT 8 +#define RTC_TR_SECOND_BIT 0 + +#define RTC_TR_PM_MASK (0x01)//<>4)) + (b&0x0F) ); } +static inline uint8_t bin2bcd(uint8_t b) { return ( ((b/10)<<4) + (b%10) ); } + +#define BUILD_TIME_REGISTER(h, m, s) ( ( bin2bcd((h&RTC_TR_HOUR_MASK)) << RTC_TR_HOUR_BIT ) | \ + ( bin2bcd((m&RTC_TR_MINUTE_MASK)) << RTC_TR_MINUTE_BIT ) | \ + ( bin2bcd((s&RTC_TR_SECOND_MASK)) << RTC_TR_SECOND_BIT) ) + +#define BUILD_DATE_REGISTER(y, m, d, wd) ( ( bin2bcd((y&RTC_DR_YEAR_MASK)) << RTC_DR_YEAR_BIT ) | \ + ( bin2bcd((m&RTC_DR_MONTH_MASK)) << RTC_DR_MONTH_BIT) | \ + ( bin2bcd((d&RTC_DR_DAY_MASK)) << RTC_DR_DAY_BIT ) | \ + ( (wd&RTC_DR_WEEKDAY_MASK) << RTC_DR_WEEKDAY_BIT ) ) + +typedef struct tm_t { + uint8_t year; // years since 1970 + uint8_t month; // month of a year - [ 1 to 12 ] + uint8_t day; // day of a month - [ 1 to 31 ] + uint8_t weekday; // day of a week (first day is Monday) - [ 1 to 7 ] + uint8_t pm; // AM: 0, PM: 1 + uint8_t hour; // hour of a day - [ 0 to 23 ] + uint8_t minute; // minute of an hour - [ 0 to 59 ] + uint8_t second; // second of a minute - [ 0 to 59 ] +} tm_t; + + +void _getTime(tm_t *tm); +void _setTime(tm_t *tm); +void _breakTime(time_t epoch_time, tm_t *tm); +time_t _makeTime(tm_t * tm); + +//----------------------------------------------------------------------------- +uint8_t _year(uint32_t dr) ; +uint8_t _month(uint32_t dr) ; +uint8_t _day(uint32_t dr) ; +uint8_t _weekday(uint32_t dr); +uint8_t _pm(uint32_t tr) ; +uint8_t _hour(uint32_t tr) ; +uint8_t _minute(uint32_t tr) ; +uint8_t _second(uint32_t tr) ; + +//----------------------------------------------------------------------------- +// Clear the register synchronized flag. The flag is then set by hardware after a write to PRL/DIV or CNT. +//----------------------------------------------------------------------------- +static inline void rtc_clear_sync() { + *bb_perip(&RTC->ISR, RTC_ISR_RSF_BIT) = 0; +} + +#if 0 +//----------------------------------------------------------------------------- +// Check (wait if necessary) to see RTC registers are synchronized. +//----------------------------------------------------------------------------- +void rtc_wait_sync() +{ + PRINTF("> rtc_wait_sync\n"); + uint32 t = millis(); + while ( !(RTC->ISR & BIT(RTC_ISR_RSF_BIT)) ) + { + if ( (millis()-t)>1500) { + PRINTF("Sync Timeout ! ISR = %08X\n", RTC->ISR); + break; + } + } + PRINTF("< rtc_wait_sync\n"); +} +#endif + +void rtc_enter_config_mode(); +//----------------------------------------------------------------------------- +// Exit configuration mode. +//----------------------------------------------------------------------------- +static inline void rtc_exit_config_mode() +{ + *bb_perip(&RTC->ISR, RTC_ISR_INIT_BIT) = 0; + interrupts(); + //delayMicroseconds(100); +} + +extern voidFuncPtr handlerAlarmA; +extern voidFuncPtr handlerAlarmB; +extern voidFuncPtr handlerPeriodicWakeup; + +void rtc_enable_alarm_event(); +void rtc_enable_wakeup_event(); +void rtc_disable_wakeup_event(); + + + +#ifdef __cplusplus +} +#endif + +#endif // _LIBMAPLE_RTC_H_ diff --git a/STM32F4/cores/maple/libmaple/scb.h b/STM32F4/cores/maple/libmaple/scb.h index d9cd8c920..b8c46284c 100644 --- a/STM32F4/cores/maple/libmaple/scb.h +++ b/STM32F4/cores/maple/libmaple/scb.h @@ -36,26 +36,26 @@ /** System control block register map type */ typedef struct scb_reg_map { - __io uint32 CPUID; /**< CPU ID Base Register */ - __io uint32 ICSR; /**< Interrupt Control State Register */ - __io uint32 VTOR; /**< Vector Table Offset Register */ - __io uint32 AIRCR; /**< Application Interrupt / Reset Control Register */ - __io uint32 SCR; /**< System Control Register */ - __io uint32 CCR; /**< Configuration Control Register */ - __io uint8 SHP[12]; /**< System Handlers Priority Registers + __IO uint32 CPUID; /**< CPU ID Base Register */ + __IO uint32 ICSR; /**< Interrupt Control State Register */ + __IO uint32 VTOR; /**< Vector Table Offset Register */ + __IO uint32 AIRCR; /**< Application Interrupt / Reset Control Register */ + __IO uint32 SCR; /**< System Control Register */ + __IO uint32 CCR; /**< Configuration Control Register */ + __IO uint8 SHP[12]; /**< System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __io uint32 SHCSR; /**< System Handler Control and State Register */ - __io uint32 CFSR; /**< Configurable Fault Status Register */ - __io uint32 HFSR; /**< Hard Fault Status Register */ - __io uint32 DFSR; /**< Debug Fault Status Register */ - __io uint32 MMFAR; /**< Mem Manage Address Register */ - __io uint32 BFAR; /**< Bus Fault Address Register */ - __io uint32 AFSR; /**< Auxiliary Fault Status Register */ - __io uint32 PFR[2]; /**< Processor Feature Register */ - __io uint32 DFR; /**< Debug Feature Register */ - __io uint32 ADR; /**< Auxiliary Feature Register */ - __io uint32 MMFR[4]; /**< Memory Model Feature Register */ - __io uint32 ISAR[5]; /**< ISA Feature Register */ + __IO uint32 SHCSR; /**< System Handler Control and State Register */ + __IO uint32 CFSR; /**< Configurable Fault Status Register */ + __IO uint32 HFSR; /**< Hard Fault Status Register */ + __IO uint32 DFSR; /**< Debug Fault Status Register */ + __IO uint32 MMFAR; /**< Mem Manage Address Register */ + __IO uint32 BFAR; /**< Bus Fault Address Register */ + __IO uint32 AFSR; /**< Auxiliary Fault Status Register */ + __IO uint32 PFR[2]; /**< Processor Feature Register */ + __IO uint32 DFR; /**< Debug Feature Register */ + __IO uint32 ADR; /**< Auxiliary Feature Register */ + __IO uint32 MMFR[4]; /**< Memory Model Feature Register */ + __IO uint32 ISAR[5]; /**< ISA Feature Register */ } scb_reg_map; /** System control block register map base pointer */ diff --git a/STM32F4/cores/maple/libmaple/sdio.c b/STM32F4/cores/maple/libmaple/sdio.c index 1a9113a7c..b5e5b0235 100644 --- a/STM32F4/cores/maple/libmaple/sdio.c +++ b/STM32F4/cores/maple/libmaple/sdio.c @@ -19,7 +19,7 @@ #include "gpio.h" #include "wirish_time.h" -#if defined(BOARD_generic_f407v) +#ifdef SDIO_D0 sdio_dev * SDIO = SDIO_BASE; @@ -40,12 +40,12 @@ static void sdio_gpios_init(void) gpio_set_mode(BOARD_SDIO_CLK, GPIO_AF_OUTPUT_PP); gpio_set_mode(BOARD_SDIO_CMD, GPIO_AF_OUTPUT_PP_PU); // - gpio_set_af_mode(BOARD_SDIO_D0, 12); - gpio_set_af_mode(BOARD_SDIO_D1, 12); - gpio_set_af_mode(BOARD_SDIO_D2, 12); - gpio_set_af_mode(BOARD_SDIO_D3, 12); - gpio_set_af_mode(BOARD_SDIO_CLK, 12); - gpio_set_af_mode(BOARD_SDIO_CMD, 12); + gpio_set_af_mode(BOARD_SDIO_D0, GPIO_AFMODE_SDIO); + gpio_set_af_mode(BOARD_SDIO_D1, GPIO_AFMODE_SDIO); + gpio_set_af_mode(BOARD_SDIO_D2, GPIO_AFMODE_SDIO); + gpio_set_af_mode(BOARD_SDIO_D3, GPIO_AFMODE_SDIO); + gpio_set_af_mode(BOARD_SDIO_CLK, GPIO_AFMODE_SDIO); + gpio_set_af_mode(BOARD_SDIO_CMD, GPIO_AFMODE_SDIO); } static void sdio_gpios_deinit(void) @@ -57,12 +57,12 @@ static void sdio_gpios_deinit(void) gpio_set_mode(BOARD_SDIO_CLK, GPIO_INPUT_FLOATING); gpio_set_mode(BOARD_SDIO_CMD, GPIO_INPUT_FLOATING); // - gpio_set_af_mode(BOARD_SDIO_D0, 0); - gpio_set_af_mode(BOARD_SDIO_D1, 0); - gpio_set_af_mode(BOARD_SDIO_D2, 0); - gpio_set_af_mode(BOARD_SDIO_D3, 0); - gpio_set_af_mode(BOARD_SDIO_CLK, 0); - gpio_set_af_mode(BOARD_SDIO_CMD, 0); + gpio_set_af_mode(BOARD_SDIO_D0, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(BOARD_SDIO_D1, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(BOARD_SDIO_D2, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(BOARD_SDIO_D3, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(BOARD_SDIO_CLK, GPIO_AFMODE_SYSTEM); + gpio_set_af_mode(BOARD_SDIO_CMD, GPIO_AFMODE_SYSTEM); } /** diff --git a/STM32F4/cores/maple/libmaple/sdio.h b/STM32F4/cores/maple/libmaple/sdio.h index f0afaa163..cdcd3a037 100644 --- a/STM32F4/cores/maple/libmaple/sdio.h +++ b/STM32F4/cores/maple/libmaple/sdio.h @@ -26,7 +26,6 @@ extern "C"{ #endif -#ifdef STM32_HIGH_DENSITY /* * Register maps and devices @@ -34,23 +33,23 @@ extern "C"{ // SDIO register map type typedef struct sdio_reg_map { - __io uint32 POWER; // 0x00 - __io uint32 CLKCR; // 0x04 - __io uint32 ARG; // 0x08 - __io uint32 CMD; // 0x0C - __io uint32 RESPCMD; // 0x10 (0x3F) + __IO uint32 POWER; // 0x00 + __IO uint32 CLKCR; // 0x04 + __IO uint32 ARG; // 0x08 + __IO uint32 CMD; // 0x0C + __IO uint32 RESPCMD; // 0x10 (0x3F) const uint32 RESP[4]; // 0x14 - contain the card status, which is part of the received response. - __io uint32 DTIMER; // 0x24 - contains the data timeout period, in card bus clock periods. - __io uint32 DLEN; // 0x28 (0x01FF FFFF) - contains the number of data bytes to be transferred - __io uint32 DCTRL; // 0x2C - __io uint32 DCOUNT; // 0x30 (0x01FF FFFF) - __io uint32 STA; // 0x34 - __io uint32 ICR; // 0x38 - __io uint32 MASK; // 0x3C + __IO uint32 DTIMER; // 0x24 - contains the data timeout period, in card bus clock periods. + __IO uint32 DLEN; // 0x28 (0x01FF FFFF) - contains the number of data bytes to be transferred + __IO uint32 DCTRL; // 0x2C + __IO uint32 DCOUNT; // 0x30 (0x01FF FFFF) + __IO uint32 STA; // 0x34 + __IO uint32 ICR; // 0x38 + __IO uint32 MASK; // 0x3C const uint32 RESERVED1[2]; - __io uint32 FIFOCNT; // 0x48 (0x01FF FFFF) + __IO uint32 FIFOCNT; // 0x48 (0x01FF FFFF) const uint32 RESERVED2[13]; - __io uint32 FIFO; // 0x80 + __IO uint32 FIFO; // 0x80 } sdio_reg_map; #define sdio_dev sdio_reg_map @@ -241,7 +240,6 @@ inline void sdio_setup_transfer(uint32_t dtimer, uint32_t dlen, uint16_t flags) SDIO->DCTRL = flags;// | SDIO_DCTRL_DTEN; // enable data transfer } -#endif /* STM32_HIGH_DENSITY */ #ifdef __cplusplus } /* extern "C" */ diff --git a/STM32F4/cores/maple/libmaple/spi.c b/STM32F4/cores/maple/libmaple/spi.c index 4b274cb37..a2973cf27 100644 --- a/STM32F4/cores/maple/libmaple/spi.c +++ b/STM32F4/cores/maple/libmaple/spi.c @@ -90,17 +90,17 @@ void spi_slave_enable(spi_dev *dev, spi_mode mode, uint32 flags) { * correctly treated as 8-bit or 16-bit quantities). * @param len Maximum number of elements to transmit. */ -void spi_tx(spi_dev *dev, void *buf, uint32 len) +void spi_tx(spi_dev *dev, const void *buf, uint32 len) { spi_reg_map *regs = dev->regs; if ( spi_dff(dev) == SPI_DFF_8_BIT ) { - uint8 * dp8 = (uint8*)buf; + const uint8 * dp8 = (const uint8*)buf; while ( len-- ) { while ( (regs->SR & SPI_SR_TXE)==0 ) ; //while ( spi_is_tx_empty(dev)==0 ); // wait Tx to be empty regs->DR = *dp8++; } } else { - uint16 * dp16 = (uint16*)buf; + const uint16 * dp16 = (const uint16*)buf; while ( len-- ) { while ( (regs->SR & SPI_SR_TXE)==0 ) ; //while ( spi_is_tx_empty(dev)==0 ); // wait Tx to be empty regs->DR = *dp16++; diff --git a/STM32F4/cores/maple/libmaple/spi.h b/STM32F4/cores/maple/libmaple/spi.h index abed68c12..c264c97bb 100644 --- a/STM32F4/cores/maple/libmaple/spi.h +++ b/STM32F4/cores/maple/libmaple/spi.h @@ -53,15 +53,15 @@ extern "C" { /** SPI register map type. */ typedef struct spi_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SR; /**< Status register */ - __io uint32 DR; /**< Data register */ - __io uint32 CRCPR; /**< CRC polynomial register */ - __io uint32 RXCRCR; /**< RX CRC register */ - __io uint32 TXCRCR; /**< TX CRC register */ - __io uint32 I2SCFGR; /**< I2S configuration register */ - __io uint32 I2SPR; /**< I2S prescaler register */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ + __IO uint32 SR; /**< Status register */ + __IO uint32 DR; /**< Data register */ + __IO uint32 CRCPR; /**< CRC polynomial register */ + __IO uint32 RXCRCR; /**< RX CRC register */ + __IO uint32 TXCRCR; /**< TX CRC register */ + __IO uint32 I2SCFGR; /**< I2S configuration register */ + __IO uint32 I2SPR; /**< I2S prescaler register */ } spi_reg_map; /* @@ -207,6 +207,13 @@ typedef struct spi_dev { nvic_irq_num irq_num; /**< NVIC interrupt number */ } spi_dev; +typedef struct { + uint8 nss; + uint8 sck; + uint8 miso; + uint8 mosi; +} spi_pins_t; // __attribute((alligned(4))); + /* * SPI Convenience functions */ @@ -218,17 +225,11 @@ void spi_init(spi_dev *dev); * * @param dev SPI device * @param as_master If true, configure as bus master; otherwise, as slave. - * @param nss_bit NSS pin's GPIO bit on nss_dev - * @param sck_bit SCK pin's GPIO bit on comm_dev - * @param miso_bit MISO pin's GPIO bit on comm_dev - * @param mosi_bit MOSI pin's GPIO bit on comm_dev + * @param pins pointer to GPIO pin collection */ extern void spi_config_gpios(spi_dev *dev, uint8 as_master, - uint8 nss_pin, - uint8 sck_pin, - uint8 miso_pin, - uint8 mosi_pin); + const spi_pins_t *pins); /** * @brief SPI mode configuration. @@ -303,7 +304,7 @@ void spi_slave_enable(spi_dev *dev, spi_mode mode, uint32 flags); -void spi_tx(spi_dev *dev, void *buf, uint32 len); +void spi_tx(spi_dev *dev, const void *buf, uint32 len); /** * @brief Call a function on each SPI port diff --git a/STM32F4/cores/maple/libmaple/spiF4.h b/STM32F4/cores/maple/libmaple/spiF4.h index cbdc91a73..c4e6ccedd 100644 --- a/STM32F4/cores/maple/libmaple/spiF4.h +++ b/STM32F4/cores/maple/libmaple/spiF4.h @@ -50,16 +50,29 @@ struct spi_reg_map; #define SPI2_BASE ((struct spi_reg_map*)0x40003800) #define SPI3_BASE ((struct spi_reg_map*)0x40003C00) +#define SPI4_BASE ((struct spi_reg_map*)0x40013400) +#define SPI5_BASE ((struct spi_reg_map*)0x40015000) + /* * Device pointers */ struct spi_dev; -extern struct spi_dev *SPI1; -extern struct spi_dev *SPI2; -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) -extern struct spi_dev *SPI3; +extern struct spi_dev spi1; +extern struct spi_dev spi2; +extern struct spi_dev spi3; +#define SPI1 (&spi1) +#define SPI2 (&spi2) +#define SPI3 (&spi3) + +#if BOARD_NR_SPI>3 +extern struct spi_dev spi4; +#define SPI4 (&spi4) +#endif +#if BOARD_NR_SPI>4 +extern struct spi_dev spi5; +#define SPI5 (&spi5) #endif diff --git a/STM32F4/cores/maple/libmaple/spi_f4.c b/STM32F4/cores/maple/libmaple/spi_f4.c index f52853e0c..3a8569bd4 100644 --- a/STM32F4/cores/maple/libmaple/spi_f4.c +++ b/STM32F4/cores/maple/libmaple/spi_f4.c @@ -33,22 +33,27 @@ #include #include -#include "spi_private.h" /* * Devices */ +#define SPI_DEV(num) \ + { \ + .regs = SPI##num##_BASE, \ + .clk_id = RCC_SPI##num, \ + .irq_num = NVIC_SPI##num, \ + } -static spi_dev spi1 = SPI_DEV(1); -static spi_dev spi2 = SPI_DEV(2); - -spi_dev *SPI1 = &spi1; -spi_dev *SPI2 = &spi2; - -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) -static spi_dev spi3 = SPI_DEV(3); -spi_dev *SPI3 = &spi3; +spi_dev spi1 = SPI_DEV(1); +spi_dev spi2 = SPI_DEV(2); +spi_dev spi3 = SPI_DEV(3); +#if BOARD_NR_SPI>3 +spi_dev spi4 = SPI_DEV(4); #endif +#if BOARD_NR_SPI>4 +spi_dev spi5 = SPI_DEV(5); +#endif + /* * Routines @@ -56,35 +61,30 @@ spi_dev *SPI3 = &spi3; void spi_config_gpios(spi_dev *dev, uint8 as_master, - uint8 nss_pin, - uint8 sck_pin, - uint8 miso_pin, - uint8 mosi_pin) { + const spi_pins_t *pins) { if (as_master) { - gpio_set_mode(sck_pin, GPIO_AF_OUTPUT_PP); - gpio_set_mode(miso_pin, GPIO_AF_INPUT_PD); - gpio_set_mode(mosi_pin, GPIO_AF_OUTPUT_PP); + gpio_set_mode(pins->sck, GPIO_AF_OUTPUT_PP); + gpio_set_mode(pins->miso, GPIO_AF_INPUT_PD); + gpio_set_mode(pins->mosi, GPIO_AF_OUTPUT_PP); } else { - gpio_set_mode(nss_pin, GPIO_INPUT_FLOATING); - gpio_set_mode(sck_pin, GPIO_INPUT_FLOATING); - gpio_set_mode(miso_pin, GPIO_AF_OUTPUT_PP); - gpio_set_mode(mosi_pin, GPIO_INPUT_FLOATING); + gpio_set_mode(pins->nss, GPIO_INPUT_FLOATING); + gpio_set_mode(pins->sck, GPIO_INPUT_FLOATING); + gpio_set_mode(pins->miso, GPIO_AF_OUTPUT_PP); + gpio_set_mode(pins->mosi, GPIO_INPUT_FLOATING); } - uint8_t af_mode = 6; - if(dev->clk_id <= RCC_SPI2) { af_mode = 5; } - if(!as_master) { - gpio_set_af_mode(nss_pin, af_mode); + gpio_af_mode af_mode = GPIO_AFMODE_SPI1_4; + if ((dev->clk_id == RCC_SPI5) || (dev->clk_id == RCC_SPI3)) { af_mode = GPIO_AFMODE_SPI3_5; } + if (!as_master) { + gpio_set_af_mode(pins->nss, af_mode); } - gpio_set_af_mode(sck_pin, af_mode); - gpio_set_af_mode(miso_pin, af_mode); - gpio_set_af_mode(mosi_pin, af_mode); + gpio_set_af_mode(pins->sck, af_mode); + gpio_set_af_mode(pins->miso, af_mode); + gpio_set_af_mode(pins->mosi, af_mode); } void spi_foreach(void (*fn)(spi_dev*)) { fn(SPI1); fn(SPI2); -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) fn(SPI3); -#endif } diff --git a/STM32F4/cores/maple/libmaple/spi_private.h b/STM32F4/cores/maple/libmaple/spi_private.h deleted file mode 100644 index f0e0bd10f..000000000 --- a/STM32F4/cores/maple/libmaple/spi_private.h +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2012 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#ifndef _LIBMAPLE_SPI_PRIVATE_H_ -#define _LIBMAPLE_SPI_PRIVATE_H_ - -#define SPI_DEV(num) \ - { \ - .regs = SPI##num##_BASE, \ - .clk_id = RCC_SPI##num, \ - .irq_num = NVIC_SPI##num, \ - } - -#endif diff --git a/STM32F4/variants/discovery_f407/wirish/start.S b/STM32F4/cores/maple/libmaple/start.S similarity index 100% rename from STM32F4/variants/discovery_f407/wirish/start.S rename to STM32F4/cores/maple/libmaple/start.S diff --git a/STM32F4/variants/generic_f407v/wirish/start_c.c b/STM32F4/cores/maple/libmaple/start_c.c similarity index 90% rename from STM32F4/variants/generic_f407v/wirish/start_c.c rename to STM32F4/cores/maple/libmaple/start_c.c index 655fefb88..69269a67d 100644 --- a/STM32F4/variants/generic_f407v/wirish/start_c.c +++ b/STM32F4/cores/maple/libmaple/start_c.c @@ -56,6 +56,7 @@ extern char __bss_start__, __bss_end__; struct rom_img_cfg { int *img_start; + int *ccmimg_start; }; extern char _lm_rom_img_cfgp; @@ -73,7 +74,17 @@ void __attribute__((noreturn)) start_c(void) { *dst++ = *src++; } } - +#ifdef __CCMRAM__ +extern char __ccmdata_start__, __ccmdata_end__; + /* Initialize .ccm, if necessary. */ + src = img_cfg->ccmimg_start; + dst = (int*)&__ccmdata_start__; + if (src != dst) { + while (dst < (int*)&__ccmdata_end__) { + *dst++ = *src++; + } + } +#endif /* Zero .bss. */ dst = (int*)&__bss_start__; while (dst < (int*)&__bss_end__) { diff --git a/STM32F4/cores/maple/libmaple/stm32.h b/STM32F4/cores/maple/libmaple/stm32.h index 3921788e7..e9a48312a 100644 --- a/STM32F4/cores/maple/libmaple/stm32.h +++ b/STM32F4/cores/maple/libmaple/stm32.h @@ -54,25 +54,6 @@ #endif -#ifndef STM32_PCLK1 -#define STM32_PCLK1 36000000U -#endif -#ifndef PCLK1 -#define PCLK1 STM32_PCLK1 -#endif -#if PCLK1 != STM32_PCLK1 -#error "(Deprecated) PCLK1 differs from STM32_PCLK1" -#endif - -#ifndef STM32_PCLK2 -#define STM32_PCLK2 72000000U -#endif -#ifndef PCLK2 -#define PCLK2 STM32_PCLK2 -#endif -#if PCLK2 != STM32_PCLK2 -#error "(Deprecated) PCLK2 differs from STM32_PCLK2" -#endif /* * Density-specific configuration. @@ -82,10 +63,6 @@ /** * @brief Number of interrupts in the NVIC. - * - * This define is automatically generated whenever the proper - * density is defined (currently, this is restricted to defining - * one of STM32_MEDIUM_DENSITY and STM32_HIGH_DENSITY). */ #define STM32_NR_INTERRUPTS @@ -94,15 +71,6 @@ #endif -#ifdef STM32_MEDIUM_DENSITY - #define STM32_NR_INTERRUPTS 43 -#elif defined(STM32_HIGH_DENSITY) - #define STM32_NR_INTERRUPTS 60 -#else -#error "No STM32 board type defined!" -#endif - -#define NR_INTERRUPTS STM32_NR_INTERRUPTS /* * MCU-specific configuration. @@ -138,22 +106,22 @@ #endif - -#if defined( STM32F4 ) - #define STM32_TICKS_PER_US 168 - #define STM32_NR_GPIO_PORTS 5 - #define STM32_DELAY_US_MULT (STM32_TICKS_PER_US/3) - #define STM32_SRAM_END ((void*)0x20010000) - //#define STM32_SRAM_END ((void*)0x20030000) - - #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS - #define DELAY_US_MULT STM32_DELAY_US_MULT - -#else - -#error "No MCU type specified. Add something like -DMCU_STM32F103RB " \ - "to your compiler arguments (probably in a Makefile)." - -#endif - +#include + + #undef STM32_PCLK1 + #undef STM32_PCLK2 + #define STM32_PCLK1 (CLOCK_SPEED_HZ/4) + #define STM32_PCLK2 (CLOCK_SPEED_HZ/2) + + #define SYSTICK_RELOAD_VAL (CYCLES_PER_MICROSECOND*1000-1) + + #define STM32_NR_GPIO_PORTS 5 + #define STM32_DELAY_US_MULT (CYCLES_PER_MICROSECOND/3) + #define STM32_SRAM_END ((void*)0x20010000) + //#define STM32_SRAM_END ((void*)0x20030000) + + #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS + #define DELAY_US_MULT STM32_DELAY_US_MULT + + #endif /* _STM32_H_ */ diff --git a/STM32F4/cores/maple/libmaple/stm32_isrs.S b/STM32F4/cores/maple/libmaple/stm32_isrs.S new file mode 100644 index 000000000..32a34ad82 --- /dev/null +++ b/STM32F4/cores/maple/libmaple/stm32_isrs.S @@ -0,0 +1,299 @@ +/* STM32 ISR weak declarations */ + + .thumb + +/* Default handler for all non-overridden interrupts and exceptions */ + .globl __default_handler + .type __default_handler, %function + +__default_handler: + b . + + .weak __exc_nmi + .globl __exc_nmi + .set __exc_nmi, __default_handler + .weak __exc_hardfault + .globl __exc_hardfault + .set __exc_hardfault, __default_handler + .weak __exc_memmanage + .globl __exc_memmanage + .set __exc_memmanage, __default_handler + .weak __exc_busfault + .globl __exc_busfault + .set __exc_busfault, __default_handler + .weak __exc_usagefault + .globl __exc_usagefault + .set __exc_usagefault, __default_handler + .weak __stm32reservedexception7 + .globl __stm32reservedexception7 + .set __stm32reservedexception7, __default_handler + .weak __stm32reservedexception8 + .globl __stm32reservedexception8 + .set __stm32reservedexception8, __default_handler + .weak __stm32reservedexception9 + .globl __stm32reservedexception9 + .set __stm32reservedexception9, __default_handler + .weak __stm32reservedexception10 + .globl __stm32reservedexception10 + .set __stm32reservedexception10, __default_handler + .weak __exc_svc + .globl __exc_svc + .set __exc_svc, __default_handler + .weak __exc_debug_monitor + .globl __exc_debug_monitor + .set __exc_debug_monitor, __default_handler + .weak __stm32reservedexception13 + .globl __stm32reservedexception13 + .set __stm32reservedexception13, __default_handler + .weak __exc_pendsv + .globl __exc_pendsv + .set __exc_pendsv, __default_handler + .weak __exc_systick + .globl __exc_systick + .set __exc_systick, __default_handler + .weak __irq_wwdg + .globl __irq_wwdg + .set __irq_wwdg, __default_handler + .weak __irq_pvd + .globl __irq_pvd + .set __irq_pvd, __default_handler + .weak __irq_tamper + .globl __irq_tamper + .set __irq_tamper, __default_handler + .weak __irq_rtc + .globl __irq_rtc + .set __irq_rtc, __default_handler + .weak __irq_flash + .globl __irq_flash + .set __irq_flash, __default_handler + .weak __irq_rcc + .globl __irq_rcc + .set __irq_rcc, __default_handler + .weak __irq_exti0 + .globl __irq_exti0 + .set __irq_exti0, __default_handler + .weak __irq_exti1 + .globl __irq_exti1 + .set __irq_exti1, __default_handler + .weak __irq_exti2 + .globl __irq_exti2 + .set __irq_exti2, __default_handler + .weak __irq_exti3 + .globl __irq_exti3 + .set __irq_exti3, __default_handler + .weak __irq_exti4 + .globl __irq_exti4 + .set __irq_exti4, __default_handler + .weak __irq_dma1_stream0 + .globl __irq_dma1_stream0 + .set __irq_dma1_stream0, __default_handler + .weak __irq_dma1_stream1 + .globl __irq_dma1_stream1 + .set __irq_dma1_stream1, __default_handler + .weak __irq_dma1_stream2 + .globl __irq_dma1_stream2 + .set __irq_dma1_stream2, __default_handler + .weak __irq_dma1_stream3 + .globl __irq_dma1_stream3 + .set __irq_dma1_stream3, __default_handler + .weak __irq_dma1_stream4 + .globl __irq_dma1_stream4 + .set __irq_dma1_stream4, __default_handler + .weak __irq_dma1_stream5 + .globl __irq_dma1_stream5 + .set __irq_dma1_stream5, __default_handler + .weak __irq_dma1_stream6 + .globl __irq_dma1_stream6 + .set __irq_dma1_stream6, __default_handler + .weak __irq_adc + .globl __irq_adc + .set __irq_adc, __default_handler + .weak __irq_can1_tx + .globl __irq_can1_tx + .set __irq_can1_tx, __default_handler + .weak __irq_can1_rx0 + .globl __irq_can1_rx0 + .set __irq_can1_rx0, __default_handler + .weak __irq_can1_rx1 + .globl __irq_can1_rx1 + .set __irq_can1_rx1, __default_handler + .weak __irq_can1_sce + .globl __irq_can1_sce + .set __irq_can1_sce, __default_handler + .weak __irq_exti9_5 + .globl __irq_exti9_5 + .set __irq_exti9_5, __default_handler + .weak __irq_tim1_brk + .globl __irq_tim1_brk + .set __irq_tim1_brk, __default_handler + .weak __irq_tim1_up + .globl __irq_tim1_up + .set __irq_tim1_up, __default_handler + .weak __irq_tim1_trg_com + .globl __irq_tim1_trg_com + .set __irq_tim1_trg_com, __default_handler + .weak __irq_tim1_cc + .globl __irq_tim1_cc + .set __irq_tim1_cc, __default_handler + .weak __irq_tim2 + .globl __irq_tim2 + .set __irq_tim2, __default_handler + .weak __irq_tim3 + .globl __irq_tim3 + .set __irq_tim3, __default_handler + .weak __irq_tim4 + .globl __irq_tim4 + .set __irq_tim4, __default_handler + .weak __irq_i2c1_ev + .globl __irq_i2c1_ev + .set __irq_i2c1_ev, __default_handler + .weak __irq_i2c1_er + .globl __irq_i2c1_er + .set __irq_i2c1_er, __default_handler + .weak __irq_i2c2_ev + .globl __irq_i2c2_ev + .set __irq_i2c2_ev, __default_handler + .weak __irq_i2c2_er + .globl __irq_i2c2_er + .set __irq_i2c2_er, __default_handler + .weak __irq_spi1 + .globl __irq_spi1 + .set __irq_spi1, __default_handler + .weak __irq_spi2 + .globl __irq_spi2 + .set __irq_spi2, __default_handler + .weak __irq_usart1 + .globl __irq_usart1 + .set __irq_usart1, __default_handler + .weak __irq_usart2 + .globl __irq_usart2 + .set __irq_usart2, __default_handler + .weak __irq_usart3 + .globl __irq_usart3 + .set __irq_usart3, __default_handler + .weak __irq_exti15_10 + .globl __irq_exti15_10 + .set __irq_exti15_10, __default_handler + .weak __irq_rtcalarm + .globl __irq_rtcalarm + .set __irq_rtcalarm, __default_handler + .weak __irq_usbwakeup + .globl __irq_usbwakeup + .set __irq_usbwakeup, __default_handler + .weak __irq_tim8_brk + .globl __irq_tim8_brk + .set __irq_tim8_brk, __default_handler + .weak __irq_tim8_up + .globl __irq_tim8_up + .set __irq_tim8_up, __default_handler + .weak __irq_tim8_trg_com + .globl __irq_tim8_trg_com + .set __irq_tim8_trg_com, __default_handler + .weak __irq_tim8_cc + .globl __irq_tim8_cc + .set __irq_tim8_cc, __default_handler + .weak __irq_dma1_stream7 + .globl __irq_dma1_stream7 + .set __irq_dma1_stream7, __default_handler + .weak __irq_fsmc + .globl __irq_fsmc + .set __irq_fsmc, __default_handler + .weak __irq_sdio + .globl __irq_sdio + .set __irq_sdio, __default_handler + .weak __irq_tim5 + .globl __irq_tim5 + .set __irq_tim5, __default_handler + .weak __irq_spi3 + .globl __irq_spi3 + .set __irq_spi3, __default_handler + .weak __irq_uart4 + .globl __irq_uart4 + .set __irq_uart4, __default_handler + .weak __irq_uart5 + .globl __irq_uart5 + .set __irq_uart5, __default_handler + .weak __irq_tim6_dac + .globl __irq_tim6_dac + .set __irq_tim6_dac, __default_handler + .weak __irq_tim7 + .globl __irq_tim7 + .set __irq_tim7, __default_handler + .weak __irq_dma2_stream0 + .globl __irq_dma2_stream0 + .set __irq_dma2_stream0, __default_handler + .weak __irq_dma2_stream1 + .globl __irq_dma2_stream1 + .set __irq_dma2_stream1, __default_handler + .weak __irq_dma2_stream2 + .globl __irq_dma2_stream2 + .set __irq_dma2_stream2, __default_handler + .weak __irq_dma2_stream3 + .globl __irq_dma2_stream3 + .set __irq_dma2_stream3, __default_handler + .weak __irq_dma2_stream4 + .globl __irq_dma2_stream4 + .set __irq_dma2_stream4, __default_handler + .weak __irq_eth + .globl __irq_eth + .set __irq_eth, __default_handler + .weak __irq_eth_wkup + .globl __irq_eth_wkup + .set __irq_eth_wkup, __default_handler + .weak __irq_can2_tx + .globl __irq_can2_tx + .set __irq_can2_tx, __default_handler + .weak __irq_can2_rx0 + .globl __irq_can2_rx0 + .set __irq_can2_rx0, __default_handler + .weak __irq_can2_rx1 + .globl __irq_can2_rx1 + .set __irq_can2_rx1, __default_handler + .weak __irq_can2_sce + .globl __irq_can2_sce + .set __irq_can2_sce, __default_handler + .weak __irq_usb_fs + .globl __irq_usb_fs + .set __irq_usb_fs, __default_handler + .weak __irq_dma2_stream5 + .globl __irq_dma2_stream5 + .set __irq_dma2_stream5, __default_handler + .weak __irq_dma2_stream6 + .globl __irq_dma2_stream6 + .set __irq_dma2_stream6, __default_handler + .weak __irq_dma2_stream7 + .globl __irq_dma2_stream7 + .set __irq_dma2_stream7, __default_handler + .weak __irq_usart6 + .globl __irq_usart6 + .set __irq_usart6, __default_handler + .weak __irq_i2c3_ev + .globl __irq_i2c3_ev + .set __irq_i2c3_ev, __default_handler + .weak __irq_i2c3_er + .globl __irq_i2c3_er + .set __irq_i2c3_er, __default_handler + .weak __irq_usb_hs_ep1_out + .globl __irq_usb_hs_ep1_out + .set __irq_usb_hs_ep1_out, __default_handler + .weak __irq_usb_hs_ep1_in + .globl __irq_usb_hs_ep1_in + .set __irq_usb_hs_ep1_in, __default_handler + .weak __irq_usb_hs_wkup + .globl __irq_usb_hs_wkup + .set __irq_usb_hs_wkup, __default_handler + .weak __irq_usb_hs + .globl __irq_usb_hs + .set __irq_usb_hs, __default_handler + .weak __irq_dcmi + .globl __irq_dcmi + .set __irq_dcmi, __default_handler + .weak __irq_cryp + .globl __irq_cryp + .set __irq_cryp, __default_handler + .weak __irq_hash_rng + .globl __irq_hash_rng + .set __irq_hash_rng, __default_handler + .weak __irq_fpu + .globl __irq_fpu + .set __irq_fpu, __default_handler diff --git a/STM32F4/cores/maple/libmaple/stm32_vector_table.S b/STM32F4/cores/maple/libmaple/stm32_vector_table.S new file mode 100644 index 000000000..e3799fe26 --- /dev/null +++ b/STM32F4/cores/maple/libmaple/stm32_vector_table.S @@ -0,0 +1,110 @@ +/* STM32 vector table */ + + .section ".stm32.interrupt_vector" + + .globl __stm32_vector_table + .type __stm32_vector_table, %object + +__stm32_vector_table: +/* CM3 core interrupts */ + .long __msp_init + .long __exc_reset + .long __exc_nmi + .long __exc_hardfault + .long __exc_memmanage + .long __exc_busfault + .long __exc_usagefault + .long __stm32reservedexception7 + .long __stm32reservedexception8 + .long __stm32reservedexception9 + .long __stm32reservedexception10 + .long __exc_svc + .long __exc_debug_monitor + .long __stm32reservedexception13 + .long __exc_pendsv + .long __exc_systick +/* Peripheral interrupts */ + .long __irq_wwdg + .long __irq_pvd + .long __irq_tamper + .long __irq_rtc + .long __irq_flash + .long __irq_rcc + .long __irq_exti0 + .long __irq_exti1 + .long __irq_exti2 + .long __irq_exti3 + .long __irq_exti4 + .long __irq_dma1_stream0 + .long __irq_dma1_stream1 + .long __irq_dma1_stream2 + .long __irq_dma1_stream3 + .long __irq_dma1_stream4 + .long __irq_dma1_stream5 + .long __irq_dma1_stream6 + .long __irq_adc + .long __irq_can1_tx + .long __irq_can1_rx0 + .long __irq_can1_rx1 + .long __irq_can1_sce + .long __irq_exti9_5 + .long __irq_tim1_brk + .long __irq_tim1_up + .long __irq_tim1_trg_com + .long __irq_tim1_cc + .long __irq_tim2 + .long __irq_tim3 + .long __irq_tim4 + .long __irq_i2c1_ev + .long __irq_i2c1_er + .long __irq_i2c2_ev + .long __irq_i2c2_er + .long __irq_spi1 + .long __irq_spi2 + .long __irq_usart1 + .long __irq_usart2 + .long __irq_usart3 + .long __irq_exti15_10 + .long __irq_rtcalarm + .long __irq_usbwakeup + .long __irq_tim8_brk + .long __irq_tim8_up + .long __irq_tim8_trg_com + .long __irq_tim8_cc + .long __irq_dma1_stream7 + .long __irq_fsmc + .long __irq_sdio + .long __irq_tim5 + .long __irq_spi3 + .long __irq_uart4 + .long __irq_uart5 + .long __irq_tim6_dac + .long __irq_tim7 + .long __irq_dma2_stream0 + .long __irq_dma2_stream1 + .long __irq_dma2_stream2 + .long __irq_dma2_stream3 + .long __irq_dma2_stream4 + .long __irq_eth + .long __irq_eth_wkup + .long __irq_can2_tx + .long __irq_can2_rx0 + .long __irq_can2_rx1 + .long __irq_can2_sce + .long __irq_usb_fs + .long __irq_dma2_stream5 + .long __irq_dma2_stream6 + .long __irq_dma2_stream7 + .long __irq_usart6 + .long __irq_i2c3_ev + .long __irq_i2c3_er + .long __irq_usb_hs_ep1_out + .long __irq_usb_hs_ep1_in + .long __irq_usb_hs_wkup + .long __irq_usb_hs + .long __irq_dcmi + .long __irq_cryp + .long __irq_hash_rng + .long __irq_fpu + + .size __stm32_vector_table, . - __stm32_vector_table diff --git a/STM32F4/cores/maple/libmaple/systick.c b/STM32F4/cores/maple/libmaple/systick.c index dbe773ce0..6385e050c 100644 --- a/STM32F4/cores/maple/libmaple/systick.c +++ b/STM32F4/cores/maple/libmaple/systick.c @@ -34,6 +34,8 @@ volatile uint32 systick_uptime_millis; static void (*systick_user_callback)(void); +systick_reg_map * const SYSTICK = SYSTICK_BASE; + /** * @brief Initialize and enable SysTick. * @@ -43,7 +45,7 @@ static void (*systick_user_callback)(void); * @param reload_val Appropriate reload counter to tick every 1 ms. */ void systick_init(uint32 reload_val) { - SYSTICK_BASE->RVR = reload_val; + SYSTICK->LOAD = reload_val; systick_enable(); } @@ -52,7 +54,7 @@ void systick_init(uint32 reload_val) { * on or enable interrupt. */ void systick_disable() { - SYSTICK_BASE->CSR = SYSTICK_CSR_CLKSOURCE_CORE; + SYSTICK->CTRL = SYSTICK_CTRL_CLKSOURCE_CORE; } /** @@ -61,9 +63,9 @@ void systick_disable() { */ void systick_enable() { /* re-enables init registers without changing reload val */ - SYSTICK_BASE->CSR = (SYSTICK_CSR_CLKSOURCE_CORE | - SYSTICK_CSR_ENABLE | - SYSTICK_CSR_TICKINT_PEND); + SYSTICK->CTRL = (SYSTICK_CTRL_CLKSOURCE_CORE | + SYSTICK_CTRL_ENABLE | + SYSTICK_CTRL_TICKINT_PENDING); } /** diff --git a/STM32F4/cores/maple/libmaple/systick.h b/STM32F4/cores/maple/libmaple/systick.h index 6ec33644c..d4e83a500 100644 --- a/STM32F4/cores/maple/libmaple/systick.h +++ b/STM32F4/cores/maple/libmaple/systick.h @@ -42,12 +42,14 @@ extern "C"{ /** SysTick register map type */ typedef struct systick_reg_map { - __io uint32 CSR; /**< Control and status register */ - __io uint32 RVR; /**< Reload value register */ - __io uint32 CNT; /**< Current value register ("count") */ - __io uint32 CVR; /**< Calibration value register */ + __IO uint32 CTRL; /**< Control and status register */ + __IO uint32 LOAD; /**< Reload value register */ + __IO uint32 VAL; /**< Current value register ("count") */ + __IO uint32 CALIB; /**< Calibration value register */ } systick_reg_map; +extern systick_reg_map * const SYSTICK; + /** SysTick register map base pointer */ #define SYSTICK_BASE ((struct systick_reg_map*)0xE000E010) @@ -57,26 +59,28 @@ typedef struct systick_reg_map { /* Control and status register */ -#define SYSTICK_CSR_COUNTFLAG BIT(16) -#define SYSTICK_CSR_CLKSOURCE BIT(2) -#define SYSTICK_CSR_CLKSOURCE_EXTERNAL 0 -#define SYSTICK_CSR_CLKSOURCE_CORE BIT(2) -#define SYSTICK_CSR_TICKINT BIT(1) -#define SYSTICK_CSR_TICKINT_PEND BIT(1) -#define SYSTICK_CSR_TICKINT_NO_PEND 0 -#define SYSTICK_CSR_ENABLE BIT(0) -#define SYSTICK_CSR_ENABLE_MULTISHOT BIT(0) -#define SYSTICK_CSR_ENABLE_DISABLED 0 +#define SYSTICK_CTRL_COUNTFLAG BIT(16) +#define SYSTICK_CTRL_CLKSOURCE BIT(2) +#define SYSTICK_CTRL_CLKSOURCE_CORE BIT(2) +#define SYSTICK_CTRL_TICKINT BIT(1) +#define SYSTICK_CTRL_TICKINT_PENDING BIT(1) +#define SYSTICK_CTRL_ENABLE BIT(0) /* Calibration value register */ -#define SYSTICK_CVR_NOREF BIT(31) -#define SYSTICK_CVR_SKEW BIT(30) -#define SYSTICK_CVR_TENMS 0xFFFFFF +#define SYSTICK_CALIB_NOREF BIT(31) +#define SYSTICK_CALIB_SKEW BIT(30) +#define SYSTICK_CALIB_TENMS 0xFFFFFF /** System elapsed time, in milliseconds */ extern volatile uint32 systick_uptime_millis; + +void systick_init(uint32 reload_val); +void systick_disable(); +void systick_enable(); +void systick_attach_callback(void (*callback)(void)); + /** * @brief Returns the system uptime, in milliseconds. */ @@ -84,16 +88,11 @@ static inline uint32 systick_uptime(void) { return systick_uptime_millis; } - -void systick_init(uint32 reload_val); -void systick_disable(); -void systick_enable(); - /** * @brief Returns the current value of the SysTick counter. */ static inline uint32 systick_get_count(void) { - return SYSTICK_BASE->CNT; + return SYSTICK->VAL; } /** @@ -106,7 +105,7 @@ static inline uint32 systick_get_count(void) { * Reference Manual for more details (e.g. Table 8-3 in revision r1p1). */ static inline uint32 systick_check_underflow(void) { - return SYSTICK_BASE->CSR & SYSTICK_CSR_COUNTFLAG; + return SYSTICK->CTRL & SYSTICK_CTRL_COUNTFLAG; } #ifdef __cplusplus diff --git a/STM32F4/cores/maple/libmaple/timer.c b/STM32F4/cores/maple/libmaple/timer.c index f8e55a185..53eac507c 100644 --- a/STM32F4/cores/maple/libmaple/timer.c +++ b/STM32F4/cores/maple/libmaple/timer.c @@ -44,95 +44,162 @@ /* Update only. */ #define NR_BAS_HANDLERS 1 -timer_dev timer1 = { +/** Timer 1 device (advanced) */ +voidFuncPtr timer1_handlers[] = { [NR_ADV_HANDLERS - 1] = 0 }; +const timer_dev timer1 = { .regs = { .adv = TIMER1_BASE }, .clk_id = RCC_TIMER1, .type = TIMER_ADVANCED, - .handlers = { [NR_ADV_HANDLERS - 1] = 0 }, + .af_mode = GPIO_AFMODE_TIM1_2, + .handler_p = &timer1_handlers, }; -/** Timer 1 device (advanced) */ -timer_dev *TIMER1 = &timer1; -timer_dev timer2 = { +/** Timer 2 device (general-purpose) */ +voidFuncPtr timer2_handlers[] = { [NR_GEN_HANDLERS - 1] = 0 }; +const timer_dev timer2 = { .regs = { .gen = TIMER2_BASE }, .clk_id = RCC_TIMER2, .type = TIMER_GENERAL, - .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, + .af_mode = GPIO_AFMODE_TIM1_2, + .handler_p = &timer2_handlers, }; -/** Timer 2 device (general-purpose) */ -timer_dev *TIMER2 = &timer2; -timer_dev timer3 = { +/** Timer 3 device (general-purpose) */ +voidFuncPtr timer3_handlers[] = { [NR_GEN_HANDLERS - 1] = 0 }; +const timer_dev timer3 = { .regs = { .gen = TIMER3_BASE }, .clk_id = RCC_TIMER3, .type = TIMER_GENERAL, - .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, + .af_mode = GPIO_AFMODE_TIM3_5, + .handler_p = &timer3_handlers, }; -/** Timer 3 device (general-purpose) */ -timer_dev *TIMER3 = &timer3; -timer_dev timer4 = { +/** Timer 4 device (general-purpose) */ +voidFuncPtr timer4_handlers[] = { [NR_GEN_HANDLERS - 1] = 0 }; +const timer_dev timer4 = { .regs = { .gen = TIMER4_BASE }, .clk_id = RCC_TIMER4, .type = TIMER_GENERAL, - .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, + .af_mode = GPIO_AFMODE_TIM3_5, + .handler_p = &timer4_handlers, }; -/** Timer 4 device (general-purpose) */ -timer_dev *TIMER4 = &timer4; -#ifdef STM32_HIGH_DENSITY -timer_dev timer5 = { +/** Timer 5 device (general-purpose) */ +voidFuncPtr timer5_handlers[] = { [NR_GEN_HANDLERS - 1] = 0 }; +const timer_dev timer5 = { .regs = { .gen = TIMER5_BASE }, .clk_id = RCC_TIMER5, .type = TIMER_GENERAL, - .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, + .af_mode = GPIO_AFMODE_TIM3_5, + .handler_p = &timer5_handlers, }; -/** Timer 5 device (general-purpose) */ -timer_dev *TIMER5 = &timer5; -timer_dev timer6 = { +/** Timer 6 device (basic) */ +voidFuncPtr timer6_handlers[] = { [NR_BAS_HANDLERS - 1] = 0 }; +const timer_dev timer6 = { .regs = { .bas = TIMER6_BASE }, .clk_id = RCC_TIMER6, .type = TIMER_BASIC, - .handlers = { [NR_BAS_HANDLERS - 1] = 0 }, + .af_mode = GPIO_AFMODE_SYSTEM, + .handler_p = &timer6_handlers, }; -/** Timer 6 device (basic) */ -timer_dev *TIMER6 = &timer6; -timer_dev timer7 = { +/** Timer 7 device (basic) */ +voidFuncPtr timer7_handlers[] = { [NR_BAS_HANDLERS - 1] = 0 }; +const timer_dev timer7 = { .regs = { .bas = TIMER7_BASE }, .clk_id = RCC_TIMER7, .type = TIMER_BASIC, - .handlers = { [NR_BAS_HANDLERS - 1] = 0 }, + .af_mode = GPIO_AFMODE_SYSTEM, + .handler_p = &timer7_handlers, }; -/** Timer 7 device (basic) */ -timer_dev *TIMER7 = &timer7; -timer_dev timer8 = { +/** Timer 8 device (advanced) */ +voidFuncPtr timer8_handlers[] = { [NR_ADV_HANDLERS - 1] = 0 }; +const timer_dev timer8 = { .regs = { .adv = TIMER8_BASE }, .clk_id = RCC_TIMER8, .type = TIMER_ADVANCED, - .handlers = { [NR_ADV_HANDLERS - 1] = 0 }, + .af_mode = GPIO_AFMODE_TIM8_11, + .handler_p = &timer8_handlers, +}; + +/** Timer 9 device (general-purpose) */ +voidFuncPtr timer9_handlers[] = { [NR_GEN_HANDLERS - 1] = 0 }; +const timer_dev timer9 = { + .regs = { .gen = TIMER9_BASE }, + .clk_id = RCC_TIMER9, + .type = TIMER_GENERAL, + .af_mode = GPIO_AFMODE_TIM8_11, + .handler_p = &timer9_handlers, }; -/** Timer 8 device (advanced) */ -timer_dev *TIMER8 = &timer8; -#endif + +/** Timer 10 device (general-purpose) */ +voidFuncPtr timer10_handlers[] = { [NR_GEN_HANDLERS - 1] = 0 }; +const timer_dev timer10 = { + .regs = { .gen = TIMER10_BASE }, + .clk_id = RCC_TIMER10, + .type = TIMER_GENERAL, + .af_mode = GPIO_AFMODE_TIM8_11, + .handler_p = &timer10_handlers, +}; + +/** Timer 11 device (general-purpose) */ +voidFuncPtr timer11_handlers[] = { [NR_GEN_HANDLERS - 1] = 0 }; +const timer_dev timer11 = { + .regs = { .gen = TIMER11_BASE }, + .clk_id = RCC_TIMER11, + .type = TIMER_GENERAL, + .af_mode = GPIO_AFMODE_TIM8_11, + .handler_p = &timer11_handlers, +}; + +/** Timer 12 device (general-purpose) */ +voidFuncPtr timer12_handlers[] = { [NR_GEN_HANDLERS - 1] = 0 }; +const timer_dev timer12 = { + .regs = { .gen = TIMER12_BASE }, + .clk_id = RCC_TIMER12, + .type = TIMER_GENERAL, + .af_mode = GPIO_AFMODE_TIM12_14, + .handler_p = &timer12_handlers, +}; + +/** Timer 13 device (general-purpose) */ +voidFuncPtr timer13_handlers[] = { [NR_GEN_HANDLERS - 1] = 0 }; +const timer_dev timer13 = { + .regs = { .gen = TIMER13_BASE }, + .clk_id = RCC_TIMER13, + .type = TIMER_GENERAL, + .af_mode = GPIO_AFMODE_TIM12_14, + .handler_p = &timer13_handlers, +}; + +/** Timer 14 device (general-purpose) */ +voidFuncPtr timer14_handlers[] = { [NR_GEN_HANDLERS - 1] = 0 }; +const timer_dev timer14 = { + .regs = { .gen = TIMER14_BASE }, + .clk_id = RCC_TIMER14, + .type = TIMER_GENERAL, + .af_mode = GPIO_AFMODE_TIM12_14, + .handler_p = &timer14_handlers, +}; + /* * Convenience routines */ -static void disable_channel(timer_dev *dev, uint8 channel); -static void pwm_mode(timer_dev *dev, uint8 channel); -static void output_compare_mode(timer_dev *dev, uint8 channel); +static void disable_channel(const timer_dev *dev, uint8 channel); +static void pwm_mode(const timer_dev *dev, uint8 channel); +static void output_compare_mode(const timer_dev *dev, uint8 channel); -static inline void enable_irq(timer_dev *dev, uint8 interrupt); +static inline void enable_irq(const timer_dev *dev, uint8 interrupt); /** * Initialize a timer, and reset its register map. * @param dev Timer to initialize */ -void timer_init(timer_dev *dev) { +void timer_init(const timer_dev *dev) { rcc_clk_enable(dev->clk_id); rcc_reset_dev(dev->clk_id); } @@ -145,7 +212,7 @@ void timer_init(timer_dev *dev) { * * @param dev Timer to disable. */ -void timer_disable(timer_dev *dev) { +void timer_disable(const timer_dev *dev) { (dev->regs).bas->CR1 = 0; (dev->regs).bas->DIER = 0; switch (dev->type) { @@ -169,8 +236,9 @@ void timer_disable(timer_dev *dev) { * @param channel Relevant channel * @param mode New timer mode for channel */ -void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) { - ASSERT_FAULT(channel > 0 && channel <= 4); +void timer_set_mode(const timer_dev *dev, uint8 channel, timer_mode mode) { + //ASSERT_FAULT(channel > 4); + if (channel>4) return; /* TODO decide about the basic timers */ ASSERT(dev->type != TIMER_BASIC); @@ -187,6 +255,9 @@ void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) { case TIMER_OUTPUT_COMPARE: output_compare_mode(dev, channel); break; + case TIMER_ENCODER: + case TIMER_INPUT_CAPTURE: + break; } } @@ -194,17 +265,21 @@ void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) { * @brief Call a function on timer devices. * @param fn Function to call on each timer device. */ -void timer_foreach(void (*fn)(timer_dev*)) { +void timer_foreach(void (*fn)(const timer_dev*)) { fn(TIMER1); fn(TIMER2); fn(TIMER3); fn(TIMER4); -#ifdef STM32_HIGH_DENSITY fn(TIMER5); fn(TIMER6); fn(TIMER7); fn(TIMER8); -#endif + fn(TIMER9); + fn(TIMER10); + fn(TIMER11); + fn(TIMER12); + fn(TIMER13); + fn(TIMER14); } /** @@ -217,10 +292,10 @@ void timer_foreach(void (*fn)(timer_dev*)) { * @see timer_interrupt_id * @see timer_channel */ -void timer_attach_interrupt(timer_dev *dev, +void timer_attach_interrupt(const timer_dev *dev, uint8 interrupt, voidFuncPtr handler) { - dev->handlers[interrupt] = handler; + (*(dev->handler_p))[interrupt] = handler; timer_enable_irq(dev, interrupt); enable_irq(dev, interrupt); } @@ -234,21 +309,21 @@ void timer_attach_interrupt(timer_dev *dev, * @see timer_interrupt_id * @see timer_channel */ -void timer_detach_interrupt(timer_dev *dev, uint8 interrupt) { +void timer_detach_interrupt(const timer_dev *dev, uint8 interrupt) { timer_disable_irq(dev, interrupt); - dev->handlers[interrupt] = NULL; + (*(dev->handler_p))[interrupt] = NULL; } /* * IRQ handlers */ -static inline void dispatch_adv_brk(timer_dev *dev); -static inline void dispatch_adv_up(timer_dev *dev); -static inline void dispatch_adv_trg_com(timer_dev *dev); -static inline void dispatch_adv_cc(timer_dev *dev); -static inline void dispatch_general(timer_dev *dev); -static inline void dispatch_basic(timer_dev *dev); +static inline void dispatch_adv_brk(const timer_dev *dev); +static inline void dispatch_adv_up(const timer_dev *dev); +static inline void dispatch_adv_trg_com(const timer_dev *dev); +static inline void dispatch_adv_cc(const timer_dev *dev); +static inline void dispatch_general(const timer_dev *dev); +static inline void dispatch_basic(const timer_dev *dev); void __irq_tim1_brk(void) { dispatch_adv_brk(TIMER1); @@ -278,13 +353,11 @@ void __irq_tim4(void) { dispatch_general(TIMER4); } -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - void __irq_tim5(void) { dispatch_general(TIMER5); } -void __irq_tim6(void) { +void __irq_tim6_dac(void) { dispatch_basic(TIMER6); } @@ -307,7 +380,6 @@ void __irq_tim8_trg_com(void) { void __irq_tim8_cc(void) { dispatch_adv_cc(TIMER8); } -#endif /* Note: the following dispatch routines make use of the fact that * DIER interrupt enable bits and SR interrupt flags have common bit @@ -318,11 +390,11 @@ void __irq_tim8_cc(void) { /* A special-case dispatch routine for single-interrupt NVIC lines. * This function assumes that the interrupt corresponding to `iid' has * in fact occurred (i.e., it doesn't check DIER & SR). */ -static inline void dispatch_single_irq(timer_dev *dev, +static inline void dispatch_single_irq(const timer_dev *dev, timer_interrupt_id iid, uint32 irq_mask) { timer_bas_reg_map *regs = (dev->regs).bas; - void (*handler)(void) = dev->handlers[iid]; + void (*handler)(void) = (*(dev->handler_p))[iid]; if (handler) { handler(); regs->SR &= ~irq_mask; @@ -340,18 +412,18 @@ static inline void dispatch_single_irq(timer_dev *dev, } \ } while (0) -static inline void dispatch_adv_brk(timer_dev *dev) { +static inline void dispatch_adv_brk(const timer_dev *dev) { dispatch_single_irq(dev, TIMER_BREAK_INTERRUPT, TIMER_SR_BIF); } -static inline void dispatch_adv_up(timer_dev *dev) { +static inline void dispatch_adv_up(const timer_dev *dev) { dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); } -static inline void dispatch_adv_trg_com(timer_dev *dev) { +static inline void dispatch_adv_trg_com(const timer_dev *dev) { timer_adv_reg_map *regs = (dev->regs).adv; uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; + void (**hs)(void) = *(dev->handler_p); uint32 handled = 0; /* Logical OR of SR interrupt flags we end up * handling. We clear these. User handlers * must clear overcapture flags, to avoid @@ -363,10 +435,10 @@ static inline void dispatch_adv_trg_com(timer_dev *dev) { regs->SR &= ~handled; } -static inline void dispatch_adv_cc(timer_dev *dev) { +static inline void dispatch_adv_cc(const timer_dev *dev) { timer_adv_reg_map *regs = (dev->regs).adv; uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; + void (**hs)(void) = *(dev->handler_p); uint32 handled = 0; handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled); @@ -377,10 +449,10 @@ static inline void dispatch_adv_cc(timer_dev *dev) { regs->SR &= ~handled; } -static inline void dispatch_general(timer_dev *dev) { +static inline void dispatch_general(const timer_dev *dev) { timer_gen_reg_map *regs = (dev->regs).gen; uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; + void (**hs)(void) = *(dev->handler_p); uint32 handled = 0; handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); @@ -393,7 +465,7 @@ static inline void dispatch_general(timer_dev *dev) { regs->SR &= ~handled; } -static inline void dispatch_basic(timer_dev *dev) { +static inline void dispatch_basic(const timer_dev *dev) { dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); } @@ -401,26 +473,26 @@ static inline void dispatch_basic(timer_dev *dev) { * Utilities */ -static void disable_channel(timer_dev *dev, uint8 channel) { +static void disable_channel(const timer_dev *dev, uint8 channel) { timer_detach_interrupt(dev, channel); timer_cc_disable(dev, channel); } -static void pwm_mode(timer_dev *dev, uint8 channel) { +static void pwm_mode(const timer_dev *dev, uint8 channel) { timer_disable_irq(dev, channel); timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE); timer_cc_enable(dev, channel); } -static void output_compare_mode(timer_dev *dev, uint8 channel) { +static void output_compare_mode(const timer_dev *dev, uint8 channel) { timer_oc_set_mode(dev, channel, TIMER_OC_MODE_ACTIVE_ON_MATCH, 0); timer_cc_enable(dev, channel); } -static void enable_advanced_irq(timer_dev *dev, timer_interrupt_id id); -static void enable_nonmuxed_irq(timer_dev *dev); +static void enable_advanced_irq(const timer_dev *dev, timer_interrupt_id id); +static void enable_nonmuxed_irq(const timer_dev *dev); -static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid) { +static inline void enable_irq(const timer_dev *dev, timer_interrupt_id iid) { if (dev->type == TIMER_ADVANCED) { enable_advanced_irq(dev, iid); } else { @@ -428,7 +500,7 @@ static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid) { } } -static void enable_advanced_irq(timer_dev *dev, timer_interrupt_id id) { +static void enable_advanced_irq(const timer_dev *dev, timer_interrupt_id id) { uint8 is_timer1 = dev->clk_id == RCC_TIMER1; switch (id) { @@ -451,7 +523,7 @@ static void enable_advanced_irq(timer_dev *dev, timer_interrupt_id id) { } } -static void enable_nonmuxed_irq(timer_dev *dev) { +static void enable_nonmuxed_irq(const timer_dev *dev) { switch (dev->clk_id) { case RCC_TIMER2: nvic_irq_enable(NVIC_TIMER2); @@ -462,17 +534,15 @@ static void enable_nonmuxed_irq(timer_dev *dev) { case RCC_TIMER4: nvic_irq_enable(NVIC_TIMER4); break; -#ifdef STM32_HIGH_DENSITY case RCC_TIMER5: nvic_irq_enable(NVIC_TIMER5); break; case RCC_TIMER6: - nvic_irq_enable(NVIC_TIMER6); + nvic_irq_enable(NVIC_TIMER6_DAC); break; case RCC_TIMER7: nvic_irq_enable(NVIC_TIMER7); break; -#endif default: ASSERT_FAULT(0); break; diff --git a/STM32F4/cores/maple/libmaple/timer.h b/STM32F4/cores/maple/libmaple/timer.h index 79b7d2996..c02ee7f6a 100644 --- a/STM32F4/cores/maple/libmaple/timer.h +++ b/STM32F4/cores/maple/libmaple/timer.h @@ -27,9 +27,7 @@ /** * @file timer.h * @author Marti Bolivar - * @brief New-style timer interface. - * - * Replaces old timers.h implementation. + * @brief Timer interface. */ #ifndef _TIMERS_H_ @@ -39,77 +37,79 @@ #include "rcc.h" #include "nvic.h" #include "bitband.h" +#include "gpio_def.h" #ifdef __cplusplus extern "C"{ #endif + /* * Register maps and devices */ /** Advanced control timer register map type */ typedef struct timer_adv_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SMCR; /**< Slave mode control register */ - __io uint32 DIER; /**< DMA/Interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - __io uint32 CCMR1; /**< Capture/compare mode register 1 */ - __io uint32 CCMR2; /**< Capture/compare mode register 2 */ - __io uint32 CCER; /**< Capture/compare enable register */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ - __io uint32 RCR; /**< Repetition counter register */ - __io uint32 CCR1; /**< Capture/compare register 1 */ - __io uint32 CCR2; /**< Capture/compare register 2 */ - __io uint32 CCR3; /**< Capture/compare register 3 */ - __io uint32 CCR4; /**< Capture/compare register 4 */ - __io uint32 BDTR; /**< Break and dead-time register */ - __io uint32 DCR; /**< DMA control register */ - __io uint32 DMAR; /**< DMA address for full transfer */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ + __IO uint32 SMCR; /**< Slave mode control register */ + __IO uint32 DIER; /**< DMA/interrupt enable register */ + __IO uint32 SR; /**< Status register */ + __IO uint32 EGR; /**< Event generation register */ + __IO uint32 CCMR1; /**< Capture/compare mode register 1 */ + __IO uint32 CCMR2; /**< Capture/compare mode register 2 */ + __IO uint32 CCER; /**< Capture/compare enable register */ + __IO uint32 CNT; /**< Counter */ + __IO uint32 PSC; /**< Prescaler */ + __IO uint32 ARR; /**< Auto-reload register */ + __IO uint32 RCR; /**< Repetition counter register */ + __IO uint32 CCR1; /**< Capture/compare register 1 */ + __IO uint32 CCR2; /**< Capture/compare register 2 */ + __IO uint32 CCR3; /**< Capture/compare register 3 */ + __IO uint32 CCR4; /**< Capture/compare register 4 */ + __IO uint32 BDTR; /**< Break and dead-time register */ + __IO uint32 DCR; /**< DMA control register */ + __IO uint32 DMAR; /**< DMA address for full transfer */ } timer_adv_reg_map; /** General purpose timer register map type */ typedef struct timer_gen_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SMCR; /**< Slave mode control register */ - __io uint32 DIER; /**< DMA/Interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - __io uint32 CCMR1; /**< Capture/compare mode register 1 */ - __io uint32 CCMR2; /**< Capture/compare mode register 2 */ - __io uint32 CCER; /**< Capture/compare enable register */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ + __IO uint32 SMCR; /**< Slave mode control register */ + __IO uint32 DIER; /**< DMA/Interrupt enable register */ + __IO uint32 SR; /**< Status register */ + __IO uint32 EGR; /**< Event generation register */ + __IO uint32 CCMR1; /**< Capture/compare mode register 1 */ + __IO uint32 CCMR2; /**< Capture/compare mode register 2 */ + __IO uint32 CCER; /**< Capture/compare enable register */ + __IO uint32 CNT; /**< Counter */ + __IO uint32 PSC; /**< Prescaler */ + __IO uint32 ARR; /**< Auto-reload register */ const uint32 RESERVED1; /**< Reserved */ - __io uint32 CCR1; /**< Capture/compare register 1 */ - __io uint32 CCR2; /**< Capture/compare register 2 */ - __io uint32 CCR3; /**< Capture/compare register 3 */ - __io uint32 CCR4; /**< Capture/compare register 4 */ + __IO uint32 CCR1; /**< Capture/compare register 1 */ + __IO uint32 CCR2; /**< Capture/compare register 2 */ + __IO uint32 CCR3; /**< Capture/compare register 3 */ + __IO uint32 CCR4; /**< Capture/compare register 4 */ const uint32 RESERVED2; /**< Reserved */ - __io uint32 DCR; /**< DMA control register */ - __io uint32 DMAR; /**< DMA address for full transfer */ + __IO uint32 DCR; /**< DMA control register */ + __IO uint32 DMAR; /**< DMA address for full transfer */ } timer_gen_reg_map; /** Basic timer register map type */ typedef struct timer_bas_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ + __IO uint32 CR1; /**< Control register 1 */ + __IO uint32 CR2; /**< Control register 2 */ const uint32 RESERVED1; /**< Reserved */ - __io uint32 DIER; /**< DMA/Interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ + __IO uint32 DIER; /**< DMA/interrupt enable register */ + __IO uint32 SR; /**< Status register */ + __IO uint32 EGR; /**< Event generation register */ const uint32 RESERVED2; /**< Reserved */ const uint32 RESERVED3; /**< Reserved */ const uint32 RESERVED4; /**< Reserved */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ + __IO uint32 CNT; /**< Counter */ + __IO uint32 PSC; /**< Prescaler */ + __IO uint32 ARR; /**< Auto-reload register */ } timer_bas_reg_map; @@ -121,7 +121,6 @@ typedef struct timer_bas_reg_map { #define TIMER3_BASE ((struct timer_gen_reg_map*)0x40000400) /** Timer 4 register map base pointer */ #define TIMER4_BASE ((struct timer_gen_reg_map*)0x40000800) -#ifdef STM32_HIGH_DENSITY /** Timer 5 register map base pointer */ #define TIMER5_BASE ((struct timer_gen_reg_map*)0x40000C00) /** Timer 6 register map base pointer */ @@ -130,7 +129,19 @@ typedef struct timer_bas_reg_map { #define TIMER7_BASE ((struct timer_bas_reg_map*)0x40001400) /** Timer 8 register map base pointer */ #define TIMER8_BASE ((struct timer_adv_reg_map*)0x40010400) -#endif +/** Timer 9 register map base pointer */ +#define TIMER9_BASE ((struct timer_gen_reg_map*)0x40014000) +/** Timer 10 register map base pointer */ +#define TIMER10_BASE ((struct timer_gen_reg_map*)0x40014400) +/** Timer 11 register map base pointer */ +#define TIMER11_BASE ((struct timer_gen_reg_map*)0x40014800) +/** Timer 12 register map base pointer */ +#define TIMER12_BASE ((struct timer_gen_reg_map*)0x40001800) +/** Timer 13 register map base pointer */ +#define TIMER13_BASE ((struct timer_gen_reg_map*)0x40001C00) +/** Timer 14 register map base pointer */ +#define TIMER14_BASE ((struct timer_gen_reg_map*)0x40002000) + /* * Timer devices @@ -166,19 +177,53 @@ typedef struct timer_dev { timer_reg_map regs; /**< Register map */ rcc_clk_id clk_id; /**< RCC clock information */ timer_type type; /**< Timer's type */ - voidFuncPtr handlers[]; /**< User IRQ handlers */ + gpio_af_mode af_mode; /**< Alternate function mode */ + voidFuncPtr (*handler_p)[]; /**< Pointer to user IRQ handlers */ } timer_dev; -extern timer_dev *TIMER1; -extern timer_dev *TIMER2; -extern timer_dev *TIMER3; -extern timer_dev *TIMER4; -#ifdef STM32_HIGH_DENSITY -extern timer_dev *TIMER5; -extern timer_dev *TIMER6; -extern timer_dev *TIMER7; -extern timer_dev *TIMER8; -#endif +extern const timer_dev timer1; +extern const timer_dev timer2; +extern const timer_dev timer3; +extern const timer_dev timer4; +extern const timer_dev timer5; +extern const timer_dev timer6; +extern const timer_dev timer7; +extern const timer_dev timer8; +extern const timer_dev timer9; +extern const timer_dev timer10; +extern const timer_dev timer11; +extern const timer_dev timer12; +extern const timer_dev timer13; +extern const timer_dev timer14; +#define TIMER1 (&timer1) +#define TIMER2 (&timer2) +#define TIMER3 (&timer3) +#define TIMER4 (&timer4) +#define TIMER5 (&timer5) +#define TIMER6 (&timer6) +#define TIMER7 (&timer7) +#define TIMER8 (&timer8) +#define TIMER9 (&timer9) +#define TIMER10 (&timer10) +#define TIMER11 (&timer11) +#define TIMER12 (&timer12) +#define TIMER13 (&timer13) +#define TIMER14 (&timer14) + +extern const timer_dev * const timer_devices[]; + +enum t_index { NO_TIM = 0, TIM1, TIM2, TIM3, TIM4, TIM5, TIM6, TIM7, TIM8, TIM9, TIM10, TIM11, TIM12, TIM13, TIM14, LAST_TIM}; + +typedef struct timer_info { + uint8_t index; // Pin's timer device, if any. + uint8_t channel; // Timer channel, or 0 if none. +} timer_info; + +extern const timer_info timer_map[]; + +#define digitalPinToTimerIndex(P) ( timer_map[P].index ) +#define digitalPinToTimerDevice(P) ( timer_devices[digitalPinToTimerIndex(P)] ) + /* * Register bit definitions @@ -218,7 +263,7 @@ extern timer_dev *TIMER8; #define TIMER_CR2_OIS2_BIT 10 #define TIMER_CR2_OIS1N_BIT 9 #define TIMER_CR2_OIS1_BIT 8 -#define TIMER_CR2_TI1S_BIT 7 /* tills? yikes */ +#define TIMER_CR2_TI1S_BIT 7 #define TIMER_CR2_CCDS_BIT 3 #define TIMER_CR2_CCUS_BIT 2 #define TIMER_CR2_CCPC_BIT 0 @@ -244,6 +289,11 @@ extern timer_dev *TIMER8; #define TIMER_CR2_CCUS BIT(TIMER_CR2_CCUS_BIT) #define TIMER_CR2_CCPC BIT(TIMER_CR2_CCPC_BIT) +typedef enum { + TIMER_MASTER_MODE_RESET = TIMER_CR2_MMS_RESET, + TIMER_MASTER_MODE_ENABLE = TIMER_CR2_MMS_ENABLE, + TIMER_MASTER_MODE_UPDATE = TIMER_CR2_MMS_UPDATE, +} timer_mms_t; /* Slave mode control register (SMCR) */ #define TIMER_SMCR_ETP_BIT 15 @@ -257,9 +307,9 @@ extern timer_dev *TIMER8; #define TIMER_SMCR_ETPS_DIV2 (0x1 << 12) #define TIMER_SMCR_ETPS_DIV4 (0x2 << 12) #define TIMER_SMCR_ETPS_DIV8 (0x3 << 12) -#define TIMER_SMCR_ETF (0xF << 12) +#define TIMER_SMCR_ETF (0xF << 8) #define TIMER_SMCR_MSM BIT(TIMER_SMCR_MSM_BIT) -#define TIMER_SMCR_TS (0x3 << 4) +#define TIMER_SMCR_TS (0x7 << 4) #define TIMER_SMCR_TS_ITR0 (0x0 << 4) #define TIMER_SMCR_TS_ITR1 (0x1 << 4) #define TIMER_SMCR_TS_ITR2 (0x2 << 4) @@ -268,7 +318,7 @@ extern timer_dev *TIMER8; #define TIMER_SMCR_TS_TI1FP1 (0x5 << 4) #define TIMER_SMCR_TS_TI2FP2 (0x6 << 4) #define TIMER_SMCR_TS_ETRF (0x7 << 4) -#define TIMER_SMCR_SMS 0x3 +#define TIMER_SMCR_SMS 0x7 #define TIMER_SMCR_SMS_DISABLED 0x0 #define TIMER_SMCR_SMS_ENCODER1 0x1 #define TIMER_SMCR_SMS_ENCODER2 0x2 @@ -281,12 +331,15 @@ extern timer_dev *TIMER8; /* DMA/Interrupt enable register (DIER) */ #define TIMER_DIER_TDE_BIT 14 +#define TIMER_DIER_COMDE_BIT 13 #define TIMER_DIER_CC4DE_BIT 12 #define TIMER_DIER_CC3DE_BIT 11 #define TIMER_DIER_CC2DE_BIT 10 #define TIMER_DIER_CC1DE_BIT 9 #define TIMER_DIER_UDE_BIT 8 +#define TIMER_DIER_BIE_BIT 7 #define TIMER_DIER_TIE_BIT 6 +#define TIMER_DIER_COMIE_BIT 5 #define TIMER_DIER_CC4IE_BIT 4 #define TIMER_DIER_CC3IE_BIT 3 #define TIMER_DIER_CC2IE_BIT 2 @@ -294,12 +347,15 @@ extern timer_dev *TIMER8; #define TIMER_DIER_UIE_BIT 0 #define TIMER_DIER_TDE BIT(TIMER_DIER_TDE_BIT) +#define TIMER_DIER_COMDE BIT(TIMER_DIER_COMDE_BIT) #define TIMER_DIER_CC4DE BIT(TIMER_DIER_CC4DE_BIT) #define TIMER_DIER_CC3DE BIT(TIMER_DIER_CC3DE_BIT) #define TIMER_DIER_CC2DE BIT(TIMER_DIER_CC2DE_BIT) #define TIMER_DIER_CC1DE BIT(TIMER_DIER_CC1DE_BIT) #define TIMER_DIER_UDE BIT(TIMER_DIER_UDE_BIT) +#define TIMER_DIER_BIE BIT(TIMER_DIER_BIE_BIT) #define TIMER_DIER_TIE BIT(TIMER_DIER_TIE_BIT) +#define TIMER_DIER_COMIE BIT(TIMER_DIER_COMIE_BIT) #define TIMER_DIER_CC4IE BIT(TIMER_DIER_CC4IE_BIT) #define TIMER_DIER_CC3IE BIT(TIMER_DIER_CC3IE_BIT) #define TIMER_DIER_CC2IE BIT(TIMER_DIER_CC2IE_BIT) @@ -336,14 +392,18 @@ extern timer_dev *TIMER8; /* Event generation register (EGR) */ +#define TIMER_EGR_BG_BIT 7 #define TIMER_EGR_TG_BIT 6 +#define TIMER_EGR_COMG_BIT 5 #define TIMER_EGR_CC4G_BIT 4 #define TIMER_EGR_CC3G_BIT 3 #define TIMER_EGR_CC2G_BIT 2 #define TIMER_EGR_CC1G_BIT 1 #define TIMER_EGR_UG_BIT 0 +#define TIMER_EGR_BG BIT(TIMER_EGR_BG_BIT) #define TIMER_EGR_TG BIT(TIMER_EGR_TG_BIT) +#define TIMER_EGR_COMG BIT(TIMER_EGR_COMG_BIT) #define TIMER_EGR_CC4G BIT(TIMER_EGR_CC4G_BIT) #define TIMER_EGR_CC3G BIT(TIMER_EGR_CC3G_BIT) #define TIMER_EGR_CC2G BIT(TIMER_EGR_CC2G_BIT) @@ -352,7 +412,6 @@ extern timer_dev *TIMER8; /* Capture/compare mode registers, common values */ -#define TIMER_CCMR_CCS_OUTPUT 0x0 #define TIMER_CCMR_CCS_INPUT_TI1 0x1 #define TIMER_CCMR_CCS_INPUT_TI2 0x2 #define TIMER_CCMR_CCS_INPUT_TRC 0x3 @@ -367,27 +426,27 @@ extern timer_dev *TIMER8; #define TIMER_CCMR1_OC1FE_BIT 2 #define TIMER_CCMR1_OC2CE BIT(TIMER_CCMR1_OC2CE_BIT) -#define TIMER_CCMR1_OC2M (0x3 << 12) +#define TIMER_CCMR1_OC2M (0x7 << 12) #define TIMER_CCMR1_IC2F (0xF << 12) #define TIMER_CCMR1_OC2PE BIT(TIMER_CCMR1_OC2PE_BIT) #define TIMER_CCMR1_OC2FE BIT(TIMER_CCMR1_OC2FE_BIT) #define TIMER_CCMR1_IC2PSC (0x3 << 10) #define TIMER_CCMR1_CC2S (0x3 << 8) -#define TIMER_CCMR1_CC2S_OUTPUT (TIMER_CCMR_CCS_OUTPUT << 8) -#define TIMER_CCMR1_CC2S_INPUT_TI1 (TIMER_CCMR_CCS_INPUT_TI1 << 8) -#define TIMER_CCMR1_CC2S_INPUT_TI2 (TIMER_CCMR_CCS_INPUT_TI2 << 8) -#define TIMER_CCMR1_CC2S_INPUT_TRC (TIMER_CCMR_CCS_INPUT_TRC << 8) +#define TIMER_CCMR1_CC2S_OUTPUT (0x0 << 8) +#define TIMER_CCMR1_CC2S_INPUT_TI2 (0x1 << 8) +#define TIMER_CCMR1_CC2S_INPUT_TI1 (0x2 << 8) +#define TIMER_CCMR1_CC2S_INPUT_TRC (0x3 << 8) #define TIMER_CCMR1_OC1CE BIT(TIMER_CCMR1_OC1CE_BIT) -#define TIMER_CCMR1_OC1M (0x3 << 4) +#define TIMER_CCMR1_OC1M (0x7 << 4) #define TIMER_CCMR1_IC1F (0xF << 4) #define TIMER_CCMR1_OC1PE BIT(TIMER_CCMR1_OC1PE_BIT) #define TIMER_CCMR1_OC1FE BIT(TIMER_CCMR1_OC1FE_BIT) #define TIMER_CCMR1_IC1PSC (0x3 << 2) #define TIMER_CCMR1_CC1S 0x3 -#define TIMER_CCMR1_CC1S_OUTPUT TIMER_CCMR_CCS_OUTPUT -#define TIMER_CCMR1_CC1S_INPUT_TI1 TIMER_CCMR_CCS_INPUT_TI1 -#define TIMER_CCMR1_CC1S_INPUT_TI2 TIMER_CCMR_CCS_INPUT_TI2 -#define TIMER_CCMR1_CC1S_INPUT_TRC TIMER_CCMR_CCS_INPUT_TRC +#define TIMER_CCMR1_CC1S_OUTPUT 0x0 +#define TIMER_CCMR1_CC1S_INPUT_TI1 0x1 +#define TIMER_CCMR1_CC1S_INPUT_TI2 0x2 +#define TIMER_CCMR1_CC1S_INPUT_TRC 0x3 /* Capture/compare mode register 2 (CCMR2) */ @@ -399,45 +458,57 @@ extern timer_dev *TIMER8; #define TIMER_CCMR2_OC3FE_BIT 2 #define TIMER_CCMR2_OC4CE BIT(TIMER_CCMR2_OC4CE_BIT) -#define TIMER_CCMR2_OC4M (0x3 << 12) -#define TIMER_CCMR2_IC2F (0xF << 12) +#define TIMER_CCMR2_OC4M (0x7 << 12) +#define TIMER_CCMR2_IC4F (0xF << 12) #define TIMER_CCMR2_OC4PE BIT(TIMER_CCMR2_OC4PE_BIT) #define TIMER_CCMR2_OC4FE BIT(TIMER_CCMR2_OC4FE_BIT) -#define TIMER_CCMR2_IC2PSC (0x3 << 10) +#define TIMER_CCMR2_IC4PSC (0x3 << 10) #define TIMER_CCMR2_CC4S (0x3 << 8) -#define TIMER_CCMR1_CC4S_OUTPUT (TIMER_CCMR_CCS_OUTPUT << 8) -#define TIMER_CCMR1_CC4S_INPUT_TI1 (TIMER_CCMR_CCS_INPUT_TI1 << 8) -#define TIMER_CCMR1_CC4S_INPUT_TI2 (TIMER_CCMR_CCS_INPUT_TI2 << 8) -#define TIMER_CCMR1_CC4S_INPUT_TRC (TIMER_CCMR_CCS_INPUT_TRC << 8) +#define TIMER_CCMR2_CC4S_OUTPUT (0x0 << 8) +#define TIMER_CCMR2_CC4S_INPUT_TI4 (0x1 << 8) +#define TIMER_CCMR2_CC4S_INPUT_TI3 (0x2 << 8) +#define TIMER_CCMR2_CC4S_INPUT_TRC (0x3 << 8) #define TIMER_CCMR2_OC3CE BIT(TIMER_CCMR2_OC3CE_BIT) -#define TIMER_CCMR2_OC3M (0x3 << 4) -#define TIMER_CCMR2_IC1F (0xF << 4) +#define TIMER_CCMR2_OC3M (0x7 << 4) +#define TIMER_CCMR2_IC3F (0xF << 4) #define TIMER_CCMR2_OC3PE BIT(TIMER_CCMR2_OC3PE_BIT) #define TIMER_CCMR2_OC3FE BIT(TIMER_CCMR2_OC3FE_BIT) -#define TIMER_CCMR2_IC1PSC (0x3 << 2) +#define TIMER_CCMR2_IC3PSC (0x3 << 2) #define TIMER_CCMR2_CC3S 0x3 -#define TIMER_CCMR1_CC3S_OUTPUT TIMER_CCMR_CCS_OUTPUT -#define TIMER_CCMR1_CC3S_INPUT_TI1 TIMER_CCMR_CCS_INPUT_TI1 -#define TIMER_CCMR1_CC3S_INPUT_TI2 TIMER_CCMR_CCS_INPUT_TI2 -#define TIMER_CCMR1_CC3S_INPUT_TRC TIMER_CCMR_CCS_INPUT_TRC +#define TIMER_CCMR2_CC3S_OUTPUT 0x0 +#define TIMER_CCMR2_CC3S_INPUT_TI3 0x1 +#define TIMER_CCMR2_CC3S_INPUT_TI4 0x2 +#define TIMER_CCMR2_CC3S_INPUT_TRC 0x3 /* Capture/compare enable register (CCER) */ #define TIMER_CCER_CC4P_BIT 13 #define TIMER_CCER_CC4E_BIT 12 +#define TIMER_CCER_CC3NP_BIT 11 +#define TIMER_CCER_CC3NE_BIT 10 #define TIMER_CCER_CC3P_BIT 9 #define TIMER_CCER_CC3E_BIT 8 +#define TIMER_CCER_CC2NP_BIT 7 +#define TIMER_CCER_CC2NE_BIT 6 #define TIMER_CCER_CC2P_BIT 5 #define TIMER_CCER_CC2E_BIT 4 +#define TIMER_CCER_CC1NP_BIT 3 +#define TIMER_CCER_CC1NE_BIT 2 #define TIMER_CCER_CC1P_BIT 1 #define TIMER_CCER_CC1E_BIT 0 #define TIMER_CCER_CC4P BIT(TIMER_CCER_CC4P_BIT) #define TIMER_CCER_CC4E BIT(TIMER_CCER_CC4E_BIT) +#define TIMER_CCER_CC3NP BIT(TIMER_CCER_CC3NP_BIT) +#define TIMER_CCER_CC3NE BIT(TIMER_CCER_CC3NE_BIT) #define TIMER_CCER_CC3P BIT(TIMER_CCER_CC3P_BIT) #define TIMER_CCER_CC3E BIT(TIMER_CCER_CC3E_BIT) +#define TIMER_CCER_CC2NP BIT(TIMER_CCER_CC2NP_BIT) +#define TIMER_CCER_CC2NE BIT(TIMER_CCER_CC2NE_BIT) #define TIMER_CCER_CC2P BIT(TIMER_CCER_CC2P_BIT) #define TIMER_CCER_CC2E BIT(TIMER_CCER_CC2E_BIT) +#define TIMER_CCER_CC1NP BIT(TIMER_CCER_CC1NP_BIT) +#define TIMER_CCER_CC1NE BIT(TIMER_CCER_CC1NE_BIT) #define TIMER_CCER_CC1P BIT(TIMER_CCER_CC1P_BIT) #define TIMER_CCER_CC1E BIT(TIMER_CCER_CC1E_BIT) @@ -466,24 +537,24 @@ extern timer_dev *TIMER8; /* DMA control register (DCR) */ #define TIMER_DCR_DBL (0x1F << 8) -#define TIMER_DCR_DBL_1BYTE (0x0 << 8) -#define TIMER_DCR_DBL_2BYTE (0x1 << 8) -#define TIMER_DCR_DBL_3BYTE (0x2 << 8) -#define TIMER_DCR_DBL_4BYTE (0x3 << 8) -#define TIMER_DCR_DBL_5BYTE (0x4 << 8) -#define TIMER_DCR_DBL_6BYTE (0x5 << 8) -#define TIMER_DCR_DBL_7BYTE (0x6 << 8) -#define TIMER_DCR_DBL_8BYTE (0x7 << 8) -#define TIMER_DCR_DBL_9BYTE (0x8 << 8) -#define TIMER_DCR_DBL_10BYTE (0x9 << 8) -#define TIMER_DCR_DBL_11BYTE (0xA << 8) -#define TIMER_DCR_DBL_12BYTE (0xB << 8) -#define TIMER_DCR_DBL_13BYTE (0xC << 8) -#define TIMER_DCR_DBL_14BYTE (0xD << 8) -#define TIMER_DCR_DBL_15BYTE (0xE << 8) -#define TIMER_DCR_DBL_16BYTE (0xF << 8) -#define TIMER_DCR_DBL_17BYTE (0x10 << 8) -#define TIMER_DCR_DBL_18BYTE (0x11 << 8) +#define TIMER_DCR_DBL_1_XFER (0x0 << 8) +#define TIMER_DCR_DBL_2_XFER (0x1 << 8) +#define TIMER_DCR_DBL_3_XFER (0x2 << 8) +#define TIMER_DCR_DBL_4_XFER (0x3 << 8) +#define TIMER_DCR_DBL_5_XFER (0x4 << 8) +#define TIMER_DCR_DBL_6_XFER (0x5 << 8) +#define TIMER_DCR_DBL_7_XFER (0x6 << 8) +#define TIMER_DCR_DBL_8_XFER (0x7 << 8) +#define TIMER_DCR_DBL_9_XFER (0x8 << 8) +#define TIMER_DCR_DBL_10_XFER (0x9 << 8) +#define TIMER_DCR_DBL_11_XFER (0xA << 8) +#define TIMER_DCR_DBL_12_XFER (0xB << 8) +#define TIMER_DCR_DBL_13_XFER (0xC << 8) +#define TIMER_DCR_DBL_14_XFER (0xD << 8) +#define TIMER_DCR_DBL_15_XFER (0xE << 8) +#define TIMER_DCR_DBL_16_XFER (0xF << 8) +#define TIMER_DCR_DBL_17_XFER (0x10 << 8) +#define TIMER_DCR_DBL_18_XFER (0x11 << 8) #define TIMER_DCR_DBA 0x1F #define TIMER_DCR_DBA_CR1 0x0 #define TIMER_DCR_DBA_CR2 0x1 @@ -511,27 +582,27 @@ extern timer_dev *TIMER8; */ /** - * Used to configure the behavior of a timer channel. Note that not - * all timers can be configured in every mode. + * @brief Used to configure the behavior of a timer channel. + * + * Be careful: not all timers can be configured in every mode. */ /* TODO TIMER_PWM_CENTER_ALIGNED, TIMER_INPUT_CAPTURE, TIMER_ONE_PULSE */ -typedef enum timer_mode { - TIMER_DISABLED, /**< In this mode, the timer stops counting, - channel interrupts are detached, and no state - changes are output. */ +typedef enum timer_mode +{ + TIMER_DISABLED, /**< In this mode the timer stops counting, + channel interrupts are detached, and no state changes are output. */ TIMER_PWM, /**< PWM output mode. This is the default mode for pins after initialization. */ /* TIMER_PWM_CENTER_ALIGNED, /\**< Center-aligned PWM output mode. *\/ */ - TIMER_OUTPUT_COMPARE, /**< In this mode, the timer counts from 0 - to its reload value repeatedly; every - time the counter value reaches one of - the channel compare values, the - corresponding interrupt is fired. */ - /* TIMER_INPUT_CAPTURE, /\**< In this mode, the timer can measure the */ + TIMER_OUTPUT_COMPARE, /**< In this mode the timer counts from 0 to its + reload value repeatedly; every time the counter value reaches one of + the channel compare values, the corresponding interrupt is fired. */ + /* TIMER_INPUT_CAPTURE, /\**< In this mode the timer can measure the */ /* pulse lengths of input signals. *\/ */ - /* TIMER_ONE_PULSE /\**< In this mode, the timer can generate a single */ - /* pulse on a GPIO pin for a specified amount of */ - /* time. *\/ */ + /* TIMER_ONE_PULSE /\**< In this mode the timer can generate a single */ + /* pulse on a GPIO pin for a specified amount of time. *\/ */ + TIMER_ENCODER, //CARLOS Change + TIMER_INPUT_CAPTURE // code from @cesco } timer_mode; /** Timer channel numbers */ @@ -552,10 +623,11 @@ typedef enum timer_channel { * without the compiler yelling at us. */ -void timer_init(timer_dev *dev); -void timer_disable(timer_dev *dev); -void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode); -void timer_foreach(void (*fn)(timer_dev*)); +void timer_init(const timer_dev *dev); +void timer_disable(const timer_dev *dev); +void timer_set_mode(const timer_dev *dev, uint8 channel, timer_mode mode); +void timer_foreach(void (*fn)(const timer_dev*)); +int timer_has_cc_channel(const timer_dev *dev, uint8 channel); /** * @brief Timer interrupt number. @@ -579,10 +651,15 @@ typedef enum timer_interrupt_id { TIMER_BREAK_INTERRUPT /**< Break interrupt, advanced timers only. */ } timer_interrupt_id; -void timer_attach_interrupt(timer_dev *dev, +void timer_attach_interrupt(const timer_dev *dev, uint8 interrupt, voidFuncPtr handler); -void timer_detach_interrupt(timer_dev *dev, uint8 interrupt); +void timer_detach_interrupt(const timer_dev *dev, uint8 interrupt); + +//CARLOS +uint8 get_direction(const timer_dev *dev); + + /** * Initialize all timer devices on the chip. @@ -605,7 +682,7 @@ static inline void timer_disable_all(void) { * * @param dev Device whose counter to pause. */ -static inline void timer_pause(timer_dev *dev) { +static inline void timer_pause(const timer_dev *dev) { *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 0; } @@ -616,10 +693,23 @@ static inline void timer_pause(timer_dev *dev) { * * @param dev Device whose counter to resume */ -static inline void timer_resume(timer_dev *dev) { +static inline void timer_resume(const timer_dev *dev) { *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 1; } +/** + * @brief Get the status register. + * @param dev Timer device + * @return Status register value (16bits). + */ +static inline uint16 timer_get_status(const timer_dev *dev) { + return (dev->regs).gen->SR; +} + +static inline void timer_reset_status_bit(const timer_dev *dev, uint8 bit) { + (dev->regs).gen->SR = ~BIT(bit); // rc_w0 +} + /** * @brief Returns the timer's counter value. * @@ -628,7 +718,7 @@ static inline void timer_resume(timer_dev *dev) { * * @param dev Timer whose counter to return */ -static inline uint16 timer_get_count(timer_dev *dev) { +static inline uint16 timer_get_count(const timer_dev *dev) { return (uint16)(dev->regs).bas->CNT; } @@ -637,7 +727,7 @@ static inline uint16 timer_get_count(timer_dev *dev) { * @param dev Timer whose counter to set * @param value New counter value */ -static inline void timer_set_count(timer_dev *dev, uint16 value) { +static inline void timer_set_count(const timer_dev *dev, uint16 value) { (dev->regs).bas->CNT = value; } @@ -653,7 +743,7 @@ static inline void timer_set_count(timer_dev *dev, uint16 value) { * @param dev Timer whose prescaler to return * @see timer_generate_update() */ -static inline uint16 timer_get_prescaler(timer_dev *dev) { +static inline uint16 timer_get_prescaler(const timer_dev *dev) { return (uint16)(dev->regs).bas->PSC; } @@ -667,7 +757,7 @@ static inline uint16 timer_get_prescaler(timer_dev *dev) { * @param psc New prescaler value * @see timer_generate_update() */ -static inline void timer_set_prescaler(timer_dev *dev, uint16 psc) { +static inline void timer_set_prescaler(const timer_dev *dev, uint16 psc) { (dev->regs).bas->PSC = psc; } @@ -675,7 +765,7 @@ static inline void timer_set_prescaler(timer_dev *dev, uint16 psc) { * @brief Returns a timer's reload value. * @param dev Timer whose reload value to return */ -static inline uint16 timer_get_reload(timer_dev *dev) { +static inline uint16 timer_get_reload(const timer_dev *dev) { return (uint16)(dev->regs).bas->ARR; } @@ -685,7 +775,7 @@ static inline uint16 timer_get_reload(timer_dev *dev) { * @param arr New reload value to use. Takes effect at next update event. * @see timer_generate_update() */ -static inline void timer_set_reload(timer_dev *dev, uint16 arr) { +static inline void timer_set_reload(const timer_dev *dev, uint16 arr) { (dev->regs).bas->ARR = arr; } @@ -694,8 +784,8 @@ static inline void timer_set_reload(timer_dev *dev, uint16 arr) { * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. * @param channel Channel whose compare value to get. */ -static inline uint16 timer_get_compare(timer_dev *dev, uint8 channel) { - __io uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); +static inline uint16 timer_get_compare(const timer_dev *dev, uint8 channel) { + __IO uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); return *ccr; } @@ -705,13 +795,19 @@ static inline uint16 timer_get_compare(timer_dev *dev, uint8 channel) { * @param channel Channel whose compare value to set. * @param value New compare value. */ -static inline void timer_set_compare(timer_dev *dev, +static inline void timer_set_compare(const timer_dev *dev, uint8 channel, uint16 value) { - __io uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); + __IO uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); *ccr = value; } +static inline void timer_set_master_mode(const timer_dev *dev, timer_mms_t value) +{ + uint32 cr2 = (dev->regs).bas->CR2 & (~TIMER_CR2_MMS); + (dev->regs).bas->CR2 = cr2 | value; +} + /** * @brief Generate an update event for the given timer. * @@ -722,7 +818,7 @@ static inline void timer_set_compare(timer_dev *dev, * * @param dev Timer device to generate an update for. */ -static inline void timer_generate_update(timer_dev *dev) { +static inline void timer_generate_update(const timer_dev *dev) { *bb_perip(&(dev->regs).bas->EGR, TIMER_EGR_UG_BIT) = 1; } @@ -730,7 +826,7 @@ static inline void timer_generate_update(timer_dev *dev) { * @brief Enable a timer's trigger DMA request * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL */ -static inline void timer_dma_enable_trg_req(timer_dev *dev) { +static inline void timer_dma_enable_trg_req(const timer_dev *dev) { *bb_perip(&(dev->regs).gen->DIER, TIMER_DIER_TDE_BIT) = 1; } @@ -738,16 +834,32 @@ static inline void timer_dma_enable_trg_req(timer_dev *dev) { * @brief Disable a timer's trigger DMA request * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL */ -static inline void timer_dma_disable_trg_req(timer_dev *dev) { +static inline void timer_dma_disable_trg_req(const timer_dev *dev) { *bb_perip(&(dev->regs).gen->DIER, TIMER_DIER_TDE_BIT) = 0; } +/** + * @brief Enable a timer's update DMA request + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL + */ +static inline void timer_dma_enable_upd_req(const timer_dev *dev) { + *bb_perip(&(dev->regs).gen->DIER, TIMER_DIER_UDE_BIT) = 1; +} + +/** + * @brief Disable a timer's update DMA request + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL + */ +static inline void timer_dma_disable_upd_req(const timer_dev *dev) { + *bb_perip(&(dev->regs).gen->DIER, TIMER_DIER_UDE_BIT) = 0; +} + /** * @brief Enable a timer channel's DMA request. * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL * @param channel Channel whose DMA request to enable. */ -static inline void timer_dma_enable_req(timer_dev *dev, uint8 channel) { +static inline void timer_dma_enable_req(const timer_dev *dev, uint8 channel) { *bb_perip(&(dev->regs).gen->DIER, channel + 8) = 1; } @@ -756,7 +868,7 @@ static inline void timer_dma_enable_req(timer_dev *dev, uint8 channel) { * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. * @param channel Channel whose DMA request to disable. */ -static inline void timer_dma_disable_req(timer_dev *dev, uint8 channel) { +static inline void timer_dma_disable_req(const timer_dev *dev, uint8 channel) { *bb_perip(&(dev->regs).gen->DIER, channel + 8) = 0; } @@ -768,7 +880,9 @@ static inline void timer_dma_disable_req(timer_dev *dev, uint8 channel) { * @see timer_interrupt_id * @see timer_channel */ -static inline void timer_enable_irq(timer_dev *dev, uint8 interrupt) { +static inline void timer_enable_irq(const timer_dev *dev, uint8 interrupt) { + // clear interrupt flag, use different masks for reserved bits + *bb_perip(&(dev->regs).adv->SR, interrupt) = 0; // clear interrupt flag *bb_perip(&(dev->regs).adv->DIER, interrupt) = 1; } @@ -780,7 +894,7 @@ static inline void timer_enable_irq(timer_dev *dev, uint8 interrupt) { * @see timer_interrupt_id * @see timer_channel */ -static inline void timer_disable_irq(timer_dev *dev, uint8 interrupt) { +static inline void timer_disable_irq(const timer_dev *dev, uint8 interrupt) { *bb_perip(&(dev->regs).adv->DIER, interrupt) = 0; } @@ -795,7 +909,7 @@ static inline void timer_disable_irq(timer_dev *dev, uint8 interrupt) { * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. * @param channel Channel to enable, from 1 to 4. */ -static inline void timer_cc_enable(timer_dev *dev, uint8 channel) { +static inline void timer_cc_enable(const timer_dev *dev, uint8 channel) { *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1)) = 1; } @@ -805,7 +919,7 @@ static inline void timer_cc_enable(timer_dev *dev, uint8 channel) { * @param channel Channel to disable, from 1 to 4. * @see timer_cc_enable() */ -static inline void timer_cc_disable(timer_dev *dev, uint8 channel) { +static inline void timer_cc_disable(const timer_dev *dev, uint8 channel) { *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1)) = 0; } @@ -816,7 +930,7 @@ static inline void timer_cc_disable(timer_dev *dev, uint8 channel) { * @return Polarity, either 0 or 1. * @see timer_cc_set_polarity() */ -static inline uint8 timer_cc_get_pol(timer_dev *dev, uint8 channel) { +static inline uint8 timer_cc_get_pol(const timer_dev *dev, uint8 channel) { return *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1) + 1); } @@ -837,27 +951,28 @@ static inline uint8 timer_cc_get_pol(timer_dev *dev, uint8 channel) { * @param channel Channel whose capture/compare output polarity to set. * @param pol New polarity, 0 or 1. */ -static inline void timer_cc_set_pol(timer_dev *dev, uint8 channel, uint8 pol) { +static inline void timer_cc_set_pol(const timer_dev *dev, uint8 channel, uint8 pol) { *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1) + 1) = pol; } /** * @brief Get a timer's DMA burst length. * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @return Number of bytes to be transferred per DMA request, from 1 to 18. + * @return Number of transfers per read or write to timer DMA register, + * from 1 to 18. */ -static inline uint8 timer_dma_get_burst_len(timer_dev *dev) { +static inline uint8 timer_dma_get_burst_len(const timer_dev *dev) { uint32 dbl = ((dev->regs).gen->DCR & TIMER_DCR_DBL) >> 8; - return dbl + 1; /* 0 means 1 byte, etc. */ + return dbl + 1; /* 0 means 1 transfer, etc. */ } /** * @brief Set a timer's DMA burst length. * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param length DMA burst length; i.e., number of bytes to transfer - * per DMA request, from 1 to 18. + * @param length DMA burst length; i.e., number of DMA transfers per + * read/write to timer DMA register, from 1 to 18. */ -static inline void timer_dma_set_burst_len(timer_dev *dev, uint8 length) { +static inline void timer_dma_set_burst_len(const timer_dev *dev, uint8 length) { uint32 tmp = (dev->regs).gen->DCR; tmp &= ~TIMER_DCR_DBL; tmp |= (length - 1) << 8; @@ -869,53 +984,39 @@ static inline void timer_dma_set_burst_len(timer_dev *dev, uint8 length) { * * Defines the base address for DMA transfers. */ -typedef enum timer_dma_base_addr { - TIMER_DMA_BASE_CR1 = TIMER_DCR_DBA_CR1, /**< Base is control register 1 */ - TIMER_DMA_BASE_CR2 = TIMER_DCR_DBA_CR2, /**< Base is control register 2 */ - TIMER_DMA_BASE_SMCR = TIMER_DCR_DBA_SMCR, /**< Base is slave mode - control register */ - TIMER_DMA_BASE_DIER = TIMER_DCR_DBA_DIER, /**< Base is DMA interrupt enable - register */ - TIMER_DMA_BASE_SR = TIMER_DCR_DBA_SR, /**< Base is status register */ - TIMER_DMA_BASE_EGR = TIMER_DCR_DBA_EGR, /**< Base is event generation - register */ - TIMER_DMA_BASE_CCMR1 = TIMER_DCR_DBA_CCMR1, /**< Base is capture/compare - mode register 1 */ - TIMER_DMA_BASE_CCMR2 = TIMER_DCR_DBA_CCMR2, /**< Base is capture/compare - mode register 2 */ - TIMER_DMA_BASE_CCER = TIMER_DCR_DBA_CCER, /**< Base is capture/compare - enable register */ +typedef enum timer_dma_base_addr +{ + TIMER_DMA_BASE_CR1 = TIMER_DCR_DBA_CR1, /**< Base is control register 1 */ + TIMER_DMA_BASE_CR2 = TIMER_DCR_DBA_CR2, /**< Base is control register 2 */ + TIMER_DMA_BASE_SMCR = TIMER_DCR_DBA_SMCR, /**< Base is slave mode control register */ + TIMER_DMA_BASE_DIER = TIMER_DCR_DBA_DIER, /**< Base is DMA interrupt enable register */ + TIMER_DMA_BASE_SR = TIMER_DCR_DBA_SR, /**< Base is status register */ + TIMER_DMA_BASE_EGR = TIMER_DCR_DBA_EGR, /**< Base is event generation register */ + TIMER_DMA_BASE_CCMR1 = TIMER_DCR_DBA_CCMR1, /**< Base is capture/compare mode register 1 */ + TIMER_DMA_BASE_CCMR2 = TIMER_DCR_DBA_CCMR2, /**< Base is capture/compare mode register 2 */ + TIMER_DMA_BASE_CCER = TIMER_DCR_DBA_CCER, /**< Base is capture/compare enable register */ TIMER_DMA_BASE_CNT = TIMER_DCR_DBA_CNT, /**< Base is counter */ TIMER_DMA_BASE_PSC = TIMER_DCR_DBA_PSC, /**< Base is prescaler */ - TIMER_DMA_BASE_ARR = TIMER_DCR_DBA_ARR, /**< Base is auto-reload - register */ - TIMER_DMA_BASE_RCR = TIMER_DCR_DBA_RCR, /**< Base is repetition - counter register */ - TIMER_DMA_BASE_CCR1 = TIMER_DCR_DBA_CCR1, /**< Base is capture/compare - register 1 */ - TIMER_DMA_BASE_CCR2 = TIMER_DCR_DBA_CCR2, /**< Base is capture/compare - register 2 */ - TIMER_DMA_BASE_CCR3 = TIMER_DCR_DBA_CCR3, /**< Base is capture/compare - register 3 */ - TIMER_DMA_BASE_CCR4 = TIMER_DCR_DBA_CCR4, /**< Base is capture/compare - register 4 */ - TIMER_DMA_BASE_BDTR = TIMER_DCR_DBA_BDTR, /**< Base is break and - dead-time register */ - TIMER_DMA_BASE_DCR = TIMER_DCR_DBA_DCR, /**< Base is DMA control - register */ - TIMER_DMA_BASE_DMAR = TIMER_DCR_DBA_DMAR /**< Base is DMA address for - full transfer */ + TIMER_DMA_BASE_ARR = TIMER_DCR_DBA_ARR, /**< Base is auto-reload register */ + TIMER_DMA_BASE_RCR = TIMER_DCR_DBA_RCR, /**< Base is repetition counter register */ + TIMER_DMA_BASE_CCR1 = TIMER_DCR_DBA_CCR1, /**< Base is capture/compare register 1 */ + TIMER_DMA_BASE_CCR2 = TIMER_DCR_DBA_CCR2, /**< Base is capture/compare register 2 */ + TIMER_DMA_BASE_CCR3 = TIMER_DCR_DBA_CCR3, /**< Base is capture/compare register 3 */ + TIMER_DMA_BASE_CCR4 = TIMER_DCR_DBA_CCR4, /**< Base is capture/compare register 4 */ + TIMER_DMA_BASE_BDTR = TIMER_DCR_DBA_BDTR, /**< Base is break and dead-time register */ + TIMER_DMA_BASE_DCR = TIMER_DCR_DBA_DCR, /**< Base is DMA control register */ + TIMER_DMA_BASE_DMAR = TIMER_DCR_DBA_DMAR /**< Base is DMA address for full transfer */ } timer_dma_base_addr; /** * @brief Get the timer's DMA base address. * - * Some restrictions apply; see ST RM0008. + * Some restrictions apply; see the reference manual for your chip. * * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. * @return DMA base address */ -static inline timer_dma_base_addr timer_dma_get_base_addr(timer_dev *dev) { +static inline timer_dma_base_addr timer_dma_get_base_addr(const timer_dev *dev) { uint32 dcr = (dev->regs).gen->DCR; return (timer_dma_base_addr)(dcr & TIMER_DCR_DBA); } @@ -923,12 +1024,12 @@ static inline timer_dma_base_addr timer_dma_get_base_addr(timer_dev *dev) { /** * @brief Set the timer's DMA base address. * - * Some restrictions apply; see ST RM0008. + * Some restrictions apply; see the reference manual for your chip. * * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. * @param dma_base DMA base address. */ -static inline void timer_dma_set_base_addr(timer_dev *dev, +static inline void timer_dma_set_base_addr(const timer_dev *dev, timer_dma_base_addr dma_base) { uint32 tmp = (dev->regs).gen->DCR; tmp &= ~TIMER_DCR_DBA; @@ -941,34 +1042,23 @@ static inline void timer_dma_set_base_addr(timer_dev *dev, */ typedef enum timer_oc_mode { TIMER_OC_MODE_FROZEN = 0 << 4, /**< Frozen: comparison between output - compare register and counter has no - effect on the outputs. */ + compare register and counter has no effect on the outputs. */ TIMER_OC_MODE_ACTIVE_ON_MATCH = 1 << 4, /**< OCxREF signal is forced - high when the count matches - the channel capture/compare - register. */ + high when the count matches the channel capture/compare register. */ TIMER_OC_MODE_INACTIVE_ON_MATCH = 2 << 4, /**< OCxREF signal is forced - low when the counter matches - the channel capture/compare - register. */ + low when the counter matches the channel capture/compare register. */ TIMER_OC_MODE_TOGGLE = 3 << 4, /**< OCxREF toggles when counter - matches the cannel capture/compare - register. */ + matches the cannel capture/compare register. */ TIMER_OC_MODE_FORCE_INACTIVE = 4 << 4, /**< OCxREF is forced low. */ TIMER_OC_MODE_FORCE_ACTIVE = 5 << 4, /**< OCxREF is forced high. */ TIMER_OC_MODE_PWM_1 = 6 << 4, /**< PWM mode 1. In upcounting, channel is - active as long as count is less than - channel capture/compare register, else - inactive. In downcounting, channel is - inactive as long as count exceeds - capture/compare register, else - active. */ + active as long as count is less than channel capture/compare register, + else inactive. In downcounting, channel is inactive as long as count + exceeds capture/compare register, else active. */ TIMER_OC_MODE_PWM_2 = 7 << 4 /**< PWM mode 2. In upcounting, channel is - inactive as long as count is less than - capture/compare register, else active. - In downcounting, channel is active as - long as count exceeds capture/compare - register, else inactive. */ + inactive as long as count is less than capture/compare register, + else active. In downcounting, channel is active as long as count + exceeds capture/compare register, else inactive. */ } timer_oc_mode; /** @@ -991,24 +1081,43 @@ typedef enum timer_oc_mode_flags { * @see timer_oc_mode * @see timer_oc_mode_flags */ -static inline void timer_oc_set_mode(timer_dev *dev, +static inline void timer_oc_set_mode(const timer_dev *dev, uint8 channel, timer_oc_mode mode, uint8 flags) { - uint8 bit0 = channel & 1; - //uint8 bit1 = (channel >> 1) & 1; // original - uint8 bit1 = ((channel-1) >> 1) & 1; // fixed /* channel == 1,2 -> CCMR1; channel == 3,4 -> CCMR2 */ - __io uint32 *ccmr = &(dev->regs).gen->CCMR1 + bit1; + __IO uint32 *ccmr = &(dev->regs).gen->CCMR1 + (((channel - 1) >> 1) & 1); /* channel == 1,3 -> shift = 0, channel == 2,4 -> shift = 8 */ - uint8 shift = 8 * (1 - bit0); + uint8 shift = 8 * (1 - (channel & 1)); uint32 tmp = *ccmr; tmp &= ~(0xFF << shift); - tmp |= (mode | flags | TIMER_CCMR_CCS_OUTPUT) << shift; + tmp |= (mode | flags) << shift; *ccmr = tmp; } +static inline void timer_set_cc_mode(const timer_dev *dev, + timer_channel channel, + uint8 cc_mode, + uint8 flags) +{ + timer_oc_set_mode(dev, channel, (timer_oc_mode)cc_mode, flags); + timer_cc_enable(dev, channel); +} + + +/** + * Timer output compare modes. + */ +typedef enum timer_ic_input_select { + TIMER_IC_INPUT_DEFAULT = TIMER_CCMR_CCS_INPUT_TI1, + TIMER_IC_INPUT_SWITCH = TIMER_CCMR_CCS_INPUT_TI2, + TIMER_IC_INPUT_TRC = TIMER_CCMR_CCS_INPUT_TRC, +} timer_ic_input_select; + +extern void input_capture_mode(const timer_dev *dev, uint8 channel, timer_ic_input_select input); + + #ifdef __cplusplus } // extern "C" #endif diff --git a/STM32F4/cores/maple/libmaple/timer_map.c b/STM32F4/cores/maple/libmaple/timer_map.c new file mode 100644 index 000000000..ed31fc3bd --- /dev/null +++ b/STM32F4/cores/maple/libmaple/timer_map.c @@ -0,0 +1,143 @@ +/** + * @file timer_map.c + * @author stevestrong + * @brief Mapping of the pins to timer device and channel. + */ + + +#include "timer.h" + + +const timer_dev * const timer_devices[] = { +NULL, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5, TIMER6, TIMER7, TIMER8, TIMER9, TIMER10, TIMER11, TIMER12, TIMER13, TIMER14 +}; + +/* +typedef struct timer_info { + uint8_t index; // Pin's timer device, if any. + uint8_t channel; // Timer channel, or 0 if none. +} timer_info; +*/ + +const timer_info timer_map[] = +{ +{TIM5, 1}, // PA0 | 23 | USART2_CTS | UART4_TX | ETH_MII_CRS | TIM2_CH1_ETR | TIM5_CH1 | TIM8_ETR | ADC123_IN0/WKUP +{TIM5, 2}, // PA1 | 24 | USART2_RTS | UART4_RX | ETH_RMII_REF_CLK | ETH_MII_RX_CLK | TIM5_CH2 | TIM2_CH2 | ADC123_IN1 +{TIM5, 3}, // PA2 | 25 | USART2_TX | TIM5_CH3 | TIM9_CH1 | TIM2_CH3 | ETH_MDIO | ADC123_IN2 +{TIM5, 4}, // PA3 | 26 | USART2_RX | TIM5_CH4 | TIM9_CH2 | TIM2_CH4 | OTG_HS_ULPI_D0 | ETH_MII_COL | ADC123_IN3 +{NULL, 0}, // PA4 | 29 | SPI1_NSS | SPI3_NSS | USART2_CK | DCMI_HSYNC | OTG_HS_SOF | I2S3_WS | ADC12_IN4 / DAC_OUT1 +{NULL, 0}, // PA5 | 30 | SPI1_SCK | OTG_HS_ULPI_CK | TIM2_CH1_ETR | TIM8_CH1N | ADC12_IN5 / DAC_OUT2 +{TIM3, 1}, // PA6 | 31 | SPI1_MISO | TIM8_BKIN | TIM13_CH1 | DCMI_PIXCLK | TIM3_CH1 | TIM1_BKIN | ADC12_IN6 +{TIM3, 2}, // PA7 | 32 | SPI1_MOSI | TIM8_CH1N | TIM14_CH1 | TIM3_CH2 | ETH_MII_RX_DV | TIM1_CH1N / ETH_RMII_CRS_DV | ADC12_IN7 +{TIM1, 1}, // PA8 | 67 | MCO1 | USART1_CK | TIM1_CH1 | I2C3_SCL | OTG_FS_SOF +{TIM1, 2}, // PA9 | 68 | USART1_TX | TIM1_CH2 | I2C3_SMBA | DCMI_D0 +{TIM1, 3}, // PA10 | 69 | USART1_RX | TIM1_CH3 | OTG_FS_ID | DCMI_D1 +{TIM1, 4}, // PA11 | 70 | USART1_CTS | CAN1_RX | TIM1_CH4 | OTG_FS_DM +{NULL, 0}, // PA12 | 71 | USART1_RTS | CAN1_TX | TIM1_ETR | OTG_FS_DP +{NULL, 0}, // PA13 | 72 | JTMS-SWDIO +{NULL, 0}, // PA14 | 76 | JTCK-SWCLK +{TIM2, 1}, // PA15 | 77 | JTDI | SPI3_NSS | I2S3_WS | TIM2_CH1_ETR | SPI1_NSS + +{TIM3, 3}, // PB0 | 35 | TIM3_CH3 | TIM8_CH2N | OTG_HS_ULPI_D1 | ETH_MII_RXD2 | TIM1_CH2N | ADC12_IN8 +{TIM3, 4}, // PB1 | 36 | TIM3_CH4 | TIM8_CH3N | OTG_HS_ULPI_D2 | ETH_MII_RXD3 | TIM1_CH3N | ADC12_IN9 +{NULL, 0}, // PB2 | 37 | BOOT1 +{TIM2, 2}, // PB3 | 89 | JTDO | TRACESWO | SPI3_SCK | I2S3_CK | TIM2_CH2 | SPI1_SCK +{TIM3, 1}, // PB4 | 90 | NJTRST | SPI3_MISO | TIM3_CH1 | SPI1_MISO | I2S3ext_SD +{TIM3, 2}, // PB5 | 91 | I2C1_SMBA | CAN2_RX | OTG_HS_ULPI_D7 | ETH_PPS_OUT | TIM3_CH2 | SPI1_MOSI | SPI3_MOSI | DCMI_D10 | I2S3_SD +{TIM4, 1}, // PB6 | 92 | I2C1_SCL | TIM4_CH1 | CAN2_TX | DCMI_D5 | USART1_TX +{TIM4, 2}, // PB7 | 93 | I2C1_SDA | FSMC_NL | DCMI_VSYNC | USART1_RX | TIM4_CH2 +{TIM4, 3}, // PB8 | 95 | TIM4_CH3 | SDIO_D4 | TIM10_CH1 | DCMI_D6 | ETH_MII_TXD3 | I2C1_SCL | CAN1_RX +{TIM4, 4}, // PB9 | 96 | SPI2_NSS | I2S2_WS | TIM4_CH4 | TIM11_CH1 | SDIO_D5 | DCMI_D7 | I2C1_SDA | CAN1_TX +{NULL, 0}, // PB10 | 47 | SPI2_SCK | I2S2_CK | I2C2_SCL | USART3_TX | OTG_HS_ULPI_D3 | ETH_MII_RX_ER | TIM2_CH3 +{NULL, 0}, // PB11 | 48 | I2C2_SDA | USART3_RX | OTG_HS_ULPI_D4 | ETH_RMII_TX_EN | ETH_MII_TX_EN | TIM2_CH4 +{NULL, 0}, // PB12 | 51 | SPI2_NSS | I2S2_WS | I2C2_SMBA | USART3_CK | TIM1_BKIN | CAN2_RX | OTG_HS_ULPI_D5 | ETH_RMII_TXD0 | ETH_MII_TXD0 | OTG_HS_ID +{NULL, 0}, // PB13 | 52 | SPI2_SCK | I2S2_CK | USART3_CTS | TIM1_CH1N | CAN2_TX | OTG_HS_ULPI_D6 | ETH_RMII_TXD1 | ETH_MII_TXD1 +{NULL, 0}, // PB14 | 53 | SPI2_MISO | TIM1_CH2N | TIM12_CH1 | OTG_HS_DM | USART3_RTS | TIM8_CH2N | I2S2ext_SD +{NULL, 0}, // PB15 | 54 | SPI2_MOSI | I2S2_SD | TIM1_CH3N | TIM8_CH3N | TIM12_CH2 | OTG_HS_DP + +{NULL, 0}, // PC0 | 15 | OTG_HS_ULPI_STP | ADC123_IN10 +{NULL, 0}, // PC1 | 16 | ETH_MDC | ADC123_IN11 +{NULL, 0}, // PC2 | 17 | SPI2_MISO | OTG_HS_ULPI_DIR | ETH_MII_TXD2 | I2S2ext_SD | ADC123_IN12 +{NULL, 0}, // PC3 | 18 | SPI2_MOSI | I2S2_SD | OTG_HS_ULPI_NXT | ETH_MII_TX_CLK | ADC123_IN13 +{NULL, 0}, // PC4 | 33 | ETH_RMII_RX_D0 | ETH_MII_RX_D0 | ADC12_IN14 +{NULL, 0}, // PC5 | 34 | ETH_RMII_RX_D1 | ETH_MII_RX_D1 | ADC12_IN15 +{TIM8, 1}, // PC6 | 63 | I2S2_MCK | TIM8_CH1/SDIO_D6 | USART6_TX | DCMI_D0 | TIM3_CH1 +{TIM8, 2}, // PC7 | 64 | I2S3_MCK | TIM8_CH2/SDIO_D7 | USART6_RX | DCMI_D1 | TIM3_CH2 +{TIM8, 3}, // PC8 | 65 | TIM8_CH3 | SDIO_D0 | TIM3_CH3 | USART6_CK | DCMI_D2 +{TIM8, 4}, // PC9 | 66 | I2S_CKIN | MCO2 | TIM8_CH4 | SDIO_D1 | I2C3_SDA | DCMI_D3 | TIM3_CH4 +{NULL, 0}, // PC10 | 78 | SPI3_SCK | I2S3_CK | UART4_TX | SDIO_D2 | DCMI_D8 | USART3_TX +{NULL, 0}, // PC11 | 79 | UART4_RX | SPI3_MISO | SDIO_D3 | DCMI_D4 | USART3_RX | I2S3ext_SD +{NULL, 0}, // PC12 | 80 | UART5_TX | SDIO_CK | DCMI_D9 | SPI3_MOSI | I2S3_SD | USART3_CK +{NULL, 0}, // PC13 | 7 | RTC_OUT, RTC_TAMP1, RTC_TS +{NULL, 0}, // PC14 | 8 | OSC32_IN +{NULL, 0}, // PC15 | 9 | OSC32_OUT + +{NULL, 0}, // PD0 | 81 | FSMC_D2 | CAN1_RX +{NULL, 0}, // PD1 | 82 | FSMC_D3 | CAN1_TX +{NULL, 0}, // PD2 | 83 | TIM3_ETR | UART5_RX | SDIO_CMD | DCMI_D11 +{NULL, 0}, // PD3 | 84 | FSMC_CLK | USART2_CTS +{NULL, 0}, // PD4 | 85 | FSMC_NOE | USART2_RTS +{NULL, 0}, // PD5 | 86 | FSMC_NWE | USART2_TX +{NULL, 0}, // PD6 | 87 | FSMC_NWAIT | USART2_RX +{NULL, 0}, // PD7 | 88 | USART2_CK | FSMC_NE1 | FSMC_NCE2 +{NULL, 0}, // PD8 | 55 | FSMC_D13 | USART3_TX +{NULL, 0}, // PD9 | 56 | FSMC_D14 | USART3_RX +{NULL, 0}, // PD10 | 57 | FSMC_D15 | USART3_CK +{NULL, 0}, // PD11 | 58 | FSMC_CLE | FSMC_A16 | USART3_CTS +{TIM4, 1}, // PD12 | 59 | FSMC_ALE | FSMC_A17 | TIM4_CH1 | USART3_RTS // remap in +{TIM4, 2}, // PD13 | 60 | FSMC_A18 | TIM4_CH2 // remap in +{TIM4, 3}, // PD14 | 61 | FSMC_D0 | TIM4_CH3 // remap in +{TIM4, 4}, // PD15 | 62 | FSMC_D1 | TIM4_CH4 // remap in + +{NULL, 0}, // PE0 | 97 | TIM4_ETR | FSMC_NBL0 | DCMI_D2 +{NULL, 0}, // PE1 | 98 | FSMC_NBL1 | DCMI_D3 +{NULL, 0}, // PE2 | 1 | TRACECLK | FSMC_A23 | ETH_MII_TXD3 +{NULL, 0}, // PE3 | 2 | TRACED0 | FSMC_A19 +{NULL, 0}, // PE4 | 3 | TRACED1 | FSMC_A20 | DCMI_D4 +{TIM9, 1}, // PE5 | 4 | TRACED2 | FSMC_A21 | TIM9_CH1 / DCMI_D6 +{TIM9, 2}, // PE6 | 5 | TRACED3 | FSMC_A22 | TIM9_CH2 / DCMI_D7 +{NULL, 0}, // PE7 | 38 | FSMC_D4 | TIM1_ETR +{NULL, 0}, // PE8 | 39 | FSMC_D5 | TIM1_CH1N +{TIM1, 1}, // PE9 | 40 | FSMC_D6 | TIM1_CH1 // remap in +{NULL, 0}, // PE10 | 41 | FSMC_D7 | TIM1_CH2N +{TIM1, 2}, // PE11 | 42 | FSMC_D8 | TIM1_CH2 // remap in +{NULL, 0}, // PE12 | 43 | FSMC_D9 | TIM1_CH3N +{TIM1, 3}, // PE13 | 44 | FSMC_D10 | TIM1_CH3 // remap in +{TIM1, 4}, // PE14 | 45 | FSMC_D11 | TIM1_CH4 // remap in +{NULL, 0}, // PE15 | 46 | FSMC_D12 | TIM1_BKIN +#ifdef PACKAGE_LQFP144 // not available on LQFP100 package +{ NULL, 0}, // PF0 +{ NULL, 0}, // PF1 +{ NULL, 0}, // PF2 +{ NULL, 0}, // PF3 +{ NULL, 0}, // PF4 +{ NULL, 0}, // PF5 +{TIM10, 1}, // PF6 +{TIM11, 1}, // PF7 +{TIM13, 1}, // PF8 +{TIM14, 1}, // PF9 +{ NULL, 0}, // PF10 +{ NULL, 0}, // PF11 +{ NULL, 0}, // PF12 +{ NULL, 0}, // PF13 +{ NULL, 0}, // PF14 +{ NULL, 0}, // PF15 + +{ NULL, 0}, // PG0 +{ NULL, 0}, // PG1 +{ NULL, 0}, // PG2 +{ NULL, 0}, // PG3 +{ NULL, 0}, // PG4 +{ NULL, 0}, // PG5 +{ NULL, 0}, // PG6 +{ NULL, 0}, // PG7 +{ NULL, 0}, // PG8 +{ NULL, 0}, // PG9 +{ NULL, 0}, // PG10 +{ NULL, 0}, // PG11 +{ NULL, 0}, // PG12 +{ NULL, 0}, // PG13 +{ NULL, 0}, // PG14 +{ NULL, 0} // PG15 +#endif +}; diff --git a/STM32F4/cores/maple/libmaple/usart.c b/STM32F4/cores/maple/libmaple/usart.c index 48c0eabb7..23bb212c6 100644 --- a/STM32F4/cores/maple/libmaple/usart.c +++ b/STM32F4/cores/maple/libmaple/usart.c @@ -37,53 +37,53 @@ /* * Devices */ - -static usart_dev usart1 = { +/** USART1 device */ +usart_dev usart1 = { .regs = USART1_BASE, - .max_baud = 4500000UL, + .max_baud = 5250000UL, .clk_id = RCC_USART1, .irq_num = NVIC_USART1 }; -/** USART1 device */ -usart_dev *USART1 = &usart1; -static usart_dev usart2 = { +/** USART2 device */ +usart_dev usart2 = { .regs = USART2_BASE, - .max_baud = 2250000UL, + .max_baud = 2620000UL, .clk_id = RCC_USART2, .irq_num = NVIC_USART2 }; -/** USART2 device */ -usart_dev *USART2 = &usart2; -static usart_dev usart3 = { +/** USART3 device */ +usart_dev usart3 = { .regs = USART3_BASE, - .max_baud = 2250000UL, + .max_baud = 2620000UL, .clk_id = RCC_USART3, .irq_num = NVIC_USART3 }; -/** USART3 device */ -usart_dev *USART3 = &usart3; -#ifdef STM32_HIGH_DENSITY -static usart_dev uart4 = { +/** UART4 device */ +usart_dev uart4 = { .regs = UART4_BASE, - .max_baud = 2250000UL, + .max_baud = 2620000UL, .clk_id = RCC_UART4, .irq_num = NVIC_UART4 }; -/** UART4 device */ -usart_dev *UART4 = &uart4; -static usart_dev uart5 = { +/** UART5 device */ +usart_dev uart5 = { .regs = UART5_BASE, - .max_baud = 2250000UL, + .max_baud = 2620000UL, .clk_id = RCC_UART5, .irq_num = NVIC_UART5 }; -/** UART5 device */ -usart_dev *UART5 = &uart5; -#endif + +/** USART6 device */ +usart_dev usart6 = { + .regs = USART6_BASE, + .max_baud = 5250000UL, + .clk_id = RCC_USART6, + .irq_num = NVIC_USART6 +}; /** * @brief Initialize a serial port. @@ -96,6 +96,19 @@ void usart_init(usart_dev *dev) { nvic_irq_enable(dev->irq_num); } +void usart_set_parity(usart_dev *dev, uint16_t odd) +{ + uint32_t cr1 = dev->regs->CR1 & (~USART_CR1_PS); + if (odd) cr1 |= USART_CR1_PS_ODD; + dev->regs->CR1 = cr1 | USART_CR1_PCE; +} + +void usart_set_stop_bits(usart_dev *dev, uint16_t stop_bits) +{ + uint32_t cr2 = dev->regs->CR2 & (~USART_CR2_STOP); + dev->regs->CR2 = cr2 | (stop_bits)<dev.pConfig_descriptor + 57) +#define CDC_DATA_IN_PACKET_SIZE CDC_DATA_MAX_PACKET_SIZE -#define CDC_DATA_OUT_PACKET_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 64) +#define CDC_DATA_OUT_PACKET_SIZE CDC_DATA_MAX_PACKET_SIZE /*---------------------------------------------------------------------*/ /* CDC definitions */ @@ -89,10 +89,10 @@ */ typedef struct _CDC_IF_PROP { - uint16_t (*pIf_Init) (void); + uint16_t (*pIf_Init) (void *pdev); uint16_t (*pIf_DeInit) (void); uint16_t (*pIf_Ctrl) (uint32_t Cmd, uint8_t* Buf, uint32_t Len); - uint16_t (*pIf_DataTx) (uint8_t* Buf, uint32_t Len); + uint32_t (*pIf_DataTx) (const uint8_t* Buf, uint32_t Len); uint16_t (*pIf_DataRx) (uint8_t* Buf, uint32_t Len); } CDC_IF_Prop_TypeDef; diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h index 1a12508e6..cdd14299f 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h @@ -24,11 +24,6 @@ #define __USBD_CDC_IF_TEMPLATE_H /* Includes ------------------------------------------------------------------*/ -#ifdef STM32F2XX - #include "stm32f2xx.h" -#elif defined(STM32F10X_CL) - #include "stm32f10x.h" -#endif /* STM32F2XX */ #include "usbd_conf.h" #include "usbd_cdc_core.h" diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c index 8963a8a2a..e2b1e3acb 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c @@ -129,21 +129,21 @@ static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length); * @{ */ extern CDC_IF_Prop_TypeDef APP_FOPS; -extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC]; +extern uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC]; #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 #endif #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ; +__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ; #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 #endif #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ; +__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ; #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED #if defined ( __ICCARM__ ) /*!< IAR Compiler */ @@ -157,14 +157,17 @@ __ALIGN_BEGIN static __IO uint32_t usbd_cdc_AltSet __ALIGN_END = 0; #pragma data_alignment=4 #endif #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t USB_Rx_Buffer [CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ; +__ALIGN_BEGIN uint8_t __CCMRAM__ USB_Rx_Buffer[CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ; #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 #endif +__ALIGN_BEGIN uint8_t APP_Tx_Buffer [APP_TX_DATA_SIZE] __ALIGN_END ; +#else +__ALIGN_BEGIN uint8_t __CCMRAM__ APP_Tx_Buffer[APP_TX_DATA_SIZE] __ALIGN_END ; #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE] __ALIGN_END ; + #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED @@ -174,9 +177,8 @@ __ALIGN_BEGIN uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE] __ALIGN_END ; #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ __ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ; -volatile int APP_Rx_ptr_in = 0; -volatile int APP_Rx_ptr_out = 0; -uint32_t APP_Rx_length = 0; +volatile uint16_t APP_Tx_ptr_in = 0; +volatile uint16_t APP_Tx_ptr_out = 0; uint8_t USB_Tx_State = 0; @@ -315,7 +317,7 @@ __ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ __ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, USB_CDC_CONFIG_DESC_SIZ, 0x00, @@ -416,7 +418,7 @@ __ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_EN /** * @brief usbd_cdc_Init - * Initilaize the CDC interface + * Initialize the CDC interface * @param pdev: device instance * @param cfgidx: Configuration index * @retval status @@ -449,7 +451,7 @@ static uint8_t usbd_cdc_Init (void *pdev, pbuf[5] = DEVICE_SUBCLASS_CDC; /* Initialize the Interface physical components */ - APP_FOPS.pIf_Init(); + APP_FOPS.pIf_Init(pdev); /* Prepare Out endpoint to receive next packet */ DCD_EP_PrepareRx(pdev, @@ -498,9 +500,6 @@ static uint8_t usbd_cdc_DeInit (void *pdev, static uint8_t usbd_cdc_Setup (void *pdev, USB_SETUP_REQ *req) { - uint16_t len; - uint8_t *pbuf; - switch (req->bmRequest & USB_REQ_TYPE_MASK) { /* CDC Class Requests -------------------------------*/ @@ -519,7 +518,7 @@ static uint8_t usbd_cdc_Setup (void *pdev, CmdBuff, req->wLength); } - else /* Host-to-Device requeset */ + else /* Host-to-Device request */ { /* Set the value of the current command to be processed */ cdcCmd = req->bRequest; @@ -545,8 +544,6 @@ static uint8_t usbd_cdc_Setup (void *pdev, USBD_CtlError (pdev, req); return USBD_FAIL; - - /* Standard Requests -------------------------------*/ case USB_REQ_TYPE_STANDARD: switch (req->bRequest) @@ -554,16 +551,17 @@ static uint8_t usbd_cdc_Setup (void *pdev, case USB_REQ_GET_DESCRIPTOR: if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE) { + uint8_t *pbuf; #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED pbuf = usbd_cdc_Desc; #else pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM); #endif - len = MIN(USB_CDC_DESC_SIZ , req->wLength); + uint16_t len = MIN(USB_CDC_DESC_SIZ , req->wLength); - USBD_CtlSendData (pdev, - pbuf, - len); + USBD_CtlSendData (pdev, + pbuf, + len); } break; @@ -592,7 +590,7 @@ static uint8_t usbd_cdc_Setup (void *pdev, /** * @brief usbd_cdc_EP0_RxReady * Data received on control endpoint - * @param pdev: device device instance + * @param pdev: device instance * @retval status */ static uint8_t usbd_cdc_EP0_RxReady (void *pdev) @@ -616,139 +614,86 @@ static uint8_t usbd_cdc_EP0_RxReady (void *pdev) * @param epnum: endpoint number * @retval status */ -#if 0 -static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum) -{ - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if (USB_Tx_State == 1) - { - if (APP_Rx_length == 0) - { - USB_Tx_State = 0; - } - else - { - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){ - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - } - - /* Prepare the available data buffer to be sent on IN endpoint */ - DCD_EP_Tx (pdev, - CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], - USB_Tx_length); - } - } - - return USBD_OK; -} -#endif - // ala42: applied fix from //https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2f //STe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fUSB%20CDC%20Device%20hung%20fix& //FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=75 static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum) { - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; + if (USB_Tx_State == 0) return USBD_OK; - if (USB_Tx_State == 1) - { - if (APP_Rx_length == 0) + uint16_t USB_Tx_ptr = APP_Tx_ptr_out; + uint16_t USB_Tx_length = (APP_Tx_ptr_in - USB_Tx_ptr) & APP_TX_DATA_SIZE_MASK; + if (USB_Tx_length == 0) + { + //USB_Tx_State = 0; + if (((USB_OTG_CORE_HANDLE*)pdev)->dev.in_ep[epnum].xfer_len != CDC_DATA_IN_PACKET_SIZE) + { + USB_Tx_State = 0; + return USBD_OK; + } + /* Transmit zero sized packet in case the last one has maximum allowed size. Otherwise + * the recipient may expect more data coming soon and not return buffered data to app. + * See section 5.8.3 Bulk Transfer Packet Size Constraints + * of the USB Specification document. + */ + } + + if (USB_Tx_length > CDC_DATA_IN_PACKET_SIZE) { - if (((USB_OTG_CORE_HANDLE*)pdev)->dev.in_ep[epnum].xfer_len != CDC_DATA_IN_PACKET_SIZE) - { - USB_Tx_State = 0; - return USBD_OK; - } - /* Transmit zero sized packet in case the last one has maximum allowed size. Otherwise - * the recipient may expect more data coming soon and not return buffered data to app. - * See section 5.8.3 Bulk Transfer Packet Size Constraints - * of the USB Specification document. - */ - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = 0; + USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; } - else + if ( USB_Tx_length > (APP_TX_DATA_SIZE - USB_Tx_ptr) ) { - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){ - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - } + USB_Tx_length = (APP_TX_DATA_SIZE - USB_Tx_ptr); } + APP_Tx_ptr_out = (USB_Tx_ptr + USB_Tx_length) & APP_TX_DATA_SIZE_MASK; + /* Prepare the available data buffer to be sent on IN endpoint */ DCD_EP_Tx (pdev, CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], + (uint8_t*)&APP_Tx_Buffer[USB_Tx_ptr], USB_Tx_length); - } return USBD_OK; } +void usbd_cdc_PrepareRx (void *pdev) +{ + DCD_EP_PrepareRx(pdev, CDC_OUT_EP, USB_Rx_Buffer, CDC_DATA_OUT_PACKET_SIZE); +} /** - * @brief usbd_audio_DataOut + * @brief usbd_cdc_DataOut * Data received on non-control Out endpoint * @param pdev: device instance * @param epnum: endpoint number * @retval status */ -static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum) +static uint8_t usbd_cdc_DataOut(void *pdev, uint8_t epnum) { - uint16_t USB_Rx_Cnt; - /* Get the received data buffer and update the counter */ - USB_Rx_Cnt = ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count; + uint16_t USB_Rx_Cnt = ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count; /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application Xfer */ - APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt); - - /* Prepare Out endpoint to receive next packet */ - DCD_EP_PrepareRx(pdev, - CDC_OUT_EP, - (uint8_t*)(USB_Rx_Buffer), - CDC_DATA_OUT_PACKET_SIZE); - + if ( APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt)==USBD_OK ) + { + /* Prepare Out endpoint to receive next packet */ + DCD_EP_PrepareRx(pdev, CDC_OUT_EP, USB_Rx_Buffer, CDC_DATA_OUT_PACKET_SIZE); + } return USBD_OK; } /** - * @brief usbd_audio_SOF + * @brief usbd_cdc_SOF * Start Of Frame event management * @param pdev: instance * @param epnum: endpoint number * @retval status */ -static uint8_t usbd_cdc_SOF (void *pdev) +static uint8_t usbd_cdc_SOF(void *pdev) { static uint32_t FrameCount = 0; @@ -770,62 +715,34 @@ static uint8_t usbd_cdc_SOF (void *pdev) * @param pdev: instance * @retval None */ -static void Handle_USBAsynchXfer (void *pdev) +static void Handle_USBAsynchXfer(void *pdev) { - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if(USB_Tx_State != 1) + if ( USB_Tx_State ) return; + + uint16_t USB_Tx_ptr = APP_Tx_ptr_out; + uint16_t USB_Tx_length = (APP_Tx_ptr_in - USB_Tx_ptr) & APP_TX_DATA_SIZE_MASK; + if ( USB_Tx_length==0 ) { - if (APP_Rx_ptr_out == APP_RX_DATA_SIZE) - { - APP_Rx_ptr_out = 0; - } - - if(APP_Rx_ptr_out == APP_Rx_ptr_in) - { - USB_Tx_State = 0; - return; - } - - if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */ - { - APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out; - - } - else - { - APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out; - - } -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - APP_Rx_length &= ~0x03; -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE) + return; // nothing to send + } + + USB_Tx_State = 1; + + if (USB_Tx_length > CDC_DATA_IN_PACKET_SIZE) { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; + USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; } - else + if ( USB_Tx_length > (APP_TX_DATA_SIZE - USB_Tx_ptr) ) { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; + USB_Tx_length = (APP_TX_DATA_SIZE - USB_Tx_ptr); } - USB_Tx_State = 1; + + APP_Tx_ptr_out = (USB_Tx_ptr+USB_Tx_length)&APP_TX_DATA_SIZE_MASK; DCD_EP_Tx (pdev, CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], + (uint8_t*)&APP_Tx_Buffer[USB_Tx_ptr], USB_Tx_length); - } - } /** diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h index 9ed095b73..fc9e25e6b 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h @@ -24,11 +24,6 @@ #define __DFU_MAL_H /* Includes ------------------------------------------------------------------*/ -#ifdef STM32F2XX - #include "stm32f2xx.h" -#elif defined(STM32F10X_CL) - #include "stm32f10x.h" -#endif /* STM32F2XX */ #include "usbd_conf.h" #include "usbd_dfu_core.h" @@ -53,7 +48,7 @@ DFU_MAL_Prop_TypeDef; #define MAL_OK 0 #define MAL_FAIL 1 -/* utils macro ---------------------------------------------------------------*/ +/* useful macro ---------------------------------------------------------------*/ #define _1st_BYTE(x) (uint8_t)((x)&0xFF) /* 1st addressing cycle */ #define _2nd_BYTE(x) (uint8_t)(((x)&0xFF00)>>8) /* 2nd addressing cycle */ #define _3rd_BYTE(x) (uint8_t)(((x)&0xFF0000)>>16) /* 3rd addressing cycle */ diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h index 07e49dfb2..2fae83169 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h @@ -30,13 +30,14 @@ /* Exported constants --------------------------------------------------------*/ #define FLASH_START_ADD 0x08000000 -#ifdef STM32F2XX +#if defined(STM32F40_41xxx) #define FLASH_END_ADD 0x08100000 #define FLASH_IF_STRING "@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg" -#elif defined(STM32F10X_CL) - #define FLASH_END_ADD 0x08040000 - #define FLASH_IF_STRING "@Internal Flash /0x08000000/06*002Ka,122*002Kg" -#endif /* STM32F2XX */ + +#elif defined(STM32F429_439xx) + #define FLASH_END_ADD 0x08200000 + #define FLASH_IF_STRING "@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg,04*016Kg,01*064Kg,07*128Kg" +#endif extern DFU_MAL_Prop_TypeDef DFU_Flash_cb; diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h index d1e0dda9a..451ac49c4 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h @@ -24,9 +24,6 @@ #define __MEM_IF_MAL_H /* Includes ------------------------------------------------------------------*/ -#ifdef STM32F2XX - #include "stm32f2xx.h" -#endif /* STM32F2XX */ #include "usbd_dfu_mal.h" /* Exported types ------------------------------------------------------------*/ diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h index d93fc77d6..c3710841c 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h @@ -46,6 +46,8 @@ #define HID_DESCRIPTOR_TYPE 0x21 #define HID_REPORT_DESC 0x22 +#define HID_HS_BINTERVAL 0x07 +#define HID_FS_BINTERVAL 0x0A #define HID_REQ_SET_PROTOCOL 0x0B #define HID_REQ_GET_PROTOCOL 0x03 @@ -94,6 +96,9 @@ extern USBD_Class_cb_TypeDef USBD_HID_cb; uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev, uint8_t *report, uint16_t len); + +uint32_t USBD_HID_GetPollingInterval (USB_OTG_CORE_HANDLE *pdev); + /** * @} */ diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h index be1d401e2..525e1984d 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h @@ -44,9 +44,8 @@ #define BOT_RESET 0xFF #define USB_MSC_CONFIG_DESC_SIZ 32 -#define MSC_EPIN_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 22) - -#define MSC_EPOUT_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 29) +#define MSC_EPIN_SIZE MSC_MAX_PACKET +#define MSC_EPOUT_SIZE MSC_MAX_PACKET /** * @} diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h index 34cd39d11..c6a751f86 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h @@ -24,9 +24,7 @@ #define __USBD_CONF__H__ /* Includes ------------------------------------------------------------------*/ -#include "stm32f2xx.h" - - +#include "usb_conf.h" /** @defgroup USB_CONF_Exported_Defines * @{ diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_def.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_def.h index 03a8afc9d..237525a90 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_def.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_def.h @@ -23,6 +23,7 @@ #ifndef __USBD_DEF_H #define __USBD_DEF_H + /* Includes ------------------------------------------------------------------*/ #include @@ -86,7 +87,7 @@ #define USB_DESC_TYPE_ENDPOINT 5 #define USB_DESC_TYPE_DEVICE_QUALIFIER 6 #define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 - +#define USB_DESC_TYPE_BOS 0x0F #define USB_CONFIG_REMOTE_WAKEUP 2 #define USB_CONFIG_SELF_POWERED 1 @@ -115,8 +116,8 @@ #define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) -#define LOBYTE(x) ((uint8_t)(x & 0x00FF)) -#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) +#define LOBYTE(x) ((uint8_t)((x) & 0x00FF)) +#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00) >>8)) /** * @} */ diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c index 2c5e82206..04d3478ba 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c @@ -101,8 +101,8 @@ USBD_DCD_INT_cb_TypeDef USBD_DCD_INT_cb = USBD_IsoINIncomplete, USBD_IsoOUTIncomplete, #ifdef VBUS_SENSING_ENABLED -USBD_DevConnected, -USBD_DevDisconnected, + USBD_DevConnected, + USBD_DevDisconnected, #endif }; @@ -117,7 +117,7 @@ USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops = &USBD_DCD_INT_cb; /** * @brief USBD_Init -* Initailizes the device stack and load the class driver +* Initializes the device stack and load the class driver * @param pdev: device instance * @param core_address: USB OTG core ID * @param class_cb: Class callback structure address @@ -152,7 +152,7 @@ void USBD_Init(USB_OTG_CORE_HANDLE *pdev, /** * @brief USBD_DeInit -* Re-Initialize th deviuce library +* Re-Initialize the device library * @param pdev: device instance * @retval status: status */ @@ -247,7 +247,7 @@ static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) (pdev->dev.device_status == USB_OTG_CONFIGURED)) { pdev->dev.class_cb->DataOut(pdev, epnum); - } + } return USBD_OK; } @@ -305,7 +305,7 @@ static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) (pdev->dev.device_status == USB_OTG_CONFIGURED)) { pdev->dev.class_cb->DataIn(pdev, epnum); - } + } return USBD_OK; } diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c index 620b9e5cf..3e74d6d53 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c @@ -169,7 +169,7 @@ USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev, } /** * @brief USBD_CtlSendStatus -* send zero lzngth packet on the ctl pipe +* send zero length packet on the ctl pipe * @param pdev: USB OTG device instance * @retval status */ @@ -189,7 +189,7 @@ USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev) /** * @brief USBD_CtlReceiveStatus -* receive zero lzngth packet on the ctl pipe +* receive zero length packet on the ctl pipe * @param pdev: USB OTG device instance * @retval status */ diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_bsp.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_bsp.h index dad600ae2..097c50b8f 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_bsp.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_bsp.h @@ -25,7 +25,6 @@ /* Includes ------------------------------------------------------------------*/ #include "usb_core.h" -//#include "stm32f4_discovery.h" /** @addtogroup USB_OTG_DRIVER * @{ @@ -81,6 +80,8 @@ void USB_OTG_BSP_DisableInterrupt (USB_OTG_CORE_HANDLE *pdev); #ifdef USE_HOST_MODE void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev); void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev,uint8_t state); +void USB_OTG_BSP_Resume(USB_OTG_CORE_HANDLE *pdev) ; +void USB_OTG_BSP_Suspend(USB_OTG_CORE_HANDLE *pdev); #endif /** * @} diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_conf_template.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_conf_template.h index 39b35529e..ecc0f21cd 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_conf_template.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_conf_template.h @@ -24,8 +24,7 @@ #define __USB_CONF__H__ /* Includes ------------------------------------------------------------------*/ -#include "stm32f2xx.h" - +#include "usb_conf.h" /** @addtogroup USB_OTG_DRIVER * @{ @@ -45,10 +44,37 @@ configuration, you can declare the needed define in your toolchain compiler preprocessor. */ +/****************** USB OTG FS PHY CONFIGURATION ******************************* +* The USB OTG FS Core supports one on-chip Full Speed PHY. +* +* The USE_EMBEDDED_PHY symbol is defined in the project compiler preprocessor +* when FS core is used. +*******************************************************************************/ #ifndef USE_USB_OTG_FS //#define USE_USB_OTG_FS #endif /* USE_USB_OTG_FS */ +#ifdef USE_USB_OTG_FS + #define USB_OTG_FS_CORE +#endif + +/****************** USB OTG HS PHY CONFIGURATION ******************************* +* The USB OTG HS Core supports two PHY interfaces: +* (i) An ULPI interface for the external High Speed PHY: the USB HS Core will +* operate in High speed mode +* (ii) An on-chip Full Speed PHY: the USB HS Core will operate in Full speed mode +* +* You can select the PHY to be used using one of these two defines: +* (i) USE_ULPI_PHY: if the USB OTG HS Core is to be used in High speed mode +* (ii) USE_EMBEDDED_PHY: if the USB OTG HS Core is to be used in Full speed mode +* +* Notes: +* - The USE_ULPI_PHY symbol is defined in the project compiler preprocessor as +* default PHY when HS core is used. +* - On STM322xG-EVAL and STM324xG-EVAL boards, only configuration(i) is available. +* Configuration (ii) need a different hardware, for more details refer to your +* STM32 device datasheet. +*******************************************************************************/ #ifndef USE_USB_OTG_HS //#define USE_USB_OTG_HS #endif /* USE_USB_OTG_HS */ @@ -61,15 +87,6 @@ //#define USE_EMBEDDED_PHY #endif /* USE_EMBEDDED_PHY */ -#ifndef USE_I2C_PHY - //#define USE_I2C_PHY -#endif /* USE_I2C_PHY */ - - -#ifdef USE_USB_OTG_FS - #define USB_OTG_FS_CORE -#endif - #ifdef USE_USB_OTG_HS #define USB_OTG_HS_CORE #endif @@ -151,9 +168,6 @@ #ifdef USE_EMBEDDED_PHY #define USB_OTG_EMBEDDED_PHY_ENABLED #endif - #ifdef USE_I2C_PHY - #define USB_OTG_I2C_PHY_ENABLED - #endif #define USB_OTG_HS_INTERNAL_DMA_ENABLED #define USB_OTG_HS_DEDICATED_EP1_ENABLED #endif @@ -172,19 +186,20 @@ //#define USB_OTG_FS_SOF_OUTPUT_ENABLED #endif +/****************** USB OTG MISC CONFIGURATION ********************************/ +//#define VBUS_SENSING_ENABLED + /****************** USB OTG MODE CONFIGURATION ********************************/ //#define USE_HOST_MODE #define USE_DEVICE_MODE //#define USE_OTG_MODE - #ifndef USB_OTG_FS_CORE #ifndef USB_OTG_HS_CORE #error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined" #endif #endif - #ifndef USE_DEVICE_MODE #ifndef USE_HOST_MODE #error "USE_DEVICE_MODE or USE_HOST_MODE should be defined" @@ -198,9 +213,7 @@ #else //USE_USB_OTG_HS #ifndef USE_ULPI_PHY #ifndef USE_EMBEDDED_PHY - #ifndef USE_I2C_PHY - #error "USE_ULPI_PHY or USE_EMBEDDED_PHY or USE_I2C_PHY should be defined" - #endif + #error "USE_ULPI_PHY or USE_EMBEDDED_PHY should be defined" #endif #endif #endif diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_core.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_core.h index dd6a86ad2..b2f9b8da1 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_core.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_core.h @@ -63,7 +63,7 @@ /** * @} */ -#define MAX_DATA_LENGTH 0xFF +#define MAX_DATA_LENGTH 0x100 /** @defgroup USB_CORE_Exported_Types * @{ @@ -188,7 +188,11 @@ typedef struct _Device_TypeDef uint8_t *(*GetProductStrDescriptor)( uint8_t speed , uint16_t *length); uint8_t *(*GetSerialStrDescriptor)( uint8_t speed , uint16_t *length); uint8_t *(*GetConfigurationStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetInterfaceStrDescriptor)( uint8_t speed , uint16_t *length); + uint8_t *(*GetInterfaceStrDescriptor)( uint8_t speed , uint16_t *length); + +#if (USBD_LPM_ENABLED == 1) + uint8_t *(*GetBOSDescriptor)( uint8_t speed , uint16_t *length); +#endif } USBD_DEVICE, *pUSBD_DEVICE; typedef struct USB_OTG_hPort @@ -248,7 +252,10 @@ typedef struct _DCD uint8_t device_config; uint8_t device_state; uint8_t device_status; + uint8_t device_old_status; uint8_t device_address; + uint8_t connection_status; + uint8_t test_mode; uint32_t DevRemoteWakeup; USB_OTG_EP in_ep [USB_OTG_MAX_TX_FIFOS]; USB_OTG_EP out_ep [USB_OTG_MAX_TX_FIFOS]; @@ -265,6 +272,7 @@ typedef struct _HCD { uint8_t Rx_Buffer [MAX_DATA_LENGTH]; __IO uint32_t ConnSts; + __IO uint32_t PortEnabled; __IO uint32_t ErrCnt[USB_OTG_MAX_TX_FIFOS]; __IO uint32_t XferCnt[USB_OTG_MAX_TX_FIFOS]; __IO HC_STATUS HC_Status[USB_OTG_MAX_TX_FIFOS]; diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h index 9df1a4172..53d8cc49c 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h @@ -84,7 +84,7 @@ extern USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops; #define CLEAR_OUT_EP_INTR(epnum,intr) \ doepint.d32=0; \ doepint.b.intr = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT,doepint.d32); + USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[(epnum)]->DOEPINT,doepint.d32); /** * @} @@ -102,7 +102,8 @@ extern USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops; */ uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev); - +uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev); +uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev); /** * @} */ diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_defines.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_defines.h index 546f5ab8b..846660007 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_defines.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_defines.h @@ -57,7 +57,6 @@ #define USB_OTG_ULPI_PHY 1 #define USB_OTG_EMBEDDED_PHY 2 -#define USB_OTG_I2C_PHY 3 /** * @} @@ -216,9 +215,9 @@ typedef enum * @{ */ #define USB_OTG_READ_REG32(reg) (*(__IO uint32_t *)(reg)) -#define USB_OTG_WRITE_REG32(reg,value) (*(__IO uint32_t *)(reg) = value) +#define USB_OTG_WRITE_REG32(reg,value) (*(__IO uint32_t *)(reg) = (value)) #define USB_OTG_MODIFY_REG32(reg,clear_mask,set_mask) \ - USB_OTG_WRITE_REG32(reg, (((USB_OTG_READ_REG32(reg)) & ~clear_mask) | set_mask ) ) + USB_OTG_WRITE_REG32((reg), (((USB_OTG_READ_REG32(reg)) & ~(clear_mask)) | (set_mask)) ) /******************************************************************************** ENUMERATION TYPE diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd.h index 15e8ab161..249ce5763 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd.h @@ -80,6 +80,8 @@ uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev , uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev); uint32_t HCD_ResetPort (USB_OTG_CORE_HANDLE *pdev); uint32_t HCD_IsDeviceConnected (USB_OTG_CORE_HANDLE *pdev); +uint32_t HCD_IsPortEnabled (USB_OTG_CORE_HANDLE *pdev); + uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev) ; URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num); uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num); diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h index c95c59f82..4387a386e 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h @@ -23,7 +23,6 @@ #ifndef __HCD_INT_H__ #define __HCD_INT_H__ - /* Includes ------------------------------------------------------------------*/ #include "usb_hcd.h" @@ -49,6 +48,18 @@ /** @defgroup USB_HCD_INT_Exported_Types * @{ */ + +typedef struct _USBH_HCD_INT +{ + uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* DevPortEnabled) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* DevPortDisabled) (USB_OTG_CORE_HANDLE *pdev); + +}USBH_HCD_INT_cb_TypeDef; + +extern USBH_HCD_INT_cb_TypeDef *USBH_HCD_INT_fops; /** * @} */ @@ -66,25 +77,25 @@ USB_OTG_WRITE_REG32(&((HC_REGS)->HCINT), hcint_clear.d32);\ }\ -#define MASK_HOST_INT_CHH(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.chhltd = 0; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -#define UNMASK_HOST_INT_CHH(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.chhltd = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -#define MASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.ack = 0; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -#define UNMASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.ack = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} +#define MASK_HOST_INT_CHH(hc_num) { USB_OTG_HCINTMSK_TypeDef INTMSK; \ + INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \ + INTMSK.b.chhltd = 0; \ + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, INTMSK.d32);} + +#define UNMASK_HOST_INT_CHH(hc_num) { USB_OTG_HCINTMSK_TypeDef INTMSK; \ + INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \ + INTMSK.b.chhltd = 1; \ + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, INTMSK.d32);} + +#define MASK_HOST_INT_ACK(hc_num) { USB_OTG_HCINTMSK_TypeDef INTMSK; \ + INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \ + INTMSK.b.ack = 0; \ + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, GINTMSK.d32);} + +#define UNMASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef INTMSK; \ + INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \ + INTMSK.b.ack = 1; \ + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, INTMSK.d32);} /** * @} diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_regs.h b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_regs.h index 3038f0d86..ae3f781b0 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_regs.h +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_regs.h @@ -58,7 +58,7 @@ #define USB_OTG_DATA_FIFO_SIZE 0x1000 -#define USB_OTG_MAX_TX_FIFOS 15 +#define USB_OTG_MAX_TX_FIFOS 7 #define USB_OTG_HS_MAX_PACKET_SIZE 512 #define USB_OTG_FS_MAX_PACKET_SIZE 64 @@ -88,8 +88,7 @@ typedef struct _USB_OTG_GREGS //000h __IO uint32_t GRXFSIZ; /* Receive FIFO Size Register 024h*/ __IO uint32_t DIEPTXF0_HNPTXFSIZ; /* EP0 / Non Periodic Tx FIFO Size Register 028h*/ __IO uint32_t HNPTXSTS; /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/ - __IO uint32_t GI2CCTL; /* I2C Access Register 030h*/ - uint32_t Reserved34; /* PHY Vendor Control Register 034h*/ + uint32_t Reserved30[2]; /* Reserved 030h*/ __IO uint32_t GCCFG; /* General Purpose IO Register 038h*/ __IO uint32_t CID; /* User ID Register 03Ch*/ uint32_t Reserved40[48]; /* Reserved 040h-0FFh*/ @@ -160,12 +159,12 @@ USB_OTG_INEPREGS; typedef struct _USB_OTG_OUTEPREGS { __IO uint32_t DOEPCTL; /* dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ - __IO uint32_t DOUTEPFRM; /* dev OUT Endpoint Frame number B00h + (ep_num * 20h) + 04h*/ - __IO uint32_t DOEPINT; /* dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /* Reserved B00h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DOEPTSIZ; /* dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ - __IO uint32_t DOEPDMA; /* dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/ - uint32_t Reserved18[2]; /* Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/ + uint32_t Reserved04; /* Reserved B00h + (ep_num * 20h) + 04h*/ + __IO uint32_t DOEPINT; /* dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ + uint32_t Reserved0C; /* Reserved B00h + (ep_num * 20h) + 0Ch*/ + __IO uint32_t DOEPTSIZ; /* dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ + __IO uint32_t DOEPDMA; /* dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/ + uint32_t Reserved18[2]; /* Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/ } USB_OTG_OUTEPREGS; /** @@ -200,7 +199,7 @@ typedef struct _USB_OTG_HC_REGS __IO uint32_t HCCHAR; __IO uint32_t HCSPLT; __IO uint32_t HCINT; - __IO uint32_t HCGINTMSK; + __IO uint32_t HCINTMSK; __IO uint32_t HCTSIZ; __IO uint32_t HCDMA; uint32_t Reserved[2]; @@ -227,7 +226,7 @@ typedef struct USB_OTG_core_regs //000h __IO uint32_t *PCGCCTL; } USB_OTG_CORE_REGS , *PUSB_OTG_CORE_REGS; -typedef union _USB_OTG_OTGCTL_TypeDef +typedef union _USB_OTG_GOTGCTL_TypeDef { uint32_t d32; struct @@ -250,19 +249,18 @@ uint32_t Reserved12_15 : 4; uint32_t conidsts : 1; -uint32_t Reserved17 : +uint32_t dbct : 1; uint32_t asesvld : 1; uint32_t bsesvld : 1; -uint32_t currmod : - 1; -uint32_t Reserved21_31 : - 11; +uint32_t Reserved20_31 : + 12; } b; -} USB_OTG_OTGCTL_TypeDef ; +} USB_OTG_GOTGCTL_TypeDef ; + typedef union _USB_OTG_GOTGINT_TypeDef { uint32_t d32; @@ -320,15 +318,11 @@ typedef union _USB_OTG_GUSBCFG_TypeDef { uint32_t toutcal : 3; -uint32_t phyif : - 1; -uint32_t ulpi_utmi_sel : - 1; -uint32_t fsintf : - 1; +uint32_t Reserved3_5 : + 3; uint32_t physel : 1; -uint32_t ddrsel : +uint32_t Reserved7 : 1; uint32_t srpcap : 1; @@ -336,11 +330,11 @@ uint32_t hnpcap : 1; uint32_t usbtrdtim : 4; -uint32_t nptxfrwnden : +uint32_t Reserved14 : 1; uint32_t phylpwrclksel : 1; -uint32_t otgutmifssel : +uint32_t Reserved16 : 1; uint32_t ulpi_fsls : 1; @@ -350,12 +344,18 @@ uint32_t ulpi_clk_sus_m : 1; uint32_t ulpi_ext_vbus_drv : 1; -uint32_t ulpi_int_vbus_indicator : +uint32_t ulpi_int_vbus_ind : 1; uint32_t term_sel_dl_pulse : 1; -uint32_t Reserved : - 6; +uint32_t ulpi_ind_cpl : + 1; +uint32_t ulpi_passthrough : + 1; +uint32_t ulpi_protect_disable : + 1; +uint32_t Reserved26_28 : + 3; uint32_t force_host : 1; uint32_t force_dev : @@ -376,7 +376,7 @@ uint32_t hsftrst : 1; uint32_t hstfrm : 1; -uint32_t intknqflsh : +uint32_t Reserved3 : 1; uint32_t rxfflsh : 1; @@ -414,10 +414,8 @@ uint32_t ginnakeff : 1; uint32_t goutnakeff : 1; -uint32_t Reserved8 : - 1; -uint32_t i2cintr : - 1; +uint32_t Reserved8_9 : + 2; uint32_t erlysuspend : 1; uint32_t usbsuspend : @@ -484,10 +482,8 @@ uint32_t ginnakeff : 1; uint32_t goutnakeff : 1; -uint32_t Reserved8 : - 1; -uint32_t i2cintr : - 1; +uint32_t Reserved8_9 : + 2; uint32_t erlysuspend : 1; uint32_t usbsuspend : @@ -500,10 +496,8 @@ uint32_t isooutdrop : 1; uint32_t eopframe : 1; -uint32_t intimerrx : - 1; -uint32_t epmismatch : - 1; +uint32_t Reserved16_17 : + 2; uint32_t inepint: 1; uint32_t outepintr : @@ -592,14 +586,15 @@ uint32_t nptxfspcavail : 16; uint32_t nptxqspcavail : 8; -uint32_t nptxqtop_terminate : + struct + { + uint32_t terminate : 1; -uint32_t nptxqtop_timer : - 2; -uint32_t nptxqtop : + uint32_t token : 2; -uint32_t chnum : - 2; + uint32_t chnum : + 4; + } nptxqtop; uint32_t Reserved : 1; } @@ -617,36 +612,7 @@ uint32_t Reserved : } b; } USB_OTG_DTXFSTSn_TypeDef ; -typedef union _USB_OTG_GI2CCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t rwdata : - 8; -uint32_t regaddr : - 8; -uint32_t addr : - 7; -uint32_t i2cen : - 1; -uint32_t ack : - 1; -uint32_t i2csuspctl : - 1; -uint32_t i2cdevaddr : - 2; -uint32_t dat_se0: - 1; -uint32_t Reserved : - 1; -uint32_t rw : - 1; -uint32_t bsydne : - 1; - } - b; -} USB_OTG_GI2CCTL_TypeDef ; + typedef union _USB_OTG_GCCFG_TypeDef { uint32_t d32; @@ -656,7 +622,7 @@ uint32_t Reserved_in : 16; uint32_t pwdn : 1; -uint32_t i2cifen : +uint32_t Reserved_17 : 1; uint32_t vbussensingA : 1; @@ -687,10 +653,8 @@ uint32_t devaddr : 7; uint32_t perfrint : 2; -uint32_t Reserved13_17 : - 5; -uint32_t epmscnt : - 4; +uint32_t Reserved13_31 : + 19; } b; } USB_OTG_DCFG_TypeDef ; @@ -717,8 +681,10 @@ uint32_t sgoutnak : 1; uint32_t cgoutnak : 1; +uint32_t poprg_done : + 1; uint32_t Reserved : - 21; + 20; } b; } USB_OTG_DCTL_TypeDef ; @@ -751,13 +717,13 @@ uint32_t xfercompl : 1; uint32_t epdisabled : 1; -uint32_t ahberr : +uint32_t Reserved2 : 1; uint32_t timeout : 1; uint32_t intktxfemp : 1; -uint32_t intknepmis : +uint32_t Reserved5 : 1; uint32_t inepnakeff : 1; @@ -765,7 +731,7 @@ uint32_t emptyintr : 1; uint32_t txfifoundrn : 1; -uint32_t Reserved08_31 : +uint32_t Reserved9_31 : 23; } b; @@ -780,7 +746,7 @@ uint32_t xfercompl : 1; uint32_t epdisabled : 1; -uint32_t ahberr : +uint32_t Reserved2 : 1; uint32_t setup : 1; @@ -821,8 +787,12 @@ uint32_t rx_thr_en : 1; uint32_t rx_thr_len : 9; -uint32_t Reserved26_31 : - 6; +uint32_t Reserved26 : + 1; +uint32_t arp_en : + 1; +uint32_t Reserved28_31 : + 4; } b; } USB_OTG_DTHRCTL_TypeDef ; @@ -890,12 +860,13 @@ uint32_t xfersize : uint32_t Reserved7_18 : 12; uint32_t pktcnt : - 2; + 1; uint32_t Reserved20_28 : 9; uint32_t supcnt : 2; - uint32_t Reserved31; +uint32_t Reserved31 : + 1; } b; } USB_OTG_DEP0XFRSIZ_TypeDef ; @@ -945,16 +916,17 @@ uint32_t ptxfspcavail : 16; uint32_t ptxqspcavail : 8; -uint32_t ptxqtop_terminate : - 1; -uint32_t ptxqtop_timer : - 2; -uint32_t ptxqtop : - 2; -uint32_t chnum : - 2; -uint32_t ptxqtop_odd : - 1; + struct + { + uint32_t terminate : + 1; + uint32_t token : + 2; + uint32_t chnum : + 4; + uint32_t odd_even : + 1; + } ptxqtop; } b; } USB_OTG_HPTXSTS_TypeDef ; @@ -1118,7 +1090,7 @@ uint32_t dopng : } b; } USB_OTG_HCTSIZn_TypeDef ; -typedef union _USB_OTG_HCGINTMSK_TypeDef +typedef union _USB_OTG_HCINTMSK_TypeDef { uint32_t d32; struct @@ -1149,7 +1121,8 @@ uint32_t Reserved : 21; } b; -} USB_OTG_HCGINTMSK_TypeDef ; +} USB_OTG_HCINTMSK_TypeDef ; + typedef union _USB_OTG_PCGCCTL_TypeDef { uint32_t d32; @@ -1159,8 +1132,12 @@ uint32_t stoppclk : 1; uint32_t gatehclk : 1; -uint32_t Reserved : - 30; +uint32_t Reserved2_3 : + 2; +uint32_t phy_susp : + 1; +uint32_t Reserved5_31 : + 27; } b; } USB_OTG_PCGCCTL_TypeDef ; diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_core.c b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_core.c index dd3856f12..6a2002fca 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_core.c +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_core.c @@ -167,14 +167,11 @@ USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev, USB_OTG_STS status = USB_OTG_OK; if (pdev->cfg.dma_enable == 0) { - uint32_t count32b= 0 , i= 0; - __IO uint32_t *fifo; - - count32b = (len + 3) / 4; - fifo = pdev->regs.DFIFO[ch_ep_num]; - for (i = 0; i < count32b; i++, src+=4) + __IO uint32_t *fifo = pdev->regs.DFIFO[ch_ep_num]; + uint32_t count32b = (len + 3) / 4; + for (uint32_t i = 0; i < count32b; i++, src+=4) { - USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) ); + USB_OTG_WRITE_REG32( fifo, *((uint32_t *)src) ); } } return status; @@ -192,15 +189,13 @@ void *USB_OTG_ReadPacket(USB_OTG_CORE_HANDLE *pdev, uint8_t *dest, uint16_t len) { - uint32_t i=0; uint32_t count32b = (len + 3) / 4; __IO uint32_t *fifo = pdev->regs.DFIFO[0]; - for ( i = 0; i < count32b; i++, dest += 4 ) + for (uint32_t i = 0; i < count32b; i++, dest += 4 ) { - *(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo); - + *(uint32_t *)dest = USB_OTG_READ_REG32(fifo); } return ((void *)dest); } @@ -223,7 +218,7 @@ USB_OTG_STS USB_OTG_SelectCore(USB_OTG_CORE_HANDLE *pdev, /* at startup the core is in FS mode */ pdev->cfg.speed = USB_OTG_SPEED_FULL; pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; - + /* initialize device cfg following its address */ if (coreID == USB_OTG_FS_CORE_ID) { @@ -252,15 +247,11 @@ USB_OTG_STS USB_OTG_SelectCore(USB_OTG_CORE_HANDLE *pdev, #ifdef USB_OTG_ULPI_PHY_ENABLED pdev->cfg.phy_itface = USB_OTG_ULPI_PHY; -#else +#else #ifdef USB_OTG_EMBEDDED_PHY_ENABLED pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY; - #else - #ifdef USB_OTG_I2C_PHY_ENABLED - pdev->cfg.phy_itface = USB_OTG_I2C_PHY; - #endif - #endif -#endif + #endif +#endif #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED pdev->cfg.dma_enable = 1; @@ -323,15 +314,14 @@ USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev) USB_OTG_STS status = USB_OTG_OK; USB_OTG_GUSBCFG_TypeDef usbcfg; USB_OTG_GCCFG_TypeDef gccfg; - USB_OTG_GI2CCTL_TypeDef i2cctl; USB_OTG_GAHBCFG_TypeDef ahbcfg; - +#if defined (STM32F446xx) || defined (STM32F469_479xx) + USB_OTG_DCTL_TypeDef dctl; +#endif usbcfg.d32 = 0; gccfg.d32 = 0; ahbcfg.d32 = 0; - - if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) { gccfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GCCFG); @@ -351,15 +341,11 @@ USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev) #ifdef USB_OTG_INTERNAL_VBUS_ENABLED usbcfg.b.ulpi_ext_vbus_drv = 0; /* Use internal VBUS */ #else - #ifdef USB_OTG_EXTERNAL_VBUS_ENABLED + #ifdef USB_OTG_EXTERNAL_VBUS_ENABLED usbcfg.b.ulpi_ext_vbus_drv = 1; /* Use external VBUS */ #endif -#endif +#endif usbcfg.b.term_sel_dl_pulse = 0; /* Data line pulsing using utmi_txvalid */ - usbcfg.b.ulpi_utmi_sel = 1; /* ULPI seleInterfacect */ - - usbcfg.b.phyif = 0; /* 8 bits */ - usbcfg.b.ddrsel = 0; /* single data rate */ usbcfg.b.ulpi_fsls = 0; usbcfg.b.ulpi_clk_sus_m = 0; @@ -375,9 +361,9 @@ USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev) ahbcfg.b.dmaenable = 1; USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32); - } + } } - else /* FS interface (embedded Phy or I2C Phy) */ + else /* FS interface (embedded Phy) */ { usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);; @@ -385,19 +371,15 @@ USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev) USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); /* Reset after a PHY select and set Host mode */ USB_OTG_CoreReset(pdev); - /* Enable the I2C interface and deactivate the power down*/ + /* Deactivate the power down*/ gccfg.d32 = 0; gccfg.b.pwdn = 1; - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - gccfg.b.i2cifen = 1; - } - gccfg.b.vbussensingA = 1 ; - gccfg.b.vbussensingB = 1 ; + gccfg.b.vbussensingA = 1; + gccfg.b.vbussensingB = 1; + #ifndef VBUS_SENSING_ENABLED - gccfg.b.disablevbussensing = 1; -#endif + gccfg.b.disablevbussensing = 1; +#endif if(pdev->cfg.Sof_output) { @@ -406,32 +388,6 @@ USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev) USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32); USB_OTG_BSP_mDelay(20); - /* Program GUSBCFG.OtgUtmifsSel to I2C*/ - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - usbcfg.b.otgutmifssel = 1; - } - - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - /*Program GI2CCTL.I2CEn*/ - i2cctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GI2CCTL); - i2cctl.b.i2cdevaddr = 1; - i2cctl.b.i2cen = 0; - i2cctl.b.dat_se0 = 1; - i2cctl.b.addr = 0x2D; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32); - - USB_OTG_BSP_mDelay(200); - - i2cctl.b.i2cen = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32); - USB_OTG_BSP_mDelay(200); - } } /* case the HS core is working in FS mode */ if(pdev->cfg.dma_enable == 1) @@ -451,6 +407,20 @@ USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev) USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); USB_OTG_EnableCommonInt(pdev); #endif + +#if defined (STM32F446xx) || defined (STM32F469_479xx) + usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); + usbcfg.b.srpcap = 1; + /*clear sdis bit in dctl */ + dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); + /* Connect device */ + dctl.b.sftdiscon = 0; + USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); + dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); + USB_OTG_EnableCommonInt(pdev); +#endif + return status; } /** @@ -670,7 +640,15 @@ USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev) USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0); /* Initialize Host Configuration Register */ - USB_OTG_InitFSLSPClkSel(pdev , HCFG_48_MHZ); /* in init phase */ + if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) + { + USB_OTG_InitFSLSPClkSel(pdev , HCFG_30_60_MHZ); + } + else + { + USB_OTG_InitFSLSPClkSel(pdev , HCFG_48_MHZ); + } + USB_OTG_ResetPort(pdev); hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); hcfg.b.fslssupp = 0; @@ -693,9 +671,9 @@ USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev) } #endif #ifdef USB_OTG_HS_CORE - if (pdev->cfg.coreID == USB_OTG_HS_CORE_ID) + if (pdev->cfg.coreID == USB_OTG_HS_CORE_ID) { - /* set Rx FIFO size */ + /* set Rx FIFO size */ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE); nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE; nptxfifosize.b.depth = TXH_NP_HS_FIFOSIZ; @@ -722,7 +700,7 @@ USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev) for (i = 0; i < pdev->cfg.host_channels; i++) { USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINT, 0xFFFFFFFF ); - USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCGINTMSK, 0 ); + USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINTMSK, 0 ); } #ifndef USE_OTG_MODE USB_OTG_DriveVbus(pdev, 1); @@ -795,13 +773,20 @@ USB_OTG_STS USB_OTG_EnableHostInt(USB_OTG_CORE_HANDLE *pdev) if (pdev->cfg.dma_enable == 0) { intmsk.b.rxstsqlvl = 1; - } - intmsk.b.portintr = 1; - intmsk.b.hcintr = 1; - intmsk.b.disconnect = 1; - intmsk.b.sofintr = 1; - intmsk.b.incomplisoout = 1; + } + + + intmsk.b.incomplisoout = 1; + intmsk.b.hcintr = 1; +intmsk.b.portintr = 1; USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32); + + intmsk.d32 = 0; + + intmsk.b.disconnect = 1; + + intmsk.b.sofintr = 1; + USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, intmsk.d32, 0); return status; } @@ -955,7 +940,7 @@ USB_OTG_STS USB_OTG_HC_Init(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) } - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, hcintmsk.d32); + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, hcintmsk.d32); /* Enable the top level host channel interrupt. */ @@ -1048,11 +1033,11 @@ USB_OTG_STS USB_OTG_HC_StartXfer(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) hcchar.b.chen = 1; hcchar.b.chdis = 0; USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - + if (pdev->cfg.dma_enable == 0) /* Slave mode */ { if((pdev->host.hc[hc_num].ep_is_in == 0) && - (pdev->host.hc[hc_num].xfer_len > 0)) + (pdev->host.hc[hc_num].xfer_len > 0)) { switch(pdev->host.hc[hc_num].ep_type) { @@ -1116,7 +1101,7 @@ USB_OTG_STS USB_OTG_HC_Halt(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) nptxsts.d32 = 0; hptxsts.d32 = 0; hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); - hcchar.b.chen = 1; + hcchar.b.chdis = 1; /* Check for space in the request queue to issue the halt. */ @@ -1126,6 +1111,7 @@ USB_OTG_STS USB_OTG_HC_Halt(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) if (nptxsts.b.nptxqspcavail == 0) { hcchar.b.chen = 0; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); } } else @@ -1134,8 +1120,10 @@ USB_OTG_STS USB_OTG_HC_Halt(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) if (hptxsts.b.ptxqspcavail == 0) { hcchar.b.chen = 0; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); } } + hcchar.b.chen = 1; USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); return status; } @@ -1150,7 +1138,7 @@ USB_OTG_STS USB_OTG_HC_DoPing(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) USB_OTG_STS status = USB_OTG_OK; USB_OTG_HCCHAR_TypeDef hcchar; USB_OTG_HCTSIZn_TypeDef hctsiz; - + hctsiz.d32 = 0; hctsiz.b.dopng = 1; hctsiz.b.pktcnt = 1; @@ -1282,7 +1270,7 @@ USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev) if(pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) { - USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH); + USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH); } else /* set High speed phy in Full speed mode */ { @@ -1421,7 +1409,7 @@ USB_OTG_STS USB_OTG_EnableDevInt(USB_OTG_CORE_HANDLE *pdev) intmsk.b.inepintr = 1; intmsk.b.outepintr = 1; intmsk.b.sofintr = 1; - + intmsk.b.incomplisoin = 1; intmsk.b.incomplisoout = 1; #ifdef VBUS_SENSING_ENABLED @@ -1460,10 +1448,14 @@ enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev) case DSTS_ENUMSPD_LS_PHY_6MHZ: speed = USB_SPEED_LOW; break; + default: + speed = USB_SPEED_FULL; + break; } return speed; } + /** * @brief enables EP0 OUT to receive SETUP packets and configures EP0 * for transmitting packets @@ -1492,6 +1484,9 @@ USB_OTG_STS USB_OTG_EP0Activate(USB_OTG_CORE_HANDLE *pdev) case DSTS_ENUMSPD_LS_PHY_6MHZ: diepctl.b.mps = DEP0CTL_MPS_8; break; + default: + diepctl.b.mps = DEP0CTL_MPS_64; + break; } USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL, diepctl.d32); dctl.b.cgnpinnak = 1; @@ -1672,7 +1667,7 @@ USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) depctl.b.cnak = 1; depctl.b.epena = 1; USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPCTL, depctl.d32); - + if (ep->type == EP_TYPE_ISOC) { USB_OTG_WritePacket(pdev, ep->xfer_buff, ep->num, ep->xfer_len); @@ -1696,6 +1691,7 @@ USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) { deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket; deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; + ep->xfer_len = deptsiz.b.xfersize ; } USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32); @@ -1986,8 +1982,7 @@ void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev) if(pdev->cfg.low_power) { /* un-gate USB Core clock */ - //power.d32 = USB_OTG_READ_REG32(&(pdev->regs.PCGCCTL)); - power.d32 = USB_OTG_READ_REG32((pdev->regs.PCGCCTL)); // ala42 + power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL); power.b.gatehclk = 0; power.b.stoppclk = 0; USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); @@ -2021,8 +2016,7 @@ void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev) if(dsts.b.suspsts == 1) { /* un-gate USB Core clock */ - //power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); - power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL); // ala42 + power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL); power.b.gatehclk = 0; power.b.stoppclk = 0; USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); @@ -2041,13 +2035,13 @@ void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev) uint32_t i; pdev->dev.device_status = 1; - + for (i = 0; i < pdev->cfg.dev_endpoints ; i++) { USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); } - + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 ); USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 ); USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 ); @@ -2077,24 +2071,35 @@ uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep) depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - if (depctl.b.stall == 1) + if (depctl.b.stall == 1) + { Status = USB_OTG_EP_TX_STALL; + } else if (depctl.b.naksts == 1) + { Status = USB_OTG_EP_TX_NAK; + } else + { Status = USB_OTG_EP_TX_VALID; - + } } else { depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - if (depctl.b.stall == 1) + if (depctl.b.stall == 1) + { Status = USB_OTG_EP_RX_STALL; + } else if (depctl.b.naksts == 1) + { Status = USB_OTG_EP_RX_NAK; + } else + { Status = USB_OTG_EP_RX_VALID; + } } /* Return the current status */ @@ -2114,7 +2119,7 @@ void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t __IO uint32_t *depctl_addr; depctl.d32 = 0; - + /* Process for IN endpoint */ if (ep->is_in == 1) { @@ -2126,7 +2131,9 @@ void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t USB_OTG_EPSetStall(pdev, ep); return; } else if (Status == USB_OTG_EP_TX_NAK) + { depctl.b.snak = 1; + } else if (Status == USB_OTG_EP_TX_VALID) { if (depctl.b.stall == 1) @@ -2140,7 +2147,9 @@ void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t depctl.b.epena = 1; } else if (Status == USB_OTG_EP_TX_DIS) + { depctl.b.usbactep = 0; + } } else /* Process for OUT endpoint */ { @@ -2151,7 +2160,9 @@ void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t depctl.b.stall = 1; } else if (Status == USB_OTG_EP_RX_NAK) + { depctl.b.snak = 1; + } else if (Status == USB_OTG_EP_RX_VALID) { if (depctl.b.stall == 1) @@ -2169,7 +2180,7 @@ void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t depctl.b.usbactep = 0; } } - + USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); } diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c index 0d23a9769..6a914db79 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c @@ -101,7 +101,7 @@ void DCD_Init(USB_OTG_CORE_HANDLE *pdev , ep->is_in = 1; ep->num = i; ep->tx_fifo_num = i; - /* Control until ep is actvated */ + /* Control until ep is activated */ ep->type = EP_TYPE_CTRL; ep->maxpacket = USB_OTG_MAX_EP0_SIZE; ep->xfer_buff = 0; @@ -123,18 +123,28 @@ void DCD_Init(USB_OTG_CORE_HANDLE *pdev , } USB_OTG_DisableGlobalInt(pdev); + +#if defined (STM32F446xx) || defined (STM32F469_479xx) + + /* Force Device Mode*/ + USB_OTG_SetCurrentMode(pdev, DEVICE_MODE); /*Init the Core (common init.) */ USB_OTG_CoreInit(pdev); +#else + + /*Init the Core (common init.) */ + USB_OTG_CoreInit(pdev); /* Force Device Mode*/ USB_OTG_SetCurrentMode(pdev, DEVICE_MODE); + +#endif /* Init Device */ USB_OTG_CoreInitDev(pdev); - /* Enable USB Global interrupt */ USB_OTG_EnableGlobalInt(pdev); } diff --git a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd_int.c b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd_int.c index fb3bb9d44..4fac052db 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd_int.c +++ b/STM32F4/cores/maple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd_int.c @@ -131,8 +131,7 @@ uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) if (pdev->cfg.dma_enable == 1) { deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ)); - /*ToDo : handle more than one single MPS size packet */ - pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].maxpacket - \ + pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].xfer_len- \ deptsiz.b.xfersize; } /* Inform upper layer: data ready */ @@ -147,11 +146,7 @@ uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) /* Clear the bit in DOEPINTn for this interrupt */ CLEAR_OUT_EP_INTR(1, epdisabled); } - /* AHB Error */ - if ( doepint.b.ahberr ) - { - CLEAR_OUT_EP_INTR(1, ahberr); - } + return 1; } @@ -180,10 +175,6 @@ uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) /* TX COMPLETE */ USBD_DCD_INT_fops->DataInStage(pdev , 1); } - if ( diepint.b.ahberr ) - { - CLEAR_IN_EP_INTR(1, ahberr); - } if ( diepint.b.epdisabled ) { CLEAR_IN_EP_INTR(1, epdisabled); @@ -196,10 +187,6 @@ uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) { CLEAR_IN_EP_INTR(1, intktxfemp); } - if (diepint.b.intknepmis) - { - CLEAR_IN_EP_INTR(1, intknepmis); - } if (diepint.b.inepnakeff) { CLEAR_IN_EP_INTR(1, inepnakeff); @@ -365,8 +352,7 @@ static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev) if(pdev->cfg.low_power) { /* un-gate USB Core clock */ - //power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); - power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL); // ala42 + power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL); power.b.gatehclk = 0; power.b.stoppclk = 0; USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); @@ -462,10 +448,6 @@ static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev) } } } - if ( diepint.b.ahberr ) - { - CLEAR_IN_EP_INTR(epnum, ahberr); - } if ( diepint.b.timeout ) { CLEAR_IN_EP_INTR(epnum, timeout); @@ -474,10 +456,6 @@ static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev) { CLEAR_IN_EP_INTR(epnum, intktxfemp); } - if (diepint.b.intknepmis) - { - CLEAR_IN_EP_INTR(epnum, intknepmis); - } if (diepint.b.inepnakeff) { CLEAR_IN_EP_INTR(epnum, inepnakeff); @@ -488,9 +466,7 @@ static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev) } if (diepint.b.emptyintr) { - DCD_WriteEmptyTxFifo(pdev , epnum); - CLEAR_IN_EP_INTR(epnum, emptyintr); } } @@ -557,11 +533,6 @@ static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev) /* Clear the bit in DOEPINTn for this interrupt */ CLEAR_OUT_EP_INTR(epnum, epdisabled); } - /* AHB Error */ - if ( doepint.b.ahberr ) - { - CLEAR_OUT_EP_INTR(epnum, ahberr); - } /* Setup Phase Done (control EPs) */ if ( doepint.b.setup ) { @@ -666,7 +637,7 @@ static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum) uint32_t len32b; txstatus.d32 = 0; - ep = &pdev->dev.in_ep[epnum]; + ep = &pdev->dev.in_ep[epnum]; len = ep->xfer_len - ep->xfer_count; @@ -678,8 +649,6 @@ static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum) len32b = (len + 3) / 4; txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS); - - while (txstatus.b.txfspcavail > len32b && ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) @@ -753,7 +722,6 @@ static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev) doepmsk.b.setup = 1; doepmsk.b.xfercompl = 1; - doepmsk.b.ahberr = 1; doepmsk.b.epdisabled = 1; USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 ); #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED @@ -762,8 +730,7 @@ static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev) diepmsk.b.xfercompl = 1; diepmsk.b.timeout = 1; diepmsk.b.epdisabled = 1; - diepmsk.b.ahberr = 1; - diepmsk.b.intknepmis = 1; + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 ); #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 ); @@ -807,13 +774,13 @@ static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev) if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH) { pdev->cfg.speed = USB_OTG_SPEED_HIGH; - pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ; + pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ; gusbcfg.b.usbtrdtim = 9; } else { pdev->cfg.speed = USB_OTG_SPEED_FULL; - pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; + pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; gusbcfg.b.usbtrdtim = 5; } @@ -883,8 +850,6 @@ static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) return v; } - - /** * @} */ diff --git a/STM32F4/cores/maple/libmaple/usbF4/VCP/core_cm4.h b/STM32F4/cores/maple/libmaple/usbF4/VCP/core_cm4.h index ff5e9a6d4..5da768767 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/VCP/core_cm4.h +++ b/STM32F4/cores/maple/libmaple/usbF4/VCP/core_cm4.h @@ -975,13 +975,14 @@ typedef struct /** \ingroup CMSIS_core_register @{ */ +#include /* Memory mapping of Cortex-M4 Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +//#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ diff --git a/STM32F4/cores/maple/libmaple/usbF4/VCP/misc.c b/STM32F4/cores/maple/libmaple/usbF4/VCP/misc.c index 15a715e87..12ba2d195 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/VCP/misc.c +++ b/STM32F4/cores/maple/libmaple/usbF4/VCP/misc.c @@ -68,12 +68,8 @@ /* Includes ------------------------------------------------------------------*/ typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; -typedef unsigned long uint32_t; -typedef unsigned int u32; -typedef unsigned short uint16_t; -typedef unsigned short u16; -typedef unsigned char uint8_t; -typedef unsigned char u8; + + #include "misc.h" #define assert_param(x) diff --git a/STM32F4/cores/maple/libmaple/usbF4/VCP/misc.h b/STM32F4/cores/maple/libmaple/usbF4/VCP/misc.h index 1f87d1b3e..9753592d2 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/VCP/misc.h +++ b/STM32F4/cores/maple/libmaple/usbF4/VCP/misc.h @@ -28,8 +28,10 @@ extern "C" { #endif + /* Includes ------------------------------------------------------------------*/ //#include "stm32f4xx.h" +#include "usb_conf.h" /** @addtogroup STM32F4xx_StdPeriph_Driver * @{ diff --git a/STM32F4/cores/maple/libmaple/usbF4/VCP/usb_bsp.c b/STM32F4/cores/maple/libmaple/usbF4/VCP/usb_bsp.c index c3650384c..493331818 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/VCP/usb_bsp.c +++ b/STM32F4/cores/maple/libmaple/usbF4/VCP/usb_bsp.c @@ -140,7 +140,7 @@ void USB_OTG_BSP_DeInit(USB_OTG_CORE_HANDLE *pdev) gpio_set_af_mode(GPIOA,10,GPIO_AF0) ; // OTG_FS_ID #endif - rcc_clk_enable(RCC_SYSCFG); +// rcc_clk_disable(RCC_SYSCFG); rcc_clk_disable(RCC_USBFS); } diff --git a/STM32F4/cores/maple/libmaple/usbF4/VCP/usb_conf.h b/STM32F4/cores/maple/libmaple/usbF4/VCP/usb_conf.h index fd45f4db3..7daf0b5c9 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/VCP/usb_conf.h +++ b/STM32F4/cores/maple/libmaple/usbF4/VCP/usb_conf.h @@ -23,20 +23,20 @@ #ifndef __USB_CONF__H__ #define __USB_CONF__H__ +#include #define USE_USB_OTG_FS #define __IO volatile -typedef unsigned long uint32_t; -typedef unsigned int u32; -typedef unsigned short uint16_t; +//typedef unsigned int uint32_t; +typedef unsigned int u32; +//typedef unsigned short uint16_t; typedef unsigned short u16; -typedef unsigned char uint8_t; -typedef unsigned char u8; +//typedef unsigned char uint8_t; +typedef unsigned char u8; /* Includes ------------------------------------------------------------------*/ //#include "stm32f4xx.h" - /** @addtogroup USB_OTG_DRIVER * @{ */ @@ -164,42 +164,7 @@ typedef unsigned char u8; #endif /* __GNUC__ */ #else #define __ALIGN_BEGIN - #define __ALIGN_END -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/* __packed keyword used to decrease the data type alignment to 1-byte */ -#if defined (__CC_ARM) /* ARM Compiler */ - #define __packed __packed -#elif defined (__ICCARM__) /* IAR Compiler */ - #define __packed __packed -#elif defined ( __GNUC__ ) /* GNU Compiler */ - #ifndef __packed - #define __packed __attribute__ ((__packed__)) - #endif -#elif defined (__TASKING__) /* TASKING Compiler */ - #define __packed __unaligned -#endif /* __CC_ARM */ - -/****************** C Compilers dependant keywords ****************************/ -/* In HS mode and when the DMA is used, all variables and data structures dealing - with the DMA during the transaction process should be 4-bytes aligned */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined (__GNUC__) /* GNU Compiler */ - #define __ALIGN_END __attribute__ ((aligned (4))) - #define __ALIGN_BEGIN - #else - #define __ALIGN_END - #if defined (__CC_ARM) /* ARM Compiler */ - #define __ALIGN_BEGIN __align(4) - #elif defined (__ICCARM__) /* IAR Compiler */ - #define __ALIGN_BEGIN - #elif defined (__TASKING__) /* TASKING Compiler */ - #define __ALIGN_BEGIN __align(4) - #endif /* __CC_ARM */ - #endif /* __GNUC__ */ -#else - #define __ALIGN_BEGIN - #define __ALIGN_END + #define __ALIGN_END __attribute__ ((aligned (4))) #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ /* __packed keyword used to decrease the data type alignment to 1-byte */ diff --git a/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_cdc_vcp.c b/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_cdc_vcp.c index bc4374795..58d7e2e40 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_cdc_vcp.c +++ b/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_cdc_vcp.c @@ -25,6 +25,7 @@ /* Includes ------------------------------------------------------------------*/ #include "usbd_cdc_vcp.h" +#include /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ @@ -43,43 +44,65 @@ LINE_CODING linecoding = /* These are external variables imported from CDC core to be used for IN transfer management. */ -extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer. +extern uint8_t APP_Tx_Buffer []; /* Write CDC received data in this buffer. These data will be sent over USB IN endpoint in the CDC core functions. */ -extern volatile int APP_Rx_ptr_in; /* Increment this pointer or roll it back to +extern volatile uint16_t APP_Tx_ptr_in; /* Increment this pointer or roll it back to start address when writing received data - in the buffer APP_Rx_Buffer. */ -extern volatile int APP_Rx_ptr_out; + in the buffer APP_Tx_Buffer. */ +extern volatile uint16_t APP_Tx_ptr_out; #define UsbRecBufferSize 2048 -uint8_t UsbRecBuffer[UsbRecBufferSize]; +#define UsbRecBufferSizeMask (UsbRecBufferSize-1) +uint8_t __CCMRAM__ UsbRecBuffer[UsbRecBufferSize]; volatile int UsbRecRead = 0; volatile int UsbRecWrite = 0; -volatile int VCP_DTRHIGH = 0; +volatile uint8_t VCP_DTRHIGH = 0; +volatile uint8_t VCP_RTSHIGH = 0; uint8_t UsbTXBlock = 1; +uint8_t rxDisabled = 1; +USB_OTG_CORE_HANDLE * usbDevice = NULL; -uint32_t VCPBytesAvailable(void) { - return (UsbRecWrite - UsbRecRead + UsbRecBufferSize) % UsbRecBufferSize; +uint8_t VCPGetDTR(void) { return VCP_DTRHIGH; } +uint8_t VCPGetRTS(void) { return VCP_RTSHIGH; } + +uint32_t VCPBytesAvailable(void) +{ + return (UsbRecWrite - UsbRecRead) & UsbRecBufferSizeMask; } -uint8_t VCPGetByte(void) { - if(UsbRecWrite == UsbRecRead) { +uint32_t VCPGetBytes(uint8_t * rxBuf, uint32_t len) +{ + int usbRxRead = UsbRecRead; // take volatile + uint32_t rx_unread = (UsbRecWrite - usbRxRead) & UsbRecBufferSizeMask; + if (rx_unread==0) { return 0; - } else { - uint8_t c = UsbRecBuffer[UsbRecRead++]; - if(UsbRecRead == UsbRecBufferSize) { - UsbRecRead = 0; - } - return c; } + if (len>rx_unread) len = rx_unread; + + for (uint32_t i = 0; i=CDC_DATA_MAX_PACKET_SIZE && rxDisabled ) + { + rxDisabled = 0; + extern void usbd_cdc_PrepareRx (void *pdev); + if (usbDevice) usbd_cdc_PrepareRx(usbDevice); + } + return len; } /* Private function prototypes -----------------------------------------------*/ -static uint16_t VCP_Init (void); -static uint16_t VCP_DeInit (void); -static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len); -uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len); -static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len); +static uint16_t VCP_Init (void *pdev); +static uint16_t VCP_DeInit(void); +static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len); +uint32_t VCP_DataTx (const uint8_t* Buf, uint32_t Len); +static uint16_t VCP_DataRx(uint8_t* Buf, uint32_t Len); static uint16_t VCP_COMConfig(uint8_t Conf); @@ -99,8 +122,10 @@ CDC_IF_Prop_TypeDef VCP_fops = * @param None * @retval Result of the opeartion (USBD_OK in all cases) */ -static uint16_t VCP_Init(void) +static uint16_t VCP_Init(void *pdev) { + usbDevice = pdev; + rxDisabled = 0; return USBD_OK; } @@ -112,7 +137,8 @@ static uint16_t VCP_Init(void) */ static uint16_t VCP_DeInit(void) { - + usbDevice = NULL; + rxDisabled = 1; return USBD_OK; } @@ -180,9 +206,8 @@ static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) case SET_CONTROL_LINE_STATE: linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8)); - if(Buf[0] & 1) { - VCP_DTRHIGH = 1; - } + VCP_DTRHIGH = (Buf[0] & 0x1); + VCP_RTSHIGH = (Buf[0] & 0x2)>>1; /* Not needed for this driver */ break; @@ -203,29 +228,39 @@ static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) * this function. * @param Buf: Buffer of data to be sent * @param Len: Number of data to be sent (in bytes) - * @retval Result of the operation: USBD_OK if all operations are OK else VCP_FAIL + * @retval cnt: number of bytes sent */ -uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len) +uint32_t VCP_DataTx (const uint8_t* Buf, uint32_t Len) { - while(Len-- > 0) { - if(UsbTXBlock) { - while ((APP_Rx_ptr_in - APP_Rx_ptr_out + APP_RX_DATA_SIZE) % APP_RX_DATA_SIZE + 1 >= APP_RX_DATA_SIZE) - ; - } else { - if ((APP_Rx_ptr_in - APP_Rx_ptr_out + APP_RX_DATA_SIZE) % APP_RX_DATA_SIZE + 1 >= APP_RX_DATA_SIZE) { - return USBD_BUSY; + uint32_t ptrIn = APP_Tx_ptr_in; // get volatile + uint32_t cnt = 0; + uint16_t cdc_buf_cnt = 0; + while ( cnt= 4) { - if(Buf[0] == '1' && Buf[1] == 'E' && Buf[2] == 'A' && Buf[3] == 'F') { - Len = 0; - *(int*)0x20000BFC = 0x4AFC6BB2; - systemHardReset(); - } + if (!VCP_DTRHIGH) return USBD_BUSY; + + if (Len >= 4) { + if(Buf[0] == '1' && Buf[1] == 'E' && Buf[2] == 'A' && Buf[3] == 'F') { + Len = 0; + + bkp_init(); + bkp_enable_writes(); + *(__IO uint32_t *)(BKP) = 0x424C; + bkp_disable_writes(); + + systemHardReset(); } } - VCP_DTRHIGH = 0; + + uint32_t rxWr = UsbRecWrite; // get volatile while(Len-- > 0) { - UsbRecBuffer[UsbRecWrite] = *Buf++; - if(UsbRecWrite == UsbRecBufferSize) { - UsbRecWrite = 0; - } else { - UsbRecWrite ++; - } + UsbRecBuffer[rxWr++] = *Buf++; + rxWr &= UsbRecBufferSizeMask; } - - return USBD_OK; + UsbRecWrite = rxWr; // store volatile + // check for enough space in Rx buffer for the next Rx packet + uint32_t free_rx_space = (UsbRecRead-rxWr-1) & UsbRecBufferSizeMask; + if ( free_rx_space #include "usbd_conf.h" @@ -42,15 +41,6 @@ typedef struct uint8_t datatype; }LINE_CODING; -/* Exported constants --------------------------------------------------------*/ -/* The following define is used to route the USART IRQ handler to be used. - The IRQ handler function is implemented in the usbd_cdc_vcp.c file. */ -#ifdef USE_STM322xG_EVAL - #define EVAL_COM_IRQHandler USART3_IRQHandler -#elif defined(USE_STM3210C_EVAL) - #define EVAL_COM_IRQHandler USART2_IRQHandler -#endif /* USE_STM322xG_EVAL */ -#define EVAL_COM_IRQHandler USART2_IRQHandler #define DEFAULT_CONFIG 0 #define OTHER_CONFIG 1 diff --git a/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_conf.h b/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_conf.h index 62a40c27c..8246d13c2 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_conf.h +++ b/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_conf.h @@ -32,7 +32,7 @@ */ #define USBD_CFG_MAX_NUM 1 #define USBD_ITF_MAX_NUM 1 -#define USB_MAX_STR_DESC_SIZ 50 +#define USB_MAX_STR_DESC_SIZ (64+4) // longest descriptor string length + 2 /** @defgroup USB_VCP_Class_Layer_Parameter * @{ @@ -47,16 +47,17 @@ #define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */ #define CDC_IN_FRAME_INTERVAL 40 /* Number of micro-frames between IN transfers */ - #define APP_RX_DATA_SIZE 2048 /* Total size of IN buffer: + #define APP_TX_DATA_SIZE 2048 /* Total size of IN buffer: APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL*8 */ #else #define CDC_DATA_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ #define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */ #define CDC_IN_FRAME_INTERVAL 5 /* Number of frames between IN transfers */ - #define APP_RX_DATA_SIZE 2048 /* Total size of IN buffer: + #define APP_TX_DATA_SIZE 512 /* Total size of IN buffer (must be power of 2): APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */ #endif /* USE_USB_OTG_HS */ +#define APP_TX_DATA_SIZE_MASK (APP_TX_DATA_SIZE-1) #define APP_FOPS VCP_fops /** diff --git a/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_desc.c b/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_desc.c index e37e28c72..db922286b 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_desc.c +++ b/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_desc.c @@ -57,10 +57,10 @@ #define USBD_LANGID_STRING 0x409 #define USBD_MANUFACTURER_STRING (uint8_t*)"STMicroelectronics" -#define USBD_PRODUCT_HS_STRING (uint8_t*)"STM32 Virtual ComPort in HS mode" +#define USBD_PRODUCT_HS_STRING (uint8_t*)"STM32 Virtual ComPort in HS Mode" #define USBD_SERIALNUMBER_HS_STRING (uint8_t*)"00000000050B" -#define USBD_PRODUCT_FS_STRING (uint8_t*)"STM32 Virtual ComPort in FS Mode" +#define USBD_PRODUCT_FS_STRING (uint8_t*)"STM32 Virtual ComPort in FS Mode" #define USBD_SERIALNUMBER_FS_STRING (uint8_t*)"00000000050C" #define USBD_CONFIGURATION_HS_STRING (uint8_t*)"VCP Config" diff --git a/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_desc.h b/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_desc.h index 987767ff2..36478731c 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_desc.h +++ b/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_desc.h @@ -27,6 +27,7 @@ /* Includes ------------------------------------------------------------------*/ #include + /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY * @{ */ diff --git a/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_usr.c b/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_usr.c index 44eef15e1..a05ac08cc 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_usr.c +++ b/STM32F4/cores/maple/libmaple/usbF4/VCP/usbd_usr.c @@ -22,7 +22,7 @@ /* Includes ------------------------------------------------------------------*/ #include #include - +#include "bits.h" /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY * @{ @@ -71,11 +71,23 @@ USBD_Usr_cb_TypeDef USR_cb = USBD_USR_DeviceConnected, USBD_USR_DeviceDisconnected, - - }; +enum { + USB_CONFIGURED = BIT0, + USB_CONNECTED = BIT1, + USB_RESUMED = BIT2, +}; +static volatile uint8_t usbd_status; + +uint8_t usb_isConfigured(void) { return (usbd_status&USB_CONFIGURED); } +#ifdef VBUS_SENSING_ENABLED +uint8_t usb_isConnected(void) { return (usbd_status&USB_CONNECTED); } +#else +uint8_t usb_isConnected(void) { return USB_CONNECTED; } +#endif +uint8_t usb_getStatus(void) { return usbd_status; } /** * @} @@ -120,6 +132,8 @@ void USBD_USR_Init(void) while (1); } #endif + + usbd_status = 0; } /** @@ -141,6 +155,7 @@ void USBD_USR_DeviceReset(uint8_t speed ) break; } + usbd_status = 0; } @@ -152,6 +167,7 @@ void USBD_USR_DeviceReset(uint8_t speed ) */ void USBD_USR_DeviceConfigured (void) { + usbd_status |= USB_CONFIGURED; } @@ -163,6 +179,7 @@ void USBD_USR_DeviceConfigured (void) */ void USBD_USR_DeviceConnected (void) { + usbd_status |= USB_CONNECTED; } @@ -174,6 +191,7 @@ void USBD_USR_DeviceConnected (void) */ void USBD_USR_DeviceDisconnected (void) { + usbd_status &= ~USB_CONNECTED; } /** @@ -185,6 +203,7 @@ void USBD_USR_DeviceDisconnected (void) void USBD_USR_DeviceSuspended(void) { /* Users can do their application actions here for the USB-Reset */ + usbd_status &= ~USB_RESUMED; } @@ -197,6 +216,7 @@ void USBD_USR_DeviceSuspended(void) void USBD_USR_DeviceResumed(void) { /* Users can do their application actions here for the USB-Reset */ + usbd_status |= USB_RESUMED; } /** diff --git a/STM32F4/cores/maple/libmaple/usbF4/usb.c b/STM32F4/cores/maple/libmaple/usbF4/usb.c index 3e9218609..fe22eee26 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/usb.c +++ b/STM32F4/cores/maple/libmaple/usbF4/usb.c @@ -13,8 +13,6 @@ USB_OTG_CORE_HANDLE USB_OTG_dev; - - void setupUSB (void) { gpio_set_mode(BOARD_USB_DP_PIN, GPIO_OUTPUT_OD); // ala42 @@ -25,11 +23,7 @@ void setupUSB (void) #endif gpio_clear_pin(BOARD_USB_DP_PIN); // ala42 - delay_us(200000); - - /* setup the apb1 clock for USB */ - //rcc_reg_map *pRCC = RCC_BASE; - //pRCC->APB1ENR |= RCC_APB1ENR_USBEN; + delay_us(50000); /* initialize the usb application */ gpio_set_pin(BOARD_USB_DP_PIN); // ala42 // presents us to the host @@ -40,66 +34,30 @@ void setupUSB (void) &USR_cb); } -extern uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len); -extern void VCP_SetUSBTxBlocking(uint8_t mode); -extern uint32_t VCPBytesAvailable(void); +extern uint16_t VCP_DataTx (const uint8_t* Buf, uint32_t Len); extern uint8_t VCPGetByte(void); +extern uint32_t VCPGetBytes(uint8_t * rxBuf, uint32_t len); -uint32_t usbSendBytes(const uint8_t* sendBuf, uint32_t len) { - VCP_DataTx((uint8_t*)sendBuf, len); - return len; -} - -void usbEnableBlockingTx(void) { - VCP_SetUSBTxBlocking(1); -} - -void usbDisableBlockingTx(void) { - VCP_SetUSBTxBlocking(0); -} - - -uint32_t usbBytesAvailable(void) { - return VCPBytesAvailable(); - -} -uint32_t usbReceiveBytes(uint8_t* recvBuf, uint32_t len) { - int newBytes = usbBytesAvailable(); - if (len > newBytes) { - len = newBytes; - } - - int i; - for (i=0;i -void __irq_OTG_FS_IRQHandler(void) +void __irq_usb_fs(void) { - USBD_OTG_ISR_Handler (&USB_OTG_dev); + USBD_OTG_ISR_Handler (&USB_OTG_dev); } void x__irq_usbwakeup(void) diff --git a/STM32F4/cores/maple/libmaple/usbF4/usb.h b/STM32F4/cores/maple/libmaple/usbF4/usb.h index 7f0b2aa7e..8478e2e86 100644 --- a/STM32F4/cores/maple/libmaple/usbF4/usb.h +++ b/STM32F4/cores/maple/libmaple/usbF4/usb.h @@ -22,27 +22,29 @@ void usbSuspend(void); void usbResumeInit(void); //void usbResume(RESUME_STATE); -RESULT usbPowerOn(void); +inline RESULT usbPowerOn(void) { return USB_SUCCESS; } RESULT usbPowerOff(void); -void usbDsbISR(void); -void usbEnbISR(void); - void usbBlockingSendByte(char ch); uint32_t usbSendBytes(const uint8_t* sendBuf,uint32_t len); -uint32_t usbBytesAvailable(void); +extern uint32_t VCPBytesAvailable(void); +inline uint32_t usbBytesAvailable(void) { return VCPBytesAvailable(); } uint32_t usbReceiveBytes(uint8_t* recvBuf, uint32_t len); -uint8_t usbGetDTR(void); -uint8_t usbGetRTS(void); -uint8_t usbIsConnected(void); -uint8_t usbIsConfigured(void); -uint16_t usbGetPending(void); -void usbEnableBlockingTx(void); -void usbDisableBlockingTx(void); +extern uint8_t VCPGetDTR(void); +extern uint8_t VCPGetRTS(void); +inline uint8_t usbGetDTR(void) { return VCPGetDTR(); }; +inline uint8_t usbGetRTS(void) { return VCPGetRTS(); }; +extern uint8_t usb_isConnected(void); +extern uint8_t usb_isConfigured(void); +inline uint8_t usbIsConnected(void) { return usb_isConnected(); } +inline uint8_t usbIsConfigured(void) { return usb_isConfigured(); } +uint16_t usbGetPending(void); +extern void VCP_SetUSBTxBlocking(const uint8_t mode); +inline void usbEnableBlockingTx(void) { VCP_SetUSBTxBlocking(1); } +inline void usbDisableBlockingTx(void) { VCP_SetUSBTxBlocking(0); } -void __irq_OTG_FS_IRQHandler(void); #ifdef __cplusplus } // extern "C" diff --git a/STM32F4/cores/maple/libmaple/util.c b/STM32F4/cores/maple/libmaple/util.c index 8a745e87d..db758f4d2 100644 --- a/STM32F4/cores/maple/libmaple/util.c +++ b/STM32F4/cores/maple/libmaple/util.c @@ -46,12 +46,9 @@ #define ERROR_TX_PIN 2 #endif -/* If you define ERROR_LED_PORT and ERROR_LED_PIN, then a failed +/* If you define ERROR_LED_PIN, then a failed * ASSERT() will also throb() an LED connected to that port and pin. */ -#if defined(ERROR_LED_PORT) && defined(ERROR_LED_PIN) -#define HAVE_ERROR_LED -#endif /** * @brief Disables all peripheral interrupts except USB and fades the @@ -80,8 +77,7 @@ void __error(int num) { usart_disable_all(); /* Turn the USB interrupt back on so the bootloader keeps on functioning */ - nvic_irq_enable(NVIC_USB_HP_CAN_TX); - nvic_irq_enable(NVIC_USB_LP_CAN_RX0); + nvic_irq_enable(NVIC_USB_FS); /* Reenable global interrupts */ nvic_globalirq_enable(); @@ -122,7 +118,7 @@ void _fail(const char* file, int line, const char* exp) { * @sideeffect Sets output push-pull on ERROR_LED_PIN. */ void throb(void) { -#ifdef HAVE_ERROR_LED +#ifdef ERROR_LED_PIN int32 slope = 1; uint32 CC = 0x0000; uint32 TOP_CNT = 0x0800; @@ -155,3 +151,6 @@ void throb(void) { ; #endif } + +static void __empty() { } +__weak void yield() { __empty(); }; diff --git a/STM32F4/cores/maple/libmaple/util.h b/STM32F4/cores/maple/libmaple/util.h index c5ed2de07..2bfeec742 100644 --- a/STM32F4/cores/maple/libmaple/util.h +++ b/STM32F4/cores/maple/libmaple/util.h @@ -52,6 +52,9 @@ extern "C"{ /** True if v is a power of two (1, 2, 4, 8, ...) */ #define IS_POWER_OF_TWO(v) ((v) && !((v) & ((v) - 1))) +#define __weak __attribute__((weak)) + + /* * Failure routines */ @@ -59,6 +62,7 @@ extern "C"{ void __error(int num); void _fail(const char*, int, const char*); void throb(void); +void yield(); /* * Asserts and debug levels diff --git a/STM32F4/cores/maple/pwm.cpp b/STM32F4/cores/maple/pwm.cpp index c5f2ccbc6..0f5729b5a 100644 --- a/STM32F4/cores/maple/pwm.cpp +++ b/STM32F4/cores/maple/pwm.cpp @@ -35,10 +35,14 @@ #include "pwm.h" void pwmWrite(uint8 pin, uint16 duty_cycle) { - timer_dev *dev = PIN_MAP[pin].timer_device; - if (pin >= BOARD_NR_GPIO_PINS || dev == NULL || dev->type == TIMER_BASIC) { + if ( pin >= BOARD_NR_GPIO_PINS ) return; + const timer_info * t_info = &timer_map[pin]; + uint8_t index = t_info->index; + const timer_dev *dev = timer_devices[index]; + + if (index==NO_TIM || index>=LAST_TIM || dev == NULL || dev->type == TIMER_BASIC) { return; } - timer_set_compare(dev, PIN_MAP[pin].timer_channel, duty_cycle); + timer_set_compare(dev, t_info->channel, duty_cycle); } diff --git a/STM32F4/cores/maple/usb_serial.cpp b/STM32F4/cores/maple/usb_serial.cpp index 1764e86fd..3e983186f 100644 --- a/STM32F4/cores/maple/usb_serial.cpp +++ b/STM32F4/cores/maple/usb_serial.cpp @@ -29,13 +29,12 @@ */ #include - #include "wirish.h" -#include "usb.h" + #ifdef SERIAL_USB -#define USB_TIMEOUT 50 +#define USB_TIMEOUT 500 bool USBSerial::_hasBegun = false; USBSerial::USBSerial(void) { @@ -57,7 +56,7 @@ void USBSerial::end(void) { _hasBegun = false; } -size_t USBSerial::write(uint8 ch) { +size_t USBSerial::write(const uint8 ch) { const uint8 buf[] = {ch}; return this->write(buf, 1); } @@ -66,8 +65,10 @@ size_t USBSerial::write(const char *str) { return this->write(str, strlen(str)); } -size_t USBSerial::write(const void *buf, uint32 len) { - if (!(usbIsConnected() && usbIsConfigured()) || !buf) { +uint32 usb_tx_cnt = 0; // global Tx byte counter +size_t USBSerial::write(const void *buf, uint32 len) +{ + if (!(usbOK()) || !buf) { return 0; } @@ -75,21 +76,19 @@ size_t USBSerial::write(const void *buf, uint32 len) { uint32 old_txed = 0; uint32 start = millis(); - while (txed < len && (millis() - start < USB_TIMEOUT)) { + while ( (txed < len) && ((millis() - start) < USB_TIMEOUT) ) { txed += usbSendBytes((const uint8*)buf + txed, len - txed); if (old_txed != txed) { start = millis(); } old_txed = txed; } + usb_tx_cnt += txed; return txed; } -int USBSerial::available(void) { - return usbBytesAvailable(); -} - -int USBSerial::read(void *buf, uint32 len) { +int USBSerial::read(void *buf, uint32 len) +{ if (!buf) { return 0; } @@ -103,7 +102,8 @@ int USBSerial::read(void *buf, uint32 len) { } /* Blocks forever until 1 byte is received */ -int USBSerial::read(void) { +int USBSerial::read(void) +{ uint8 buf[1]; this->read(buf, 1); return buf[0]; @@ -124,6 +124,11 @@ int USBSerial::peek(void) } } +uint8 USBSerial::usbOK(void) +{ + return usbIsConnected() && usbIsConfigured() && usbGetDTR(); +} + void USBSerial::flush(void) { /*Roger Clark. Rather slow method. Need to improve this */ @@ -135,29 +140,6 @@ void USBSerial::flush(void) return; } -uint8 USBSerial::pending(void) { - return usbGetPending(); -} - -USBSerial::operator bool() { - return usbIsConnected() && usbIsConfigured(); -} - -uint8 USBSerial::getDTR(void) { - return usbGetDTR(); -} - -uint8 USBSerial::getRTS(void) { - return usbGetRTS(); -} - -void USBSerial::enableBlockingTx(void) { - usbEnableBlockingTx(); -} - -void USBSerial::disableBlockingTx(void) { - usbDisableBlockingTx(); -} USBSerial SerialUSB; diff --git a/STM32F4/cores/maple/usb_serial.h b/STM32F4/cores/maple/usb_serial.h index 228802566..b5b239f95 100644 --- a/STM32F4/cores/maple/usb_serial.h +++ b/STM32F4/cores/maple/usb_serial.h @@ -31,6 +31,7 @@ #ifndef _USB_SERIAL_H_ #define _USB_SERIAL_H_ +#include "usb.h" #include "Stream.h" #ifdef SERIAL_USB @@ -38,7 +39,8 @@ /** * @brief Virtual serial terminal. */ -class USBSerial : public Stream { +class USBSerial : public Stream +{ public: USBSerial(void); @@ -46,25 +48,27 @@ class USBSerial : public Stream { void begin(int); void end(void); - virtual int available(void); + virtual int available(void) { return usbBytesAvailable(); } virtual int peek(void); virtual void flush(void); virtual int read(void *buf, uint32 len); virtual int read(void); - size_t write(uint8); + size_t write(const uint8); size_t write(const char *str); size_t write(const void*, uint32); - uint8 getRTS(); - uint8 getDTR(); - operator bool(); - uint8 isConnected() { return (bool) *this; } - uint8 pending(); + uint8 getRTS() { return usbGetRTS(); } + uint8 getDTR() { return usbGetDTR(); } + uint8 usbOK(void); + operator bool() { return usbOK(); } + uint8 isConnected() __attribute__((deprecated("Use !Serial instead"))) { return usbOK(); } + uint8 isConfigured() { return usbIsConfigured(); } + uint8 pending() { return usbGetPending(); } - void enableBlockingTx(void); - void disableBlockingTx(void); + void enableBlockingTx(void) { usbEnableBlockingTx(); } + void disableBlockingTx(void) { usbDisableBlockingTx(); } protected: static bool _hasBegun; @@ -73,10 +77,6 @@ class USBSerial : public Stream { extern USBSerial SerialUSB; #define Serial SerialUSB -#else // _USB_SERIAL_H_ - -#define Serial Serial1 - #endif // SERIAL_USB diff --git a/STM32F4/cores/maple/wirish.h b/STM32F4/cores/maple/wirish.h index 945e8fb94..c50444209 100644 --- a/STM32F4/cores/maple/wirish.h +++ b/STM32F4/cores/maple/wirish.h @@ -67,6 +67,8 @@ bitClear(value, bit)) #define bit(b) (1UL << (b)) +#define digitalPinToInterrupt(pin) (pin) + typedef uint8 boolean; typedef uint8 byte; diff --git a/STM32F4/cores/maple/wirish_analog.cpp b/STM32F4/cores/maple/wirish_analog.cpp index 4e920e7c7..687586ffe 100644 --- a/STM32F4/cores/maple/wirish_analog.cpp +++ b/STM32F4/cores/maple/wirish_analog.cpp @@ -30,13 +30,59 @@ #include "wirish.h" -/* Assumes that the ADC has been initialized and that the pin is set - * to INPUT_ANALOG */ -uint16 analogRead(uint8 pin) { - const adc_dev *dev = PIN_MAP[pin].adc_device; - if (dev == NULL) { +#define ADCx 0xFF + +const uint8 adc_map[] = { + 0, /* D00/PA0 */ + 1, /* D01/PA1 */ + 2, /* D02/PA2 */ + 3, /* D03/PA3 */ + 4, /* D04/PA4 */ + 5, /* D05/PA5 */ + 6, /* D06/PA6 */ + 7, /* D07/PA7 */ +ADCx, /* D08/PA8 */ +ADCx, /* D09/PA9 */ +ADCx, /* D10/PA10 */ +ADCx, /* D11/PA11 */ +ADCx, /* D12/PA12 */ +ADCx, /* D13/PA13 */ +ADCx, /* D14/PA14 */ +ADCx, /* D15/PA15 */ + + 8, /* D16/PB0 */ + 9, /* D17/PB1 */ +ADCx, /* D18/PB2 */ +ADCx, /* D19/PB3 */ +ADCx, /* D20/PB4 */ +ADCx, /* D21/PB5 */ +ADCx, /* D22/PB6 */ +ADCx, /* D23/PB7 */ +ADCx, /* D24/PB8 */ +ADCx, /* D25/PB9 */ +ADCx, /* D26/PB10 */ +ADCx, /* D27/PB11 */ +ADCx, /* D28/PB12 */ +ADCx, /* D29/PB13 */ +ADCx, /* D30/PB14 */ +ADCx, /* D31/PB15 */ + + 10, /* D32/PC0 */ + 11, /* D33/PC1 */ + 12, /* D34/PC2 */ + 13, /* D35/PC3 */ + 14, /* D36/PC4 */ + 15, /* D37/PC5 */ +ADCx, /* D38/PC6 */ +ADCx, /* D39/PC7 */ +}; + +// Assumes that the ADC has been initialized and the pin set to INPUT_ANALOG +uint16 analogReadDev(uint8 pin, const adc_dev * dev) +{ + uint8_t channel = adc_map[pin]; + if ( channel==ADCx ) return 0; - } - return adc_read(dev, PIN_MAP[pin].adc_channel); + return adc_read(dev, channel); } diff --git a/STM32F4/cores/maple/wirish_debug.h b/STM32F4/cores/maple/wirish_debug.h index d7dea2391..7fcaf9293 100644 --- a/STM32F4/cores/maple/wirish_debug.h +++ b/STM32F4/cores/maple/wirish_debug.h @@ -41,7 +41,7 @@ * @see enableDebugPorts() */ static inline void disableDebugPorts(void) { - afio_cfg_debug_ports(AFIO_DEBUG_NONE); + gpio_cfg_debug_ports(GPIO_DEBUG_NONE); } /** @@ -53,7 +53,7 @@ static inline void disableDebugPorts(void) { * @see disableDebugPorts() */ static inline void enableDebugPorts(void) { - afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); //AFIO_DEBUG_FULL_SWJ); + gpio_cfg_debug_ports(GPIO_DEBUG_SW_ONLY); } #endif diff --git a/STM32F4/cores/maple/wirish_digital.cpp b/STM32F4/cores/maple/wirish_digital.cpp index 4a656199b..281a17c68 100644 --- a/STM32F4/cores/maple/wirish_digital.cpp +++ b/STM32F4/cores/maple/wirish_digital.cpp @@ -74,12 +74,15 @@ void pinMode(uint8 pin, WiringPinMode mode) { gpio_set_mode(pin, outputMode); - if (PIN_MAP[pin].timer_device != NULL) { - /* Enable/disable timer channels if we're switching into or - * out of PWM. */ - timer_set_mode(PIN_MAP[pin].timer_device, - PIN_MAP[pin].timer_channel, + const timer_dev * dev = timer_devices[timer_map[pin].index]; + if (dev != NULL) { + // Enable/disable timer channels if we're switching into or out of PWM. + timer_set_mode(dev, timer_map[pin].channel, pwm ? TIMER_PWM : TIMER_DISABLED); + if ( pwm ) { + gpio_set_af_mode(pin, dev->af_mode); + timer_resume(dev); + } } } @@ -103,6 +106,24 @@ void digitalWrite(uint8 pin, uint8 val) gpio_write_pin(pin, val); } +void digitalSet(uint8 pin) +{ + if (pin >= BOARD_NR_GPIO_PINS) { + return; + } + + gpio_set_pin(pin); +} + +void digitalClear(uint8 pin) +{ + if (pin >= BOARD_NR_GPIO_PINS) { + return; + } + + gpio_clear_pin(pin); +} + void togglePin(uint8 pin) { if (pin >= BOARD_NR_GPIO_PINS) { diff --git a/STM32F4/cores/maple/wirish_math.h b/STM32F4/cores/maple/wirish_math.h index e0373728d..51202b652 100644 --- a/STM32F4/cores/maple/wirish_math.h +++ b/STM32F4/cores/maple/wirish_math.h @@ -91,8 +91,21 @@ long random(long min, long max); #define DEG_TO_RAD 0.017453292519943295769236907684886 #define RAD_TO_DEG 57.295779513082320876798154814105 -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) +#if (__GNUC__ > 4) && defined(__cplusplus) + #include + using std::min; + using std::max; +#else // C + #include + #ifndef min + #define min(a,b) ((a)<(b)?(a):(b)) + #endif // min + + #ifndef max + #define max(a,b) ((a)>(b)?(a):(b)) + #endif // max +#endif // __cplusplus + #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) #define radians(deg) ((deg)*DEG_TO_RAD) @@ -149,4 +162,11 @@ double sqrt(double x); */ double pow(double x, double y); +inline uint16_t makeWord( uint16_t w ) { return w; } + +inline uint16_t makeWord( uint8_t h, uint8_t l ) { return (h << 8) | l; } + +#define word(...) makeWord(__VA_ARGS__) + + #endif diff --git a/STM32F4/cores/maple/wirish_time.cpp b/STM32F4/cores/maple/wirish_time.cpp index 654c1a2d2..c33e4c0c3 100644 --- a/STM32F4/cores/maple/wirish_time.cpp +++ b/STM32F4/cores/maple/wirish_time.cpp @@ -33,10 +33,17 @@ #include "wirish_time.h" #include -void delay(unsigned long ms) { - uint32 i; - for (i = 0; i < ms; i++) { - delayMicroseconds(1000); +void delay(unsigned long ms) +{ + uint32 start = micros(); + while (ms > 0) + { + yield(); + while ( (ms > 0) && ((micros() - start) >= 1000) ) + { + ms--; + start += 1000; + } } } diff --git a/STM32F4/cores/maple/wirish_types.h b/STM32F4/cores/maple/wirish_types.h deleted file mode 100644 index de685bf9f..000000000 --- a/STM32F4/cores/maple/wirish_types.h +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish_types.h - * @author Marti Bolivar - * @brief Wirish library type definitions. - */ - -#ifndef _WIRISH_TYPES_H_ -#define _WIRISH_TYPES_H_ - -#include -#include -#include - -/** - * Invalid stm32_pin_info adc_channel value. - * @see stm32_pin_info - */ -#define ADCx 0xFF - -/** - * @brief Stores STM32-specific information related to a given Maple pin. - * @see PIN_MAP - */ -#ifdef BOARD_generic_f407v -// restructure members to build consecutive pairs -typedef struct stm32_pin_info { - const gpio_dev * gpio_device; /**< Maple pin's GPIO device */ - timer_dev * timer_device; /**< Pin's timer device, if any. */ - uint8 timer_channel; /**< Timer channel, or 0 if none. */ - uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ - const adc_dev *adc_device; /**< ADC device, if any. */ -} stm32_pin_info; - -#else - -typedef struct stm32_pin_info { - const gpio_dev *gpio_device; /**< Maple pin's GPIO device */ - timer_dev *timer_device; /**< Pin's timer device, if any. */ - const adc_dev *adc_device; /**< ADC device, if any. */ - uint8 timer_channel; /**< Timer channel, or 0 if none. */ - uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ -} stm32_pin_info; - -#endif - -/** - * Variable attribute, instructs the linker to place the marked - * variable in Flash instead of RAM. */ -#define __FLASH__ __attr_flash - -#endif diff --git a/STM32F4/examples/whetstone/fpu.txt b/STM32F4/examples/whetstone/fpu.txt new file mode 100644 index 000000000..a0f4931e1 --- /dev/null +++ b/STM32F4/examples/whetstone/fpu.txt @@ -0,0 +1,6 @@ +To use hardware fpu floating point on Cortex-M4 +the compile options + -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant +or + -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant +needs to be stated diff --git a/STM32F4/examples/whetstone/whetmain.ino b/STM32F4/examples/whetstone/whetmain.ino new file mode 100644 index 000000000..b9a802546 --- /dev/null +++ b/STM32F4/examples/whetstone/whetmain.ino @@ -0,0 +1,87 @@ +//This is the same whetstone code with adjustments for the Serial.print function on the Arduino +//To run the code on the Arduino copy and paste the content of "arduino.txt" into the Arduino IDE. +//The main loop within the procedure whetstone() is identical. Only the output format is Arduino-specific. + +#include "Arduino.h" +#include "whetstone.h" +#include +void enablefpu( void ); + +void setup() { + + /* Initializations */ + pinMode(BOARD_LED_PIN, OUTPUT); + + Serial.begin(); + delay(3000); // wait a while for host to connect + + +/* + * FPU is enabled in board_init in the core itself. Hence we'd not need to enable the fpu here + * + * Note that to use hardware fpu floating point + * + * the compile options + * -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant + * or + * -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant + * needs to be stated + +#if defined (__GNUC__) && defined (__VFP_FP__) && !defined(__SOFTFP__) +#warning enabling harware fpu + enablefpu(); +#else +#warning using software floating point +#endif +*/ +} + +void loop() { + int fcpu = 0; + + digitalWrite(BOARD_LED_PIN, LOW); //led is active low + Serial.println("press 'g' to start"); + // wait for a key g + while (1) { + byte c; + if (Serial.available()) + c = Serial.read(); + if (c == 'g') { + break; + } + delay(100); + } + + digitalWrite(BOARD_LED_PIN, HIGH); //led is active low + +#ifdef F_CPU + fcpu = F_CPU / 1000000; +#endif + + whetstone(fcpu); +} + +void blinks() { + for (int i = 0; i < 5; i++) { + digitalWrite(BOARD_LED_PIN, HIGH); + delay(100); + digitalWrite(BOARD_LED_PIN, LOW); + delay(100); + } +} + +//enable the fpu (cortex-m4 - stm32f4* and above) +void enablefpu() +{ + __asm volatile + ( + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ + " ldr r1, [r0] \n" /* read CAPCR */ + " orr r1, r1, #( 0xf << 20 )\n" /* Set bits 20-23 to enable CP10 and CP11 coprocessors */ + " str r1, [r0] \n" /* Write back the modified value to the CPACR */ + " dsb \n" /* wait for store to complete */ + " isb" /* reset pipeline now the FPU is enabled */ + + ); +} + diff --git a/STM32F4/examples/whetstone/whetstone.cpp b/STM32F4/examples/whetstone/whetstone.cpp new file mode 100644 index 000000000..fc16c672e --- /dev/null +++ b/STM32F4/examples/whetstone/whetstone.cpp @@ -0,0 +1,483 @@ + +#include +#include +#include +#include +#include +#include +/* the following is optional depending on the timing function used */ +#include +#include "whetstone.h" + +/* default is double precision, define this for single precision */ +#define SINGLE_PRECISION + +#ifdef SINGLE_PRECISION +#define DSIN sinf +#define DCOS cosf +#define DATAN atanf +#define DLOG logf +#define DEXP expf +#define DSQRT sqrtf +#else +/* map the FORTRAN math functions, etc. to the C versions */ +#define DSIN sin +#define DCOS cos +#define DATAN atan +#define DLOG log +#define DEXP exp +#define DSQRT sqrt +#endif +#define IF if + +/* function prototypes */ +#ifdef SINGLE_PRECISION +void POUT(long N, long J, long K, float X1, float X2, float X3, float X4); +void PA(float E[]); +void P3(float X, float Y, float *Z); +#else +void POUT(long N, long J, long K, double X1, double X2, double X3, double X4); +void PA(double E[]); +void P3(double X, double Y, double *Z); +#endif +void P0(void); +#define USAGE "usage: whetdc [-c] [loops]\n" + +/* + COMMON T,T1,T2,E1(4),J,K,L +*/ +#ifdef SINGLE_PRECISION +float T,T1,T2,E1[5]; +#else +double T,T1,T2,E1[5]; +#endif +int J,K,L; + +int argc=0;//Mod for nucleo. Change in code below if you want non-default loop count + +/* see the note about LOOP and II below */ +#define NUMBER_OF_LOOPS 10000 +#define NUMBER_OF_ITERATIONS 1 + +int whetstone(int argc) +{ + blinks(); + Serial.print("Beginning Whetstone benchmark at "); + if(argc==0) + Serial.print("default speed ...\n"); + else { + Serial.print(argc); + Serial.print(" MHz ...\n"); + } + /* used in the FORTRAN version */ + long I; + long N1, N2, N3, N4, N6, N7, N8, N9, N10, N11; +#ifdef SINGLE_PRECISION + float X1,X2,X3,X4,X,Y,Z; +#else + double X1,X2,X3,X4,X,Y,Z; +#endif + long LOOP; + int II, JJ; + + /* added for this version */ + long loopstart; + long Begin_Time, End_Time; + float KIPS; + int continuous; + + loopstart = NUMBER_OF_LOOPS; /* see the note about LOOP below */ + continuous = 0; + + II = 1; /* start at the first arg (temp use of II here) */ + /* while (II < argc) { + if (strncmp(argv[II], "-c", 2) == 0 || argv[II][0] == 'c') { + continuous = 1; + } else if (atol(argv[II]) > 0) { + loopstart = atol(argv[II]); + } else { +// fprintf(stderr, USAGE);//original code + fprintf(stderr, USAGE);//not output toSTM32 version + return(1); + } + II++; + }*/ + +LCONT: +/* +C +C Start benchmark timing at this point. +C +*/ + Begin_Time = micros(); + +/* +C +C The actual benchmark starts here. +C +*/ + T = .499975; + T1 = 0.50025; + T2 = 2.0; +/* +C +C With loopcount LOOP=10, one million Whetstone instructions +C will be executed in EACH MAJOR LOOP..A MAJOR LOOP IS EXECUTED +C 'II' TIMES TO INCREASE WALL-CLOCK TIMING ACCURACY. +C + LOOP = 1000; +*/ + LOOP = loopstart; + II = NUMBER_OF_ITERATIONS; + + JJ = 1; + +IILOOP: + N1 = 0; + N2 = 12 * LOOP; + N3 = 14 * LOOP; + N4 = 345 * LOOP; + N6 = 210 * LOOP; + N7 = 32 * LOOP; + N8 = 899 * LOOP; + N9 = 616 * LOOP; + N10 = 0; + N11 = 93 * LOOP; +/* +C +C Module 1: Simple identifiers +C +*/ + X1 = 1.0; + X2 = -1.0; + X3 = -1.0; + X4 = -1.0; + + for (I = 1; I <= N1; I++) { + X1 = (X1 + X2 + X3 - X4) * T; + X2 = (X1 + X2 - X3 + X4) * T; + X3 = (X1 - X2 + X3 + X4) * T; + X4 = (-X1+ X2 + X3 + X4) * T; + } +#ifdef PRINTOUT + IF (JJ==II)POUT(N1,N1,N1,X1,X2,X3,X4); +#endif + +/* +C +C Module 2: Array elements +C +*/ + E1[1] = 1.0; + E1[2] = -1.0; + E1[3] = -1.0; + E1[4] = -1.0; + + for (I = 1; I <= N2; I++) { + E1[1] = ( E1[1] + E1[2] + E1[3] - E1[4]) * T; + E1[2] = ( E1[1] + E1[2] - E1[3] + E1[4]) * T; + E1[3] = ( E1[1] - E1[2] + E1[3] + E1[4]) * T; + E1[4] = (-E1[1] + E1[2] + E1[3] + E1[4]) * T; + } + +#ifdef PRINTOUT + IF (JJ==II)POUT(N2,N3,N2,E1[1],E1[2],E1[3],E1[4]); +#endif + +/* +C +C Module 3: Array as parameter +C +*/ + for (I = 1; I <= N3; I++) + PA(E1); + +#ifdef PRINTOUT + IF (JJ==II)POUT(N3,N2,N2,E1[1],E1[2],E1[3],E1[4]); +#endif + +/* +C +C Module 4: Conditional jumps +C +*/ + J = 1; + for (I = 1; I <= N4; I++) { + if (J == 1) + J = 2; + else + J = 3; + + if (J > 2) + J = 0; + else + J = 1; + + if (J < 1) + J = 1; + else + J = 0; + } + +#ifdef PRINTOUT + IF (JJ==II)POUT(N4,J,J,X1,X2,X3,X4); +#endif + +/* +C +C Module 5: Omitted +C Module 6: Integer arithmetic +C +*/ + + J = 1; + K = 2; + L = 3; + + for (I = 1; I <= N6; I++) { + J = J * (K-J) * (L-K); + K = L * K - (L-J) * K; + L = (L-K) * (K+J); + E1[L-1] = J + K + L; + E1[K-1] = J * K * L; + } + +#ifdef PRINTOUT + IF (JJ==II)POUT(N6,J,K,E1[1],E1[2],E1[3],E1[4]); +#endif + +/* +C +C Module 7: Trigonometric functions +C +*/ + X = 0.5; + Y = 0.5; + + for (I = 1; I <= N7; I++) { + X = T * DATAN(T2*DSIN(X)*DCOS(X)/(DCOS(X+Y)+DCOS(X-Y)-1.0)); + Y = T * DATAN(T2*DSIN(Y)*DCOS(Y)/(DCOS(X+Y)+DCOS(X-Y)-1.0)); + } + +#ifdef PRINTOUT + IF (JJ==II)POUT(N7,J,K,X,X,Y,Y); +#endif + +/* +C +C Module 8: Procedure calls +C +*/ + X = 1.0; + Y = 1.0; + Z = 1.0; + + for (I = 1; I <= N8; I++) + P3(X,Y,&Z); + +#ifdef PRINTOUT + IF (JJ==II)POUT(N8,J,K,X,Y,Z,Z); +#endif + +/* +C +C Module 9: Array references +C +*/ + J = 1; + K = 2; + L = 3; + E1[1] = 1.0; + E1[2] = 2.0; + E1[3] = 3.0; + + for (I = 1; I <= N9; I++) + P0(); + +#ifdef PRINTOUT + IF (JJ==II)POUT(N9,J,K,E1[1],E1[2],E1[3],E1[4]); +#endif + +/* +C +C Module 10: Integer arithmetic +C +*/ + J = 2; + K = 3; + + for (I = 1; I <= N10; I++) { + J = J + K; + K = J + K; + J = K - J; + K = K - J - J; + } + +#ifdef PRINTOUT + IF (JJ==II)POUT(N10,J,K,X1,X2,X3,X4); +#endif + +/* +C +C Module 11: Standard functions +C +*/ + X = 0.75; + + for (I = 1; I <= N11; I++) + X = DSQRT(DEXP(DLOG(X)/T1)); + +#ifdef PRINTOUT + IF (JJ==II)POUT(N11,J,K,X,X,X,X); +#endif + +/* +C +C THIS IS THE END OF THE MAJOR LOOP. +C +*/ + if (++JJ <= II) + goto IILOOP; + +/* +C +C Stop benchmark timing at this point. +C +*/ + + + End_Time = micros(); + +/* +C---------------------------------------------------------------- +C Performance in Whetstone KIP's per second is given by +C +C (100*LOOP*II)/TIME +C +C where TIME is in seconds. +C-------------------------------------------------------------------- +*/ + int usertime = End_Time - Begin_Time; + + blinks(); + Serial.println(); + +#define ONE_SECOND 1000000 + + if (usertime < ONE_SECOND) { + Serial.print("Insufficient duration- Increase the LOOP count\n"); + return(1); + } + + //Serial.printf("Loops: %ld, Iterations: %d, Duration: %ld sec.\n", + // LOOP, II, finisec-Begin_Time); + Serial.print("Loops:"); + Serial.print(LOOP); + Serial.print(", Iterations:"); + Serial.print(II); + Serial.print(", Duration:"); + float duration = 1000.0 * (float) (End_Time-Begin_Time)/(float) ONE_SECOND; + Serial.print(duration); + Serial.println(" millisec"); + + KIPS = (100.0*LOOP*II)/duration; + if (KIPS >= 1000.0) { +#ifdef SINGLE_PRECISION + Serial.print("C Converted Single Precision Whetstones:"); +#else + Serial.print("C Converted Double Precision Whetstones:"); +#endif + Serial.print(KIPS/1000.0); + Serial.print(" gflops\n"); + + } else { +#ifdef SINGLE_PRECISION + Serial.print("C Converted Single Precision Whetstones:"); +#else + Serial.print("C Converted Double Precision Whetstones:"); +#endif + Serial.print(KIPS); + Serial.println(" Mflops"); + + } + + if (continuous) + goto LCONT; + + return(0); +} + +#ifdef SINGLE_PRECISION +void PA(float E[]) +#else +void PA(double E[]) +#endif +{ + J = 0; + +L10: + E[1] = ( E[1] + E[2] + E[3] - E[4]) * T; + E[2] = ( E[1] + E[2] - E[3] + E[4]) * T; + E[3] = ( E[1] - E[2] + E[3] + E[4]) * T; + E[4] = (-E[1] + E[2] + E[3] + E[4]) / T2; + J += 1; + + if (J < 6) + goto L10; +} + +void +P0(void) +{ + E1[J] = E1[K]; + E1[K] = E1[L]; + E1[L] = E1[J]; +} + +#ifdef SINGLE_PRECISION +void P3(float X, float Y, float *Z) +#else +void P3(double X, double Y, double *Z) +#endif +{ +#ifdef SINGLE_PRECISION + float X1, Y1; +#else + double X1, Y1; +#endif + + X1 = X; + Y1 = Y; + X1 = T * (X1 + Y1); + Y1 = T * (X1 + Y1); + *Z = (X1 + Y1) / T2; +} + +#ifdef PRINTOUT +#ifdef SINGLE_PRECISION +void POUT(long N, long J, long K, float X1, float X2, float X3, float X4) +#else +void POUT(long N, long J, long K, double X1, double X2, double X3, double X4) +#endif +{ + // Serial.printf("%7ld %7ld %7ld %12.4e %12.4e %12.4e %12.4e\n", + // N, J, K, X1, X2, X3, X4); + Serial.print(N); + Serial.print(" "); + Serial.print(J); + Serial.print(" "); + Serial.print(K); + Serial.print(" "); + Serial.print(X1); + Serial.print(" "); + Serial.print(X2); + Serial.print(" "); + Serial.print(X3); + Serial.print(" "); + Serial.print(X4); + Serial.println(); + + +} +#endif + diff --git a/STM32F4/examples/whetstone/whetstone.h b/STM32F4/examples/whetstone/whetstone.h new file mode 100644 index 000000000..419eaab8c --- /dev/null +++ b/STM32F4/examples/whetstone/whetstone.h @@ -0,0 +1,4 @@ +int whetstone(int); + +void blinks(void); + diff --git a/STM32F4/libraries/RTClock/examples/BkpTest/BkpTest.ino b/STM32F4/libraries/RTClock/examples/BkpTest/BkpTest.ino new file mode 100644 index 000000000..1727330ad --- /dev/null +++ b/STM32F4/libraries/RTClock/examples/BkpTest/BkpTest.ino @@ -0,0 +1,150 @@ +#include + +#include +#include +#include +#include +#include + +RTClock rt; // initialise + +void setbkpvalues(); +void readbkpvalues(); +void sleep(uint16_t dur); + +int ledPin = BOARD_LED_PIN; + +// the setup() method runs once when the sketch starts +void setup() { + + pinMode(ledPin, OUTPUT); + digitalWrite(ledPin, LOW); //turn on the led + + Serial.begin(); + //wait for keypress + while(!Serial.available()) sleep(1); + while(Serial.available()) Serial.read(); + + Serial.println("init"); + + // enable backup domain clock + bkp_init(); + /* enable backup sram + * bkp_init() needs to be called prior + * passing true enable the backup power regulator, runs on VBAT e.g. coin cell + * passing false BKPSRAM is lost if VDD is lost, but preserves across a reset + * if only backup sram is used rt.begin() can be skipped, but bkp_init() need to be called prior + */ + bkp_initsram(false); + // setup RTClock, + // note that an initialized RTClock is necessary to access backup registers. + // if only backup registers are accessed, bkp_initsram() can be skipped + rt.begin(); + + Serial.println("bkp values:"); + readbkpvalues(); + Serial.flush(); + sleep(500); + + Serial.println("setting bkp values:"); + Serial.flush(); + setbkpvalues(); + sleep(500); + + Serial.println("bkp values:"); + readbkpvalues(); + Serial.flush(); + + digitalWrite(ledPin, !digitalRead(ledPin)); +} + +//the loop() method runs over and over again, +//as long as maple has power +void loop() { + sleep(1000); +} + +void setbkpvalues() { + const char *text = (const char*)F("a quick brown fox jumps over the lazy dog"); + + // before writing to bkp registers it is necessary to enable writes + // or it will hardfault / freeze + bkp_enable_writes(); + // set values in backup registers + // write values 1000001 .. 1000020 in backup registers + for (uint8_t r=1; r<=20; r++) { + bkp_write(r, 100000 + r); + } + bkp_disable_writes(); + + // check if BKPSRAM is enabled, if not skip writing them + if(!(RCC->AHB1ENR & RCC_AHB1ENR_BKPSRAMEN)) + return; + + //before writing to bkpsram it is necessary to enable writes + // or it will hardfault / freeze + bkp_enable_writes(); + //clear bkp sram + bkpsram_clear(); + + // write 100 in 2nd byte in BKP_SRAM + bkp_sramwrite8(1, 100); + + // write 10000 in 2nd uint16_t word in BKP_SRAM + bkp_sramwrite16(1, 10000); + + // write 1000000 in 2nd uint32_t word in BKP_SRAM + bkp_sramwrite32(1, 1000000); + + //write text in BKPSRAM at offset 10 + bkp_sramwrite(10, (uint8_t *)text, 41); + bkp_disable_writes(); + +} + +void readbkpvalues() { + char buf[50]; + + // read backup registers + for (uint8_t r=1; r<=20; r++) { + uint32_t v = bkp_read(r); + Serial.print("reg :"); + Serial.print(r); + Serial.print(':'); + Serial.println(v); + } + + // check if BKPSRAM is enabled, if not skip reading them + if(!(RCC->AHB1ENR & RCC_AHB1ENR_BKPSRAMEN)) + return; + + uint32_t val = 0; + // read 100 in 2nd byte in BKP_SRAM + val = bkp_sramread8(1); + Serial.print("BKPSRAM 2nd byte:"); + Serial.println(val); + + // read 10000 in 2nd uint16_t word in BKP_SRAM + val = 0; + val = bkp_sramread16(1); + Serial.print("BKPSRAM 2nd uint16 word:"); + Serial.println(val); + + // read 1000000 in 2nd uint32_t word in BKP_SRAM + val = 0; + val = bkp_sramread32(1); + Serial.print("BKPSRAM 2nd uint32 word:"); + Serial.println(val); + + memset(buf, 0, 50); + memcpy(buf, bkp_sramread(10), 41); + Serial.print("BKPSRAM text at offset 10:"); + Serial.println(buf); + +} + +void sleep(uint16_t dur) { + //sleep 1ms - wait for systick interrupt + for(uint16_t i=0; i -static rtc_dev rtc = { - .regs = RTC_BASE, -// .handlers = { [NR_RTC_HANDLERS - 1] = 0 }, -}; -rtc_dev *RTC = &rtc; -voidFuncPtr handlerAlarmA = NULL; -voidFuncPtr handlerAlarmB = NULL; -voidFuncPtr handlerPeriodicWakeup = NULL; +#ifdef RTC_DEBUG + #include + #include + char dbg_s[200]; + #define PRINTF(...) { sprintf(dbg_s, __VA_ARGS__); Serial.print(dbg_s); } +#else + #define PRINTF(...) +#endif + #define PRINTF1(...) { sprintf(dbg_s, __VA_ARGS__); Serial.print(dbg_s); } -//----------------------------------------------------------------------------- -RTClock::RTClock(rtc_clk_src src, uint16 sync_prescaler, uint16 async_prescaler) { - uint32 t = 0; - RCC_BASE->APB1ENR |= RCC_APB1RSTR_PWRRST; - rtc_debug_printf("RCC_BASE->APB1ENR = %08X\r\n", RCC_BASE->APB1ENR); - rtc_debug_printf("before bkp_init\r\n"); - bkp_init(); // turn on peripheral clocks to PWR and BKP and reset the backup domain via RCC registers. - // (we reset the backup domain here because we must in order to change the rtc clock source). - rtc_debug_printf("before bkp_disable_writes\r\n"); - bkp_disable_writes(); - rtc_debug_printf("before bkp_enable_writes\r\n"); - bkp_enable_writes(); // enable writes to the backup registers and the RTC registers via the DBP bit in the PWR control register - rtc_debug_printf("RCC_BASE->CFGR = %08X\r\n", RCC_BASE->CFGR); - RCC_BASE->CFGR |= (0x08 << 16); // Set the RTCPRE to HSE / 8. - rtc_debug_printf("RCC_BASE->CFGR = %08X\r\n", RCC_BASE->CFGR); - - switch (src) { - case RTCSEL_LSE : - rtc_debug_printf("Preparing RTC for LSE mode\r\n"); - if ((RCC_BASE->BDCR & 0x00000300) != 0x0100) - RCC_BASE->BDCR = 0x00010000; // Reset the entire Backup domain - RCC_BASE->BDCR = 0x00008101; - rtc_debug_printf("RCC_BASE->BDCR = %08X\r\n", RCC_BASE->BDCR); - while (!(RCC_BASE->BDCR & 0x00000002)) { - if (++t > 1000000) { - rtc_debug_printf("RCC_BASE->BDCR.LSERDY Timeout !\r\n"); - rtc_debug_printf("RCC_BASE->BDCR = %08X\r\n", RCC_BASE->BDCR); - return; - } - } - rtc_debug_printf("RCC_BASE->BDCR = %08X\r\n", RCC_BASE->BDCR); - rtc_enter_config_mode(); - if (sync_prescaler == 0 && async_prescaler == 0) - RTC_BASE->PRER = 255 | (127 << 16); - else - RTC_BASE->PRER = sync_prescaler | (async_prescaler << 16); - break; - case RTCSEL_LSI : - rtc_debug_printf("Preparing RTC for LSI mode\r\n"); - if ((RCC_BASE->BDCR & 0x00000300) != 0x0200) - RCC_BASE->BDCR = 0x00010000; // Reset the entire Backup domain - RCC_BASE->BDCR = 0x00008204; - RCC_BASE->CSR |= 0x00000001; - rtc_debug_printf("RCC_BASE->BDCR = %08X\r\n", RCC_BASE->BDCR); - while (!(RCC_BASE->CSR & 0x00000002)) { - if (++t > 1000000) { - rtc_debug_printf("RCC_BASE->CSR.LSIRDY Timeout !\r\n"); - rtc_debug_printf("RCC_BASE->CSR = %08X\r\n", RCC_BASE->CSR); - return; - } - } - rtc_debug_printf("RCC_BASE->BDCR = %08X\r\n", RCC_BASE->BDCR); - rtc_enter_config_mode(); - if (sync_prescaler == 0 && async_prescaler == 0) - RTC_BASE->PRER = 249 | (127 << 16); - else - RTC_BASE->PRER = sync_prescaler | (async_prescaler << 16); - break; - case RTCSEL_DEFAULT: - case RTCSEL_HSE : - rtc_debug_printf("Preparing RTC for HSE mode\r\n"); - if ((RCC_BASE->BDCR & 0x00000300) != 0x0300) - RCC_BASE->BDCR = 0x00010000; // Reset the entire Backup domain - RCC_BASE->BDCR = 0x00008304; - rtc_debug_printf("RCC_BASE->BDCR = %08X\r\n", RCC_BASE->BDCR); - rtc_enter_config_mode(); - if (sync_prescaler == 0 && async_prescaler == 0) - RTC_BASE->PRER = 7999 | (124 << 16); - else - RTC_BASE->PRER = sync_prescaler | (async_prescaler << 16); - break; - case RTCSEL_NONE: - rtc_debug_printf("Preparing RTC for NONE mode\r\n"); - if ((RCC_BASE->BDCR & 0x00000300) != 0x0000) - RCC_BASE->BDCR = 0x00010000; // Reset the entire Backup domain - RCC_BASE->BDCR = RCC_BDCR_RTCSEL_NONE; - //do nothing. Have a look at the clocks to see the diff between NONE and DEFAULT - break; - } - RCC_BASE->CR |= 0x00000040; // Turn to 24hrs mode -// rtc_debug_printf("before rtc_clear_sync\r\n"); -// rtc_clear_sync(); -// rtc_debug_printf("before rtc_wait_sync\r\n"); -// rtc_wait_sync(); - rtc_exit_config_mode(); - rtc_debug_printf("end of rtc_init\r\n"); -} -/* -RTClock::~RTClock() { - //to implement -} -*/ - -//----------------------------------------------------------------------------- -void RTClock::setTime (time_t time_stamp) -{ - breakTime(time_stamp, tm); // time will be broken to tm - setTime(tm); -} +typedef struct { +uint16_t s_presc; +uint16_t as_presc; +} prescaler_t; + +const prescaler_t prescalers[4] = { + { 0, 0}, // RTCSEL_NONE + { 255, 127}, // RTCSEL_LSE + { 249, 127}, // RTCSEL_LSI + {7999, 124}, // RTCSEL_HSE +}; //----------------------------------------------------------------------------- -void RTClock::setTime (tm_t & tm) +void RTClock::begin(rtc_clk_src src, uint16 sync_presc, uint16 async_presc) { - if (tm.year > 99) - tm.year = tm.year % 100; - rtc_enter_config_mode(); - RTC_BASE->TR = BUILD_TIME_REGISTER(tm.hour, tm.minute, tm.second); - RTC_BASE->DR = BUILD_DATE_REGISTER(tm.year, tm.month, tm.day, tm.weekday); - rtc_exit_config_mode(); -} + clk_src = src; + sync_prescaler = sync_presc; + async_prescaler = async_presc; + bool lse_ison = false; -/*============================================================================*/ -/* functions to convert to and from system time */ -/* These are for interfacing with time serivces and are not normally needed in a sketch */ + PRINTF("> RTClock::begin\n"); + PRINTF("PWR->CR(1) = %08X\n", PWR->CR); + bkp_init(); // turn on peripheral clocks to PWR and BKP and reset the backup domain via RCC registers. -// leap year calulator expects year argument as years offset from 1970 -#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) ) + //if RTC is running on LSE we'd skip initialization of RTC so that the time maintained on VBAT would not be reset + lse_ison = (RCC->BDCR & RCC_BDCR_LSEON == RCC_BDCR_LSEON) && (RCC->BDCR & RCC_BDCR_RTCEN == RCC_BDCR_RTCEN) -//static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0 + PRINTF("bkp_enable_writes\n"); + bkp_enable_writes(); // enable writes to the backup registers and the RTC registers via the DBP bit in the PWR control register + PRINTF("PWR->CR(2) = %08X\n", PWR->CR); -//----------------------------------------------------------------------------- -void RTClock::breakTime(time_t timeInput, tm_t & tm) -{ -// break the given time_t into time components -// this is a more compact version of the C library localtime function -// note that year is offset from 1970 !!! - - uint8_t year; - uint8_t month, monthLength; - uint32_t time; - uint32_t days; - - time = (uint32_t)timeInput; - tm.second = time % 60; - time /= 60; // now it is minutes - tm.minute = time % 60; - time /= 60; // now it is hours - tm.hour = time % 24; - time /= 24; // now it is days - tm.weekday = ((time + 4) % 7); // Monday is day 1 // + 1; // Sunday is day 1 - - year = 0; - days = 0; - while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { - year++; - } - tm.year = year; // year is offset from 1970 - - days -= LEAP_YEAR(year) ? 366 : 365; - time -= days; // now it is days in this year, starting at 0 - - days = 0; - month = 0; - monthLength = 0; - for (month=0; month<12; month++) { - if (month==1) { // february - if (LEAP_YEAR(year)) { - monthLength=29; - } else { - monthLength=28; - } - } else { - monthLength = monthDays[month]; - } + rcc_set_prescaler(RCC_PRESCALER_RTC, RCC_RTCCLK_DIV(CRYSTAL_FREQ)); // Set the RTCPRE to 8. + PRINTF("RCC->CFGR = %08X\n", RCC->CFGR); - if (time >= monthLength) { - time -= monthLength; - } else { + PRINTF("RTC clock source: %s\n", (clk_src==RTCSEL_LSE)?"LSE":((clk_src==RTCSEL_LSI)?"LSI":((clk_src==RTCSEL_HSE)?"HSE":"NONE"))); + switch (clk_src) + { + case RTCSEL_LSE: { + PRINTF("Preparing RTC for LSE mode, RCC->BDCR = %08X\n", RCC->BDCR); + if ((RCC->BDCR & RCC_BDCR_RTCSEL_MASK) == RCC_BDCR_RTCSEL_LSE) break; - } - } - tm.month = month + 1; // jan is month 1 - tm.day = time + 1; // day of month -} -//----------------------------------------------------------------------------- -time_t RTClock::makeTime(tm_t & tm) -{ -// assemble time elements into time_t -// note year argument is offset from 1970 (see macros in time.h to convert to other formats) -// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 - - int i; - uint32_t seconds; - - // seconds from 1970 till 1 jan 00:00:00 of the given year - seconds = tm.year*(SECS_PER_DAY * 365); - for (i = 0; i < tm.year; i++) { - if (LEAP_YEAR(i)) { - seconds += SECS_PER_DAY; // add extra days for leap years - } - } + RCC->BDCR = RCC_BDCR_BDRST; // Reset the entire Backup domain + PRINTF("BCKP domain reset\n"); - // add days for this year, months start from 1 - for (i = 1; i < tm.month; i++) { - if ( (i == 2) && LEAP_YEAR(tm.year)) { - seconds += SECS_PER_DAY * 29; - } else { - seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0 + RCC->BDCR = (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_LSE | RCC_BDCR_LSEON); + PRINTF("RCC->BDCR = %08X\n", RCC->BDCR); + uint32 t = 0; + while (!(RCC->BDCR & RCC_BDCR_LSERDY)) { + if (++t > 10000000) { + PRINTF("RCC LSERDY Timeout ! BDCR = %08X\n", RCC->BDCR); + break; + } } - } - seconds+= (tm.day-1) * SECS_PER_DAY; - seconds+= tm.hour * SECS_PER_HOUR; - seconds+= tm.minute * SECS_PER_MIN; - seconds+= tm.second; - return (time_t)seconds; -} -//----------------------------------------------------------------------------- -void RTClock::getTime(tm_t & tm) -{ - uint32_t dr_reg, tr_reg; - do { // read multiple time till both readings are equal - dr_reg = getDReg(); - tr_reg = getTReg(); - } while ( (dr_reg!=getDReg()) || (tr_reg!=getTReg()) ); - tm.year = _year(dr_reg); - tm.month = _month(dr_reg); - tm.day = _day(dr_reg); - tm.weekday = _weekday(dr_reg); - tm.pm = _pm(tr_reg); - tm.hour = _hour(tr_reg); - tm.minute = _minute(tr_reg); - tm.second = _second(tr_reg); -} + break; + } + case RTCSEL_LSI: + { + PRINTF("Preparing RTC for LSI mode\n"); + if ((RCC->BDCR & RCC_BDCR_RTCSEL_MASK) == RCC_BDCR_RTCSEL_LSI) + break; + RCC->BDCR = RCC_BDCR_BDRST; // Reset the entire Backup domain + PRINTF("BCKP domain reset\n"); + RCC->BDCR = (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_LSI | RCC_BDCR_LSEBYP); + PRINTF("RCC->BDCR = %08X\r\n", RCC->BDCR); + + RCC->CSR = RCC_CSR_LSION; + uint32 t = 0; + while (!(RCC->CSR & RCC_CSR_LSIRDY)) { + if (++t > 10000000) { + PRINTF("RCC LSIRDY Timeout ! CSR = %08X\n", RCC->CSR); + goto end0; + } + } + PRINTF("RCC->CSR = %08X\n", RCC->CSR); + } break; + + case RTCSEL_HSE : + PRINTF("Preparing RTC for HSE mode, RCC->BDCR = %08X\n", RCC->BDCR); + if ((RCC->BDCR & RCC_BDCR_RTCSEL_MASK) == RCC_BDCR_RTCSEL_HSE) + break; + RCC->BDCR = RCC_BDCR_BDRST; // Reset the entire Backup domain + PRINTF("BCKP domain reset\n"); + RCC->BDCR = (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_HSE | RCC_BDCR_LSEBYP); + PRINTF("RCC->BDCR = %08X\n", RCC->BDCR); + break; -//----------------------------------------------------------------------------- -time_t RTClock::getTime() -{ - getTime(tm); - return makeTime(tm); + case RTCSEL_NONE: + PRINTF("Preparing RTC for NONE mode\n"); + if ((RCC->BDCR & RCC_BDCR_RTCSEL_MASK) != RCC_BDCR_RTCSEL_NONE) + RCC->BDCR = RCC_BDCR_BDRST; // Reset the entire Backup domain + //do nothing. Have a look at the clocks to see the diff between NONE and DEFAULT + goto end0; + break; + } + if ( (sync_prescaler + async_prescaler) == 0) { + sync_prescaler = prescalers[clk_src].s_presc; + async_prescaler = prescalers[clk_src].as_presc; + } + PRINTF("sync_prescaler = %d, async_prescaler = %d\n", sync_prescaler, async_prescaler); + if(!lse_ison) { + rtc_enter_config_mode(); + RTC->PRER = (uint32)(async_prescaler << 16) + sync_prescaler; + RTC->DR = 0x00002101; // reset value + RTC->TR = 0x00000000; // reset value + //RCC->CR |= RTC_CR_BYPSHAD; + *bb_perip(&RTC->CR, RTC_CR_BYPSHAD_BIT) = 1; // bypass shadow regs + PRINTF("RTC PRER: %08X, CR: %08X\n", RTC->PRER, RTC->CR); + rtc_exit_config_mode(); + }; + +end0: + PRINTF("< RTClock::begin\n"); } //----------------------------------------------------------------------------- -void RTClock::setAlarmATime (tm_t * tm_ptr, bool hours_match, bool mins_match, bool secs_match, bool date_match) +void RTClock::setAlarmATime (bool hours_match, bool mins_match, bool secs_match, bool date_match) { - uint32 t = 0; rtc_enter_config_mode(); - unsigned int bits = ((tm_ptr->day / 10) << 28) | ((tm_ptr->day % 10) << 24) | - ((tm_ptr->hour / 10) << 20) | ((tm_ptr->hour % 10) << 16) | - ((tm_ptr->minute / 10) << 12) | ((tm_ptr->minute % 10) << 8) | - ((tm_ptr->second / 10) << 4) | (tm_ptr->second % 10); + unsigned int bits = (bin2bcd(_tm.day)<<24) + (bin2bcd(_tm.hour)<<16) + + (bin2bcd(_tm.minute)<<8) + bin2bcd(_tm.second); if (!date_match) bits |= (1 << 31); if (!hours_match) bits |= (1 << 23); if (!mins_match) bits |= (1 << 15); if (!secs_match) bits |= (1 << 7); - RTC_BASE->CR &= ~(1 << RTC_CR_ALRAE_BIT); - while (!(RTC_BASE->ISR & (1 << RTC_ISR_ALRAWF_BIT))) { + RTC->CR &= ~(RTC_CR_ALRAE); + uint32 t = 0; + while (!(RTC->ISR & RTC_ISR_ALRAWF)) { if (++t > 1000000) { - rtc_debug_printf("RTC_BASE->ISR.ALRAWF Timeout !\r\n"); - rtc_debug_printf("RTC_BASE->ISR = %08X\r\n", RTC_BASE->ISR); + PRINTF("RTC ALRAWF Timeout ! ISR = %08X\n", RTC->ISR); return; } } - RTC_BASE->ALRMAR = bits; - RTC_BASE->CR |= (1 << RTC_CR_ALRAE_BIT); - RTC_BASE->CR |= (1 << RTC_CR_ALRAIE_BIT); // turn on ALRAIE + RTC->ALRMAR = bits; + RTC->CR |= (RTC_CR_ALRAE |RTC_CR_ALRAIE); // turn on ALRAIE rtc_exit_config_mode(); nvic_irq_enable(NVIC_RTCALARM); nvic_irq_enable(NVIC_RTC); @@ -309,42 +189,38 @@ void RTClock::setAlarmATime (tm_t * tm_ptr, bool hours_match, bool mins_match, b //----------------------------------------------------------------------------- void RTClock::setAlarmATime (time_t alarm_time, bool hours_match, bool mins_match, bool secs_match, bool date_match) { - breakTime(alarm_time, tm); - setAlarmATime(&tm, hours_match, mins_match, secs_match, date_match); + breakTime(alarm_time, &_tm); + setAlarmATime(hours_match, mins_match, secs_match, date_match); } //----------------------------------------------------------------------------- void RTClock::turnOffAlarmA(void) { rtc_enter_config_mode(); - RTC_BASE->CR &= ~(1 << RTC_CR_ALRAIE_BIT); // turn off ALRAIE + RTC->CR &= ~(RTC_CR_ALRAIE); // turn off ALRAIE rtc_exit_config_mode(); } //----------------------------------------------------------------------------- -void RTClock::setAlarmBTime (tm_t * tm_ptr, bool hours_match, bool mins_match, bool secs_match, bool date_match) +void RTClock::setAlarmBTime (bool hours_match, bool mins_match, bool secs_match, bool date_match) { - uint32 t = 0; rtc_enter_config_mode(); - unsigned int bits = ((tm_ptr->day / 10) << 28) | ((tm_ptr->day % 10) << 24) | - ((tm_ptr->hour / 10) << 20) | ((tm_ptr->hour % 10) << 16) | - ((tm_ptr->minute / 10) << 12) | ((tm_ptr->minute % 10) << 8) | - ((tm_ptr->second / 10) << 4) | (tm_ptr->second % 10); + unsigned int bits = (bin2bcd(_tm.day) << 24) + (bin2bcd(_tm.hour) << 16) + + (bin2bcd(_tm.minute) << 8) + bin2bcd(_tm.second); if (!date_match) bits |= (1 << 31); if (!hours_match) bits |= (1 << 23); if (!mins_match) bits |= (1 << 15); if (!secs_match) bits |= (1 << 7); - RTC_BASE->CR &= ~(1 << RTC_CR_ALRBE_BIT); - while (!(RTC_BASE->ISR & (1 << RTC_ISR_ALRBWF_BIT))) { + RTC->CR &= ~(RTC_CR_ALRBE); + uint32 t = 0; + while (!(RTC->ISR & RTC_ISR_ALRBWF)) { if (++t > 1000000) { - rtc_debug_printf("RTC_BASE->ISR.ALRBWF Timeout !\r\n"); - rtc_debug_printf("RTC_BASE->ISR = %08X\r\n", RTC_BASE->ISR); + PRINTF("RTC ALRBWF Timeout ! ISR = %08X\n", RTC->ISR); return; } } - RTC_BASE->ALRMBR = bits; - RTC_BASE->CR |= (1 << RTC_CR_ALRBE_BIT); - RTC_BASE->CR |= (1 << RTC_CR_ALRBIE_BIT); // turn on ALRBIE + RTC->ALRMBR = bits; + RTC->CR |= (RTC_CR_ALRBE | RTC_CR_ALRBIE); // turn on ALRBIE rtc_exit_config_mode(); nvic_irq_enable(NVIC_RTCALARM); nvic_irq_enable(NVIC_RTC); @@ -354,48 +230,49 @@ void RTClock::setAlarmBTime (tm_t * tm_ptr, bool hours_match, bool mins_match, b //----------------------------------------------------------------------------- void RTClock::setAlarmBTime (time_t alarm_time, bool hours_match, bool mins_match, bool secs_match, bool date_match) { - breakTime(alarm_time, tm); - setAlarmBTime(&tm, hours_match, mins_match, secs_match, date_match); + breakTime(alarm_time, &_tm); + setAlarmBTime(hours_match, mins_match, secs_match, date_match); } //----------------------------------------------------------------------------- void RTClock::turnOffAlarmB() { rtc_enter_config_mode(); - RTC_BASE->CR &= ~(1 << RTC_CR_ALRBIE_BIT); // turn off ALRBIE + RTC->CR &= ~(RTC_CR_ALRBIE); // turn off ALRBIE rtc_exit_config_mode(); } //----------------------------------------------------------------------------- void RTClock::setPeriodicWakeup(uint16 period) { - uint32 t = 0; + PRINTF("< setPeriodicWakeup\n"); rtc_enter_config_mode(); - RTC_BASE->CR &= ~(1 << RTC_CR_WUTE_BIT); - while (!(RTC_BASE->ISR & (1 << RTC_ISR_WUTWF_BIT))) { + RTC->CR &= ~(RTC_CR_WUTE); + uint32 t = 0; + while (!(RTC->ISR & RTC_ISR_WUTWF)) { if (++t > 1000000) { - rtc_debug_printf("RTC_BASE->ISR.WUTWF Timeout !\r\n"); - rtc_debug_printf("RTC_BASE->ISR = %08X\r\n", RTC_BASE->ISR); + PRINTF("RTC WUTWF Timeout ! ISR = %08X\n", RTC->ISR); return; } } - rtc_debug_printf("before setting RTC_BASE->WUTR\r\n"); - RTC_BASE->WUTR = period; // set the period - rtc_debug_printf("RTC_BASE->WUTR = %08X\r\n", RTC_BASE->WUTR); - rtc_debug_printf("before setting RTC_BASE->CR.WUCKSEL\r\n"); - RTC_BASE->CR &= ~(3); RTC_BASE->CR |= 4; // Set the WUCKSEL to 1Hz (0x00000004) - RTC_BASE->ISR &= ~(1 << RTC_ISR_WUTF_BIT); - RTC_BASE->CR |= (1 << RTC_CR_WUTE_BIT); + PRINTF("before setting RTC->WUTR\r\n"); + RTC->WUTR = period; // set the period + PRINTF("RTC->WUTR = %08X\r\n", RTC->WUTR); + PRINTF("before setting RTC->CR.WUCKSEL\r\n"); + RTC->CR &= ~(RTC_CR_WUCKSEL_MASK); + RTC->CR |= 4; // Set the WUCKSEL to 1Hz (0x00000004) + *bb_perip(&RTC->ISR, RTC_ISR_WUTF_BIT) = 0; + RTC->CR |= RTC_CR_WUTE; if (period == 0) - RTC_BASE->CR &= ~(1 << RTC_CR_WUTIE_BIT); // if period is 0, turn off periodic wakeup interrupt. + RTC->CR &= ~(RTC_CR_WUTIE); // if period is 0, turn off periodic wakeup interrupt. else { - rtc_debug_printf("before turn ON RTC_BASE->CR.WUTIE\r\n"); - RTC_BASE->CR |= (1 << RTC_CR_WUTIE_BIT); // turn on WUTIE + PRINTF("before turn ON RTC->CR.WUTIE\r\n"); + RTC->CR |= (RTC_CR_WUTIE); // turn on WUTIE } - rtc_debug_printf("RCC_BASE->CR = %08X\r\n", RCC_BASE->CR); + PRINTF("RCC->CR = %08X\r\n", RCC->CR); rtc_exit_config_mode(); rtc_enable_wakeup_event(); nvic_irq_enable(NVIC_RTC); - rtc_debug_printf("setPeriodicWakeup() done !\r\n"); + PRINTF("setPeriodicWakeup >\n"); } @@ -423,43 +300,3 @@ void RTClock::detachPeriodicWakeupInterrupt() { handlerPeriodicWakeup = NULL; } - - -extern "C" { - void __irq_rtc(void) { - rtc_debug_printf("__irq_rtc() called !\r\n"); - rtc_enter_config_mode(); - RTC_BASE->ISR &= ~(1 << RTC_ISR_WUTF_BIT); - rtc_exit_config_mode(); - *bb_perip(&EXTI_BASE->PR, EXTI_RTC_WAKEUP_BIT) = 1; - if (handlerPeriodicWakeup != NULL) { - handlerPeriodicWakeup(); - } - } - - void __irq_rtcalarm(void) { - bool isAlarmA = false; - bool isAlarmB = false; - rtc_debug_printf("__irq_rtcalarm() called !\r\n"); - rtc_enter_config_mode(); - if (RTC_BASE->ISR & (1 << RTC_ISR_ALRAF_BIT)) { - isAlarmA = true; - rtc_debug_printf("AlarmA !\r\n"); - RTC_BASE->ISR &= ~(1 << RTC_ISR_ALRAF_BIT); - } - if (RTC_BASE->ISR & (1 << RTC_ISR_ALRBF_BIT)) { - isAlarmB = true; - rtc_debug_printf("AlarmB !\r\n"); - RTC_BASE->ISR &= ~(1 << RTC_ISR_ALRBF_BIT); - } - rtc_exit_config_mode(); - *bb_perip(&EXTI_BASE->PR, EXTI_RTC_ALARM_BIT) = 1; - if (isAlarmA && handlerAlarmA != NULL) { - handlerAlarmA(); - } - if (isAlarmB && handlerAlarmB != NULL) { - handlerAlarmB(); - } - } -} - diff --git a/STM32F4/libraries/RTClock/src/RTClock.h b/STM32F4/libraries/RTClock/src/RTClock.h index c13bf5f52..80898f299 100644 --- a/STM32F4/libraries/RTClock/src/RTClock.h +++ b/STM32F4/libraries/RTClock/src/RTClock.h @@ -1,214 +1,61 @@ +// +// RTClock.h +// #ifndef _RTCLOCK_H_ #define _RTCLOCK_H_ -#ifdef __cplusplus -extern "C" { -#endif - - -#include // for __time_t_defined -#include +#include #include -#include -#include -#include -#include - -//#define RTC_DEBUG - - -#if !defined(__time_t_defined) // avoid conflict with newlib or other posix libc - #warning "Using private time_t definintion" - typedef uint32_t time_t; -#endif - -#ifdef RTC_DEBUG - extern void dbg_printf(const char *fmt, ... ); - #define rtc_debug_printf(fmt, ...) dbg_printf(fmt, ##__VA_ARGS__); -#else - #define rtc_debug_printf(...) -#endif - - -#define SECS_PER_MIN (60UL) -#define SECS_PER_HOUR (3600UL) -#define SECS_PER_DAY (SECS_PER_HOUR * 24UL) -#define DAYS_PER_WEEK (7UL) -#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK) -#define SECS_PER_YEAR (SECS_PER_WEEK * 52UL) -#define SECS_YR_2000 (946684800UL) // the time at the start of y2k -#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) ) - -static const unsigned char monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0 - - -typedef struct rtc_reg_map { - __io uint32 TR; /**< Time register */ - __io uint32 DR; /**< Date register */ - __io uint32 CR; /**< Control register */ - __io uint32 ISR; /**< Init Status register */ - __io uint32 PRER; /**< Prescaler register */ - __io uint32 WUTR; /**< Wakeup Timer register */ - __io uint32 CALIBR; /**< Calibration register */ - __io uint32 ALRMAR; /**< Alarm A register */ - __io uint32 ALRMBR; /**< Alarm B register */ - __io uint32 WPR; /**< Write Protect register */ - __io uint32 SSR; /**< SubSecond register */ - __io uint32 SHIFTR; /**< Shift Control register */ - __io uint32 TSTR; /**< TimeStamp Time register */ - __io uint32 TSDR; /**< TimeStamp Date register */ - __io uint32 TSSSR; /**< TimeStamp SubSecond register */ - __io uint32 CALR; /**< Calibration register */ - __io uint32 TAFCR; /**< Tamper and Alternate Function Config register */ - __io uint32 ALRMASSR; /**< Alarm A subSecond register */ - __io uint32 ALRMBSSR; /**< Alarm B subSecond register */ - __io uint32 BKPxR; /**< Backup registers */ -} rtc_reg_map; - -/** RTC register map base pointer */ -#define RTC_BASE ((struct rtc_reg_map*)0x40002800) - -/** rtc device type */ -typedef struct rtc_dev { - rtc_reg_map *regs; /**< Register map */ - voidFuncPtr handlers[]; /**< User IRQ handlers */ -} rtc_dev; - -extern rtc_dev *RTC; - -#define NR_RTC_HANDLERS 4 - -#define EXTI_RTC_ALARM_BIT 17 -#define EXTI_RTC_WAKEUP_BIT 22 -#define EXTI_RTC_TAMPSTAMP_BIT 21 - - -/** - * @brief RTC clock source. - * - */ -typedef enum rtc_clk_src { - RTCSEL_DEFAULT = 0, - RTCSEL_NONE = 0x10, - RTCSEL_LSE = 0x11, - RTCSEL_LSI = 0x12, - RTCSEL_HSE = 0x13, -} rtc_clk_src; - -// Time register -#define RTC_TR_PM_BIT 22 -#define RTC_TR_HOUR_BIT 16 -#define RTC_TR_MINUTE_BIT 8 -#define RTC_TR_SECOND_BIT 0 - -#define RTC_TR_PM_MASK (0x01)//<>4)) + (b&0x0F) ); } -static inline uint8_t bin2bcd(uint8_t b) { return ( ((b/10)<<4) + (b%10) ); } class RTClock { public: - RTClock() { RTClock(RTCSEL_LSE, 0, 0); } - RTClock(rtc_clk_src src ) { RTClock(src, 0, 0); } - RTClock(rtc_clk_src src, uint16 sync_prescaler, uint16 async_prescaler); + RTClock() {} + void begin(rtc_clk_src _src, uint16 _sync_prescaler, uint16 _async_prescaler); + void begin(rtc_clk_src _src) { begin(_src, 0, 0); } + void begin() { begin(RTCSEL_LSE, 0, 0); } //~RTClock(); //to implement - void breakTime(time_t epoch_time, tm_t & tm); - time_t makeTime(tm_t & tm); - - void setTime (time_t time_stamp); - void setTime (tm_t & tm); - - time_t getTime(); - void getTime(tm_t & tm); - #define now getTime - - uint8_t year(void) { getTime(tm); return tm.year; } - uint8_t month(void) { getTime(tm); return tm.month; } - uint8_t day(void) { getTime(tm); return tm.day; } - uint8_t weekday(void) { getTime(tm); return tm.weekday; } - uint8_t hour(void) { getTime(tm); return tm.hour; } - uint8_t minute(void) { getTime(tm); return tm.minute; } - uint8_t second(void) { getTime(tm); return tm.second; } - //uint8_t pm(void) { return _pm(RTC_BASE->TR); } + //void breakTime(time_t epoch_time, tm_t &_tm); + #define breakTime _breakTime + time_t makeTime(tm_t & tmm) { return _makeTime(&_tm); } + void setTime(time_t time_stamp) { breakTime(time_stamp, &_tm); _setTime(&_tm); } + void setTime(tm_t & tmm) { _setTime(&tmm); } + + time_t getTimeNow() { _getTime(&_tm); return makeTime(_tm); } + time_t getTime() { return getTimeNow(); } + time_t now() { return getTimeNow(); } + + void getTime(tm_t & tmm) { _getTime(&tmm); } + void now(tm_t & tmm ) { _getTime(&tmm); } // non-standard use of now() function, added for compatibility with previous versions of the library + + uint8_t year(void) { _getTime(&_tm); return _tm.year; } + uint8_t month(void) { _getTime(&_tm); return _tm.month; } + uint8_t day(void) { _getTime(&_tm); return _tm.day; } + uint8_t weekday(void) { _getTime(&_tm); return _tm.weekday; } + uint8_t hour(void) { _getTime(&_tm); return _tm.hour; } + uint8_t minute(void) { _getTime(&_tm); return _tm.minute; } + uint8_t second(void) { _getTime(&_tm); return _tm.second; } + //uint8_t pm(void) { return _pm(RTC->TR); } uint8_t isPM(void) { return ( hour()>=12 ); } - uint8_t year(time_t t) { breakTime(t, tm); return tm.year; } - uint8_t month(time_t t) { breakTime(t, tm); return tm.month; } - uint8_t day(time_t t) { breakTime(t, tm); return tm.day; } - uint8_t weekday(time_t t) { breakTime(t, tm); return tm.weekday; } - uint8_t hour(time_t t) { breakTime(t, tm); return tm.hour; } - uint8_t minute(time_t t) { breakTime(t, tm); return tm.minute; } - uint8_t second(time_t t) { breakTime(t, tm); return tm.second; } + uint8_t year(time_t t) { breakTime(t, &_tm); return _tm.year; } + uint8_t month(time_t t) { breakTime(t, &_tm); return _tm.month; } + uint8_t day(time_t t) { breakTime(t, &_tm); return _tm.day; } + uint8_t weekday(time_t t) { breakTime(t, &_tm); return _tm.weekday; } + uint8_t hour(time_t t) { breakTime(t, &_tm); return _tm.hour; } + uint8_t minute(time_t t) { breakTime(t, &_tm); return _tm.minute; } + uint8_t second(time_t t) { breakTime(t, &_tm); return _tm.second; } uint8_t isPM(time_t t) { return (hour(t)>=12); } - void setAlarmATime (tm_t * tm_ptr, bool hours_match = true, bool mins_match = true, bool secs_match = true, bool date_match = false); + void setAlarmATime (bool hours_match = true, bool mins_match = true, bool secs_match = true, bool date_match = false); void setAlarmATime (time_t alarm_time, bool hours_match = true, bool mins_match = true, bool secs_match = true, bool date_match = false); void turnOffAlarmA(); - void setAlarmBTime (tm_t * tm_ptr, bool hours_match = true, bool mins_match = true, bool secs_match = true, bool date_match = false); + void setAlarmBTime (bool hours_match = true, bool mins_match = true, bool secs_match = true, bool date_match = false); void setAlarmBTime (time_t alarm_time, bool hours_match = true, bool mins_match = true, bool secs_match = true, bool date_match = false); void turnOffAlarmB(); @@ -224,115 +71,10 @@ class RTClock { void attachAlarmBInterrupt(voidFuncPtr function); void detachAlarmBInterrupt(); - private: - inline uint8_t _year(uint32_t dr) { return bcd2bin( (dr>>RTC_DR_YEAR_BIT) & RTC_DR_YEAR_MASK ); } - inline uint8_t _month(uint32_t dr) { return bcd2bin( (dr>>RTC_DR_MONTH_BIT) & RTC_DR_MONTH_MASK ); } - inline uint8_t _day(uint32_t dr) { return bcd2bin( (dr>>RTC_DR_DAY_BIT) & RTC_DR_DAY_MASK ); } - inline uint8_t _weekday(uint32_t dr) { return bcd2bin( (dr>>RTC_DR_WEEKDAY_BIT) & RTC_DR_WEEKDAY_MASK ); } - inline uint8_t _pm(uint32_t tr) { return ( (tr>>RTC_TR_PM_BIT) & RTC_TR_PM_MASK ); } - inline uint8_t _hour(uint32_t tr) { return bcd2bin( (tr>>RTC_TR_HOUR_BIT) & RTC_TR_HOUR_MASK ); } - inline uint8_t _minute(uint32_t tr) { return bcd2bin( (tr>>RTC_TR_MINUTE_BIT) & RTC_TR_MINUTE_MASK ); } - inline uint8_t _second(uint32_t tr) { return bcd2bin( (tr>>RTC_TR_SECOND_BIT) & RTC_TR_SECOND_MASK ); } - - tm_t tm; + tm_t _tm; + uint16_t sync_prescaler, async_prescaler; + rtc_clk_src clk_src; }; -inline uint32_t getTReg(void) { return (uint32_t)(RTC_BASE->TR); } -inline uint32_t getDReg(void) { return (uint32_t)(RTC_BASE->DR); } - -/** - * @brief Clear the register synchronized flag. The flag is then set by hardware after a write to PRL/DIV or CNT. - */ -static inline void rtc_clear_sync() { - *bb_perip(&(RTC->regs)->ISR, RTC_ISR_RSF_BIT) = 0; -} - -/** - * @brief Check (wait if necessary) to see RTC registers are synchronized. - */ -static inline void rtc_wait_sync() { - uint32 t = 0; - rtc_debug_printf("entering rtc_wait_sync\r\n"); - while (*bb_perip(&(RTC->regs)->ISR, RTC_ISR_RSF_BIT) == 0) { - if (++t > 1000000) { - rtc_debug_printf("RTC_BASE->ISR.RSF Timeout !\r\n"); - rtc_debug_printf("RTC_BASE->ISR = %08X\r\n", RTC_BASE->ISR); - return; - } - } - rtc_debug_printf("finished rtc_wait_sync\r\n"); -} - -/** - * @brief Enter configuration mode. - */ -static inline void rtc_enter_config_mode() { - uint32 t = 0; - // Unlock Write Protect - RTC_BASE->WPR = 0xCA; - RTC_BASE->WPR = 0x53; - *bb_perip(&(RTC->regs)->ISR, RTC_ISR_INIT_BIT) = 1; - rtc_debug_printf("RTC_BASE->ISR = %08X\r\n", RTC_BASE->ISR); - while (!(RTC_BASE->ISR & 0x00000040)) { - if (++t > 1000000) { - rtc_debug_printf("RTC_BASE->ISR.INITF Timeout !\r\n"); - rtc_debug_printf("RTC_BASE->ISR = %08X\r\n", RTC_BASE->ISR); - return; - } - } - rtc_debug_printf("rtc_enter_config_mode done !\r\n"); -} - -/** - * @brief Exit configuration mode. - */ -static inline void rtc_exit_config_mode() { - *bb_perip(&(RTC->regs)->ISR, RTC_ISR_INIT_BIT) = 0; - rtc_debug_printf("rtc_exit_config_mode done !\r\n"); -} - - -/** - * @brief Enable an RTC alarm event. Enabling this event allows waking up from deep sleep via WFE. - * @see rtc_interrupt_id - */ -static inline void rtc_enable_alarm_event() { - *bb_perip(&EXTI_BASE->IMR, EXTI_RTC_ALARM_BIT) = 1; - *bb_perip(&EXTI_BASE->EMR, EXTI_RTC_ALARM_BIT) = 1; - *bb_perip(&EXTI_BASE->RTSR, EXTI_RTC_ALARM_BIT) = 1; -} - -/** - * @brief Disable the RTC alarm event. - * @see rtc_interrupt_id - */ -static inline void rtc_disable_alarm_event() { - *bb_perip(&EXTI_BASE->EMR, EXTI_RTC_ALARM_BIT) = 0; - *bb_perip(&EXTI_BASE->RTSR, EXTI_RTC_ALARM_BIT) = 0; -} - - -/** - * @brief Enable an RTC Wakeup event. - * @see rtc_interrupt_id - */ -static inline void rtc_enable_wakeup_event() { - *bb_perip(&EXTI_BASE->IMR, EXTI_RTC_WAKEUP_BIT) = 1; - *bb_perip(&EXTI_BASE->EMR, EXTI_RTC_WAKEUP_BIT) = 1; - *bb_perip(&EXTI_BASE->RTSR, EXTI_RTC_WAKEUP_BIT) = 1; -} - -/** - * @brief Disable the RTC alarm event. - * @see rtc_interrupt_id - */ -static inline void rtc_disable_wakeup_event() { - *bb_perip(&EXTI_BASE->EMR, EXTI_RTC_WAKEUP_BIT) = 0; - *bb_perip(&EXTI_BASE->RTSR, EXTI_RTC_WAKEUP_BIT) = 0; -} - -#ifdef __cplusplus -} -#endif #endif // _RTCLOCK_H_ diff --git a/STM32F4/libraries/SDIO/SdioF4.cpp b/STM32F4/libraries/SDIO/SdioF4.cpp index 63c928a80..12f778165 100644 --- a/STM32F4/libraries/SDIO/SdioF4.cpp +++ b/STM32F4/libraries/SDIO/SdioF4.cpp @@ -23,7 +23,7 @@ #include #include -#define USE_DEBUG_MODE 0 +#define USE_DEBUG_MODE 0 // set it 0 or 1 #define USE_YIELD 0 //============================================================================== @@ -118,8 +118,12 @@ static uint32_t t = 0; } #define DBG_PIN PD0 +static char dbg_str[1024]; +#define PRINTF(...) { sprintf(dbg_str, __VA_ARGS__); Serial.print(dbg_str); delay(1); } + #else // USE_DEBUG_MODE #define DBG_PRINT() +#define PRINTF(...) #endif // USE_DEBUG_MODE /*****************************************************************************/ @@ -282,7 +286,7 @@ static bool isBusyTransferComplete(void) return true; } /*---------------------------------------------------------------------------*/ -static void trxStart(uint8_t* buf, uint32_t n, uint8_t dir) +static void trxStart(uint32_t n, uint8_t dir) { m_dir = dir; uint32_t flags = (SDIO_BLOCKSIZE_512 | SDIO_DCTRL_DTEN); @@ -318,7 +322,6 @@ static bool dmaTrxStart(uint8_t* buf, uint32_t n, uint8_t dir) // setup SDIO to transfer n blocks of 512 bytes sdio_setup_transfer(0x00FFFFFF, n, flags); // setup DMA2 stream 3 channel 4 - dma_init(DMA2); flags = (DMA_PERIF_CTRL | DMA_BURST_INCR4 | DMA_MINC_MODE | DMA_PRIO_VERY_HIGH); if (dir==TRX_RD) flags |= DMA_FROM_PER; // read else flags |= DMA_FROM_MEM; // write @@ -481,6 +484,7 @@ delay(100); m_sdClkKhz = 24000; sdio_set_clock(m_sdClkKhz*1000); // set clock to 24MHz + dma_init(DMA2); m_initDone = true; return true; } @@ -540,9 +544,8 @@ uint32_t SdioCard::kHzSdClk() { /*---------------------------------------------------------------------------*/ bool SdioCard::readBlock(uint32_t lba, uint8_t* buf) { -#if USE_DEBUG_MODE - Serial.print("readBlock: "); Serial.println(lba); //Serial.print(", buf: "); Serial.println((uint32_t)buf, HEX); -#endif + PRINTF("_readBlock lba: %lu\n", lba); //Serial.print(", buf: "); Serial.print((uint32_t)buf, HEX); + // prepare SDIO and DMA for data read transfer dmaTrxStart((uint32_t)buf & 3 ? (uint8_t*)aligned : buf, 512, TRX_RD); // send command to start data transfer @@ -567,11 +570,8 @@ bool SdioCard::readBlock(uint32_t lba, uint8_t* buf) /*---------------------------------------------------------------------------*/ bool SdioCard::readBlocks(uint32_t lba, uint8_t* buf, size_t n) { -#if USE_DEBUG_MODE - Serial.print("readBlocks: "); Serial.print(lba); - //Serial.print(", buf: "); Serial.print((uint32_t)buf, HEX); - Serial.print(", "); Serial.println(n); -#endif + PRINTF("_readBlocks lba: %lu, n: %u\n", lba, n); //Serial.print(", buf: "); Serial.print((uint32_t)buf, HEX); + if ((uint32_t)buf & 3) { for (size_t i = 0; i < n; i++, lba++, buf += 512) { if (!readBlock(lba, buf)) { @@ -601,13 +601,13 @@ bool SdioCard::readCSD(void* csd) { /*---------------------------------------------------------------------------*/ bool SdioCard::readData(uint8_t *dst) { - //Serial.print("readData: "); Serial.print(m_lba); Serial.print(", m_cnt: "); Serial.println(m_cnt); + PRINTF("_readData m_lba: %lu, m_cnt: %lu\n", m_lba, m_cnt); if ( m_cnt==0 ) return false; if (yieldTimeout(isBusyCMD13)) { // wait for previous transmission end return sdError(SD_CARD_ERROR_CMD13); } // non-DMA block read - trxStart(dst, 512, TRX_RD); + trxStart(512, TRX_RD); // send command to start data transfer if ( !cardCommand(CMD17_XFERTYP, (m_highCapacity ? m_lba : 512*m_lba)) ) { return sdError(SD_CARD_ERROR_CMD17); @@ -651,6 +651,7 @@ bool SdioCard::readOCR(uint32_t* ocr) { //----------------------------------------------------------------------------- bool SdioCard::readStart(uint32_t lba) { + PRINTF("_readStart lba: %lu\n", lba); m_lba = lba; m_cnt = 1024; return true; @@ -659,7 +660,7 @@ bool SdioCard::readStart(uint32_t lba) // SDHC will do Auto CMD12 after count blocks. bool SdioCard::readStart(uint32_t lba, uint32_t count) { - //Serial.print("readStart: "); Serial.print(lba); Serial.print(", cnt: "); Serial.println(count); + PRINTF("_readStart lba: %lu, cnt: %lu\n", lba, count); m_lba = lba; m_cnt = count; return true; @@ -667,30 +668,33 @@ bool SdioCard::readStart(uint32_t lba, uint32_t count) /*---------------------------------------------------------------------------*/ bool SdioCard::readStop() { - //Serial.println("readStop."); + PRINTF("_readStop\n"); m_lba = 0; m_cnt = 0; return true; } //----------------------------------------------------------------------------- -bool SdioCard::syncBlocks() { +bool SdioCard::syncBlocks() +{ + PRINTF("_syncBlocks\n"); return true; } //----------------------------------------------------------------------------- -uint8_t SdioCard::type() { +uint8_t SdioCard::type() +{ return m_version2 ? m_highCapacity ? SD_CARD_TYPE_SDHC : SD_CARD_TYPE_SD2 : SD_CARD_TYPE_SD1; } /*---------------------------------------------------------------------------*/ bool SdioCard::writeBlock(uint32_t lba, const uint8_t* buf) { -#if USE_DEBUG_MODE - Serial.print("writeBlock: "); Serial.println(lba); //Serial.print(", buf: "); Serial.println((uint32_t)buf, HEX); -#endif + PRINTF("_writeBlock lba: %lu\n", lba); // Serial.print((uint32_t)buf, HEX); + uint8_t * ptr = (uint8_t *)buf; - if (3 & (uint32_t)ptr) { - Serial.print("writeBlock: "); Serial.print(lba); - Serial.print(", buf: "); Serial.print((uint32_t)ptr, HEX); + if (3 & (uint32_t)ptr) + { + PRINTF("_odd buf: %lX\n", (uint32_t)buf); // Serial.print((uint32_t)buf, HEX); + //memcpy(aligned, buf, 512); register uint8_t * src = (uint8_t *)ptr; ptr = (uint8_t *)aligned; @@ -716,11 +720,8 @@ bool SdioCard::writeBlock(uint32_t lba, const uint8_t* buf) /*---------------------------------------------------------------------------*/ bool SdioCard::writeBlocks(uint32_t lba, const uint8_t* buf, size_t n) { -#if USE_DEBUG_MODE - Serial.print("writeBlocks: "); Serial.print(lba); - //Serial.print(", buf: "); Serial.print((uint32_t)buf, HEX); - Serial.print(", "); Serial.println(n); -#endif + PRINTF("_writeBlocks lba: %lu, size: %u\n", lba, n); // Serial.print((uint32_t)buf, HEX); + if (3 & (uint32_t)buf) { // misaligned buffer address, write single blocks for (size_t i = 0; i < n; i++, lba++, buf += 512) { if (!writeBlock(lba, buf)) { @@ -750,7 +751,7 @@ bool SdioCard::writeBlocks(uint32_t lba, const uint8_t* buf, size_t n) /*---------------------------------------------------------------------------*/ bool SdioCard::writeData(const uint8_t* src) { - //Serial.print("writeData: "); Serial.print(m_lba); Serial.print(", cnt: "); Serial.println(m_cnt); + PRINTF("_writeData m_lba: %lu, m_cnt: %lu\n", m_lba, m_cnt); if ( !m_cnt ) return false; if (yieldTimeout(isBusyCMD13)) { // wait for previous transmission end return sdError(SD_CARD_ERROR_CMD13); @@ -760,7 +761,7 @@ bool SdioCard::writeData(const uint8_t* src) return sdError(SD_CARD_ERROR_CMD24); } // non-DMA block write - trxStart((uint8_t*)src, 512, TRX_WR); + trxStart(512, TRX_WR); // Receive a data block from the SDIO register uint32_t STA; // to speed up SDIO flags checking register uint16_t cnt = 512; @@ -797,6 +798,7 @@ bool SdioCard::writeData(const uint8_t* src) //----------------------------------------------------------------------------- bool SdioCard::writeStart(uint32_t lba) { + PRINTF("_writeStart lba: %lu\n", lba); m_lba = lba; m_cnt = 1024; return true; @@ -805,7 +807,7 @@ bool SdioCard::writeStart(uint32_t lba) // SDHC will do Auto CMD12 after count blocks. bool SdioCard::writeStart(uint32_t lba, uint32_t count) { - //Serial.print("writeStart: "); Serial.print(lba); Serial.print(", cnt: "); Serial.println(count); + PRINTF("_writeStart lba: %lu, cnt: %lu\n", lba, count); m_lba = lba; m_cnt = count; return true; @@ -813,7 +815,7 @@ bool SdioCard::writeStart(uint32_t lba, uint32_t count) /*---------------------------------------------------------------------------*/ bool SdioCard::writeStop() { - //Serial.println("writeStop."); + PRINTF("writeStop\n"); m_lba = 0; m_cnt = 0; return true; diff --git a/STM32F4/libraries/SPI/src/SPI.cpp b/STM32F4/libraries/SPI/src/SPI.cpp index 72a4c4835..8214e4f80 100644 --- a/STM32F4/libraries/SPI/src/SPI.cpp +++ b/STM32F4/libraries/SPI/src/SPI.cpp @@ -31,7 +31,6 @@ #include "SPI.h" -//#define SPI_DEBUG #include #include @@ -40,151 +39,306 @@ #include "wirish.h" #include "boards.h" +/** Time in ms for DMA receive timeout */ #define DMA_TIMEOUT 100 -#if CYCLES_PER_MICROSECOND != 168 -/* TODO [0.2.0?] something smarter than this */ -#warning "Unexpected clock speed; SPI frequency calculation will be incorrect" -#endif - -struct spi_pins { - uint8 nss; - uint8 sck; - uint8 miso; - uint8 mosi; -}; +#define PRINTF(...) +//#define PRINTF(...) Serial.print(__VA_ARGS__) -static const spi_pins* dev_to_spi_pins(spi_dev *dev); +//#define SPI1_ALTERNATE_CONFIG 1 // use alternate SPI1 on SPI3 pins -static void configure_gpios(spi_dev *dev, bool as_master); - -static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq); - -#if (BOARD_NR_SPI >= 3) && !defined(STM32_HIGH_DENSITY) -#error "The SPI library is misconfigured: 3 SPI ports only available on high density STM32 devices" -#endif -static const spi_pins board_spi_pins[] __FLASH__ = { -#if BOARD_NR_SPI >= 1 +static const spi_pins_t board_spi_pins[BOARD_NR_SPI] __FLASH__ = +{ {BOARD_SPI1_NSS_PIN, BOARD_SPI1_SCK_PIN, BOARD_SPI1_MISO_PIN, BOARD_SPI1_MOSI_PIN}, -#endif -#if BOARD_NR_SPI >= 2 {BOARD_SPI2_NSS_PIN, BOARD_SPI2_SCK_PIN, BOARD_SPI2_MISO_PIN, BOARD_SPI2_MOSI_PIN}, -#endif -#if BOARD_NR_SPI >= 3 {BOARD_SPI3_NSS_PIN, BOARD_SPI3_SCK_PIN, BOARD_SPI3_MISO_PIN, BOARD_SPI3_MOSI_PIN}, +#if (BOARD_NR_SPI>3) + {BOARD_SPI4_NSS_PIN, + BOARD_SPI4_SCK_PIN, + BOARD_SPI4_MISO_PIN, + BOARD_SPI4_MOSI_PIN}, +#endif +#if (BOARD_NR_SPI>4) + {BOARD_SPI5_NSS_PIN, + BOARD_SPI5_SCK_PIN, + BOARD_SPI5_MISO_PIN, + BOARD_SPI5_MOSI_PIN}, #endif }; +#if defined(BOARD_SPI1A_NSS_PIN) && defined(BOARD_SPI2A_NSS_PIN) && defined(BOARD_SPI3A_NSS_PIN) +#define SPI_ALT_PINS 1 +static const spi_pins_t board_spi_alt_pins[BOARD_NR_SPI] __FLASH__ = +{ + {BOARD_SPI1A_NSS_PIN, + BOARD_SPI1A_SCK_PIN, + BOARD_SPI1A_MISO_PIN, + BOARD_SPI1A_MOSI_PIN}, + {BOARD_SPI2A_NSS_PIN, + BOARD_SPI2A_SCK_PIN, + BOARD_SPI2A_MISO_PIN, + BOARD_SPI2A_MOSI_PIN}, + {BOARD_SPI3A_NSS_PIN, + BOARD_SPI3A_SCK_PIN, + BOARD_SPI3A_MISO_PIN, + BOARD_SPI3A_MOSI_PIN}, +}; +#else +#define SPI_ALT_PINS 0 +#endif +//----------------------------------------------------------------------------- +static uint16_t ff = 0XFFFF; -/* - * Constructor - */ +SPISettings _settings[BOARD_NR_SPI]; -SPIClass::SPIClass(uint32 spi_num) { +//----------------------------------------------------------------------------- +// Auxiliary functions +//----------------------------------------------------------------------------- - _currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed +static void disable_pwm(uint8_t pin) +{ + const timer_info * i = &timer_map[pin]; + const timer_dev * t_dev = timer_devices[i->index]; + if (i->index && t_dev) { + timer_set_mode(t_dev, i->channel, TIMER_DISABLED); + } +} - - switch (spi_num) { -#if BOARD_NR_SPI >= 1 - case 1: - _currentSetting->spi_d = SPI1; - break; -#endif -#if BOARD_NR_SPI >= 2 - case 2: - _currentSetting->spi_d = SPI2; - break; -#endif -#if BOARD_NR_SPI >= 3 - case 3: - _currentSetting->spi_d = SPI3; - break; -#endif - default: - ASSERT(0); +static void configure_gpios(SPISettings * crtSetting, bool as_master) +{ + const spi_pins_t *pins = crtSetting->pins; + disable_pwm(pins->nss); + disable_pwm(pins->sck); + disable_pwm(pins->miso); + disable_pwm(pins->mosi); + + spi_config_gpios(crtSetting->spi_d, as_master, pins); +} + +static const spi_baud_rate baud_rates[8] __FLASH__ = +{ + SPI_BAUD_PCLK_DIV_2, + SPI_BAUD_PCLK_DIV_4, + SPI_BAUD_PCLK_DIV_8, + SPI_BAUD_PCLK_DIV_16, + SPI_BAUD_PCLK_DIV_32, + SPI_BAUD_PCLK_DIV_64, + SPI_BAUD_PCLK_DIV_128, + SPI_BAUD_PCLK_DIV_256, +}; + +//----------------------------------------------------------------------------- +// Note: This assumes you're on a LeafLabs-style board +// APB2 = CYCLES_PER_MICROSECOND/2 [MHz], APB1 = APB2/2. +//----------------------------------------------------------------------------- +static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) +{ + uint32_t clock = 0; + switch (rcc_dev_clk(dev->clk_id)) + { + case RCC_APB2: clock = STM32_PCLK2; break; // 84 Mhz // SPI1 + case RCC_APB1: clock = STM32_PCLK1; break; // 42 Mhz // SPI2/3 + case RCC_AHB1: break; + default: break; + } + clock /= 2; + uint8_t i = 0; + while (i < 7 && freq < clock) { + clock /= 2; + i++; } - + return baud_rates[i]; +} + +//----------------------------------------------------------------------------- +// This function will be called after the stream finished to transfer +// (read or write) the programmed number of data (bytes or words). +// Implemented safeguard against setModule(). +//----------------------------------------------------------------------------- +void spiEventCallback(uint32 spi_num) +{ + //Serial.write('+'); + SPISettings * crtSetting = &_settings[spi_num]; + spi_mode_t state = crtSetting->state; + dma_stream dmaStream; + if ( state==SPI_STATE_RECEIVE ) + { + dmaStream = crtSetting->spiRxDmaStream; + } + else if ( state==SPI_STATE_TRANSMIT) + { + dmaStream = crtSetting->spiTxDmaStream; + } else { + PRINTF("# "); PRINTF(spi_num); PRINTF(" * state="); PRINTF(state); PRINTF(" #"); + return; + } + + uint32_t cr = (crtSetting->spiDmaDev)->regs->STREAM[dmaStream].CR; + // check for half transfer IRQ + if ( (cr&DMA_CR_HTIE) && (dma_get_isr_bits(crtSetting->spiDmaDev, dmaStream)&DMA_ISR_HTIF) ) + { + if (crtSetting->trxCallback) + crtSetting->trxCallback(0); // half transfer + return; + } + // transfer complete. stop the DMA if not in circular mode + if (!(cr&DMA_CR_CIRC)) + { + while (spi_is_tx_empty(crtSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(crtSetting->spi_d) != 0); // "... and then wait until BSY=0" + //while (spi_is_rx_nonempty(crtSetting->spi_d)); + spi_tx_dma_disable(crtSetting->spi_d); + spi_rx_dma_disable(crtSetting->spi_d); + dma_disable(crtSetting->spiDmaDev, dmaStream); + crtSetting->state = SPI_STATE_READY; + } + if (crtSetting->trxCallback) + crtSetting->trxCallback(1); // transfer complete +} +//----------------------------------------------------------------------------- +// DMA call back functions, one per port. +//----------------------------------------------------------------------------- +void _spi1EventCallback(void) { spiEventCallback(0); } + +void _spi2EventCallback(void) { spiEventCallback(1); } + +void _spi3EventCallback(void) { spiEventCallback(2); } + +void _spi4EventCallback(void) { spiEventCallback(3); } + +void _spi5EventCallback(void) { spiEventCallback(4); } + +//----------------------------------------------------------------------------- +void SPIClass::setModule(int spi_num, uint8_t alt_pins) +{ + int spi_port = spi_num - 1; // SPI channels are called 1 2 and 3 but the array is zero indexed + _currentSetting = &_settings[spi_port]; +} + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +SPIClass::SPIClass(uint32 spi_num) +{ + setModule(spi_num); + + //------------------------------------------------------------------------- // Init things specific to each SPI device // clock divider setup is a bit of hack, and needs to be improved at a later date. -/*****************************************************************************/ -// DMA / Channel / Stream -// Rx Tx -// SPI1: 2 / 3 / 0 (2) - 2 / 3 / 3 (5) -// SPI2: 1 / 0 / 3 - 1 / 0 / 4 -// SPI3: 1 / 0 / 0 (2) - 1 / 0 / 5 (7) -/*****************************************************************************/ - _settings[0].spi_d = SPI1; - _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock); -#ifdef SPI_DMA - _settings[0].spiDmaDev = DMA2; - _settings[0].spiDmaChannel = DMA_CH3; - _settings[0].spiRxDmaStream = DMA_STREAM0; // alternative: DMA_STREAM2 - _settings[0].spiTxDmaStream = DMA_STREAM3; // alternative: DMA_STREAM5 -#endif - _settings[1].spi_d = SPI2; - _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock); -#ifdef SPI_DMA - _settings[1].spiDmaDev = DMA1; - _settings[1].spiDmaChannel = DMA_CH0; - _settings[1].spiRxDmaStream = DMA_STREAM3; // alternative: - - _settings[1].spiTxDmaStream = DMA_STREAM4; // alternative: - + //------------------------------------------------------------------------- + // DMA / Channel / Stream + // Rx Tx + // SPI1: 2 / 3 / 0 (2) - 2 / 3 / 3 (5) + // SPI2: 1 / 0 / 3 - 1 / 0 / 4 + // SPI3: 1 / 0 / 0 (2) - 1 / 0 / 5 (7) + //------------------------------------------------------------------------- + if (_settings[0].spi_d==0) // initialize the settings parameters only once + { + _settings[0].spi_d = SPI1; + _settings[0].spiDmaDev = DMA2; + _settings[0].pins = &board_spi_pins[0]; + _settings[0].dmaIsr = _spi1EventCallback; + _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock); + _settings[0].spiDmaChannel = DMA_CH3; + _settings[0].spiRxDmaStream = DMA_STREAM0; // alternative: DMA_STREAM2 + _settings[0].spiTxDmaStream = DMA_STREAM3; // alternative: DMA_STREAM5 + _settings[0].state = SPI_STATE_IDLE; + _settings[1].spi_d = SPI2; + _settings[1].spiDmaDev = DMA1; + _settings[1].pins = &board_spi_pins[1]; + _settings[1].dmaIsr = _spi2EventCallback; + _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock); + _settings[1].spiDmaChannel = DMA_CH0; + _settings[1].spiRxDmaStream = DMA_STREAM3; // alternative: - + _settings[1].spiTxDmaStream = DMA_STREAM4; // alternative: - + _settings[1].state = SPI_STATE_IDLE; + _settings[2].spi_d = SPI3; + _settings[2].spiDmaDev = DMA1; + _settings[2].pins = &board_spi_pins[2]; + _settings[2].dmaIsr = _spi3EventCallback; + _settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock); + _settings[2].spiDmaChannel = DMA_CH0; + _settings[2].spiRxDmaStream = DMA_STREAM0; // alternative: DMA_STREAM2 + _settings[2].spiTxDmaStream = DMA_STREAM5; // alternative: DMA_STREAM7 + _settings[2].state = SPI_STATE_IDLE; +#if (BOARD_NR_SPI>3) + _settings[3].spi_d = SPI4; + _settings[3].spiDmaDev = DMA2; + _settings[3].pins = &board_spi_pins[3]; + _settings[3].dmaIsr = _spi4EventCallback; + _settings[3].clockDivider = determine_baud_rate(_settings[3].spi_d, _settings[3].clock); + _settings[3].spiDmaChannel = DMA_CH4; + _settings[3].spiRxDmaStream = DMA_STREAM0; // alternative: DMA_STREAM4 + _settings[3].spiTxDmaStream = DMA_STREAM1; // alternative: DMA_STREAM4, DMA_CH5 + _settings[3].state = SPI_STATE_IDLE; #endif -#if BOARD_NR_SPI >= 3 - _settings[2].spi_d = SPI3; - _settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock); -#ifdef SPI_DMA - _settings[2].spiDmaDev = DMA1; - _settings[2].spiDmaChannel = DMA_CH0; - _settings[2].spiRxDmaStream = DMA_STREAM0; // alternative: DMA_STREAM2 - _settings[2].spiTxDmaStream = DMA_STREAM5; // alternative: DMA_STREAM7 +#if (BOARD_NR_SPI>4) + _settings[4].spi_d = SPI5; + _settings[4].spiDmaDev = DMA2; + _settings[4].pins = &board_spi_pins[4]; + _settings[4].dmaIsr = _spi5EventCallback; + _settings[4].clockDivider = determine_baud_rate(_settings[4].spi_d, _settings[4].clock); + _settings[4].spiDmaChannel = DMA_CH2; + _settings[4].spiRxDmaStream = DMA_STREAM3; // alternative: CH7 & STREAM5 + _settings[4].spiTxDmaStream = DMA_STREAM4; // alternative: CH5 & STREAM5 + _settings[4].state = SPI_STATE_IDLE; #endif -#endif - + } } -/* - * Set up/tear down - */ +//----------------------------------------------------------------------------- +// Set up/tear down +//----------------------------------------------------------------------------- void SPIClass::updateSettings(void) { - uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE | SPI_SOFT_SS); - #ifdef SPI_DEBUG - Serial.print("spi_master_enable("); Serial.print(_currentSetting->clockDivider); Serial.print(","); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")"); - #endif - spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags); + uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE | SPI_SOFT_SS); + spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags); } -void SPIClass::begin(void) { +void SPIClass::begin(void) +{ + PRINTF("spi_d); - configure_gpios(_currentSetting->spi_d, 1); + configure_gpios(_currentSetting, 1); updateSettings(); -#ifdef SPI_USE_DMA_BUFFER - dmaSendBufferInit(); -#endif -//Serial.println("SPI class begin - end"); + // added for DMA callbacks. + _currentSetting->state = SPI_STATE_READY; + if (_currentSetting->dmaIsr) + { + dma_init(_currentSetting->spiDmaDev); + dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream); // avoid IRQ at NVIC enable + dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream, _currentSetting->dmaIsr); + dma_set_fifo_flags(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream, 0); + dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); // avoid IRQ at NVIC enable + dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, _currentSetting->dmaIsr); + dma_set_fifo_flags(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, 0); + } + PRINTF("-b>"); } -void SPIClass::beginSlave(void) { +void SPIClass::beginSlave(void) +{ + PRINTF("spi_d); - configure_gpios(_currentSetting->spi_d, 0); - uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_RX_ONLY); - #ifdef SPI_DEBUG - Serial.print("spi_slave_enable("); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")"); - #endif + configure_gpios(_currentSetting, 0); + uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize); spi_slave_enable(_currentSetting->spi_d, (spi_mode)_currentSetting->dataMode, flags); + // added for DMA callbacks. + _currentSetting->state = SPI_STATE_READY; + PRINTF("-bS>"); } -void SPIClass::end(void) { +void SPIClass::end(void) +{ if (!spi_is_enabled(_currentSetting->spi_d)) { return; } @@ -195,46 +349,41 @@ void SPIClass::end(void) { // FIXME [0.1.0] remove this once you have an interrupt based driver volatile uint16 rx __attribute__((unused)) = spi_rx_reg(_currentSetting->spi_d); } - while (!spi_is_tx_empty(_currentSetting->spi_d)) - ; - while (spi_is_busy(_currentSetting->spi_d)) - ; + while (!spi_is_tx_empty(_currentSetting->spi_d)); + while (spi_is_busy(_currentSetting->spi_d)); spi_peripheral_disable(_currentSetting->spi_d); + // added for DMA callbacks. + // Need to add unsetting the callbacks for the DMA channels. + _currentSetting->state = SPI_STATE_IDLE; } /* Roger Clark added 3 functions */ void SPIClass::setClockDivider(uint32_t clockDivider) { - #ifdef SPI_DEBUG - Serial.print("Clock divider set to "); Serial.println(clockDivider); - #endif - _currentSetting->clockDivider = clockDivider; - uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_BR); - _currentSetting->spi_d->regs->CR1 = cr1 | (clockDivider & SPI_CR1_BR); + _currentSetting->clockDivider = clockDivider; + uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_BR); + _currentSetting->spi_d->regs->CR1 = cr1 | (clockDivider & SPI_CR1_BR); } void SPIClass::setBitOrder(BitOrder bitOrder) { - #ifdef SPI_DEBUG - Serial.print("Bit order set to "); Serial.println(bitOrder); - #endif - _currentSetting->bitOrder = bitOrder; - uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_LSBFIRST); - if ( bitOrder==LSBFIRST ) cr1 |= SPI_CR1_LSBFIRST; - _currentSetting->spi_d->regs->CR1 = cr1; + _currentSetting->bitOrder = bitOrder; + uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_LSBFIRST); + if ( bitOrder==LSBFIRST ) cr1 |= SPI_CR1_LSBFIRST; + _currentSetting->spi_d->regs->CR1 = cr1; } -/* Victor Perez. Added to test changing datasize from 8 to 16 bit modes on the fly. -* Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word. -* -*/ +//----------------------------------------------------------------------------- +// Victor Perez. Added to test changing datasize from 8 to 16 bit modes on the fly. +// Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word. +//----------------------------------------------------------------------------- void SPIClass::setDataSize(uint32 datasize) { - _currentSetting->dataSize = datasize; - uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_DFF); - uint8 en = spi_is_enabled(_currentSetting->spi_d); - spi_peripheral_disable(_currentSetting->spi_d); - _currentSetting->spi_d->regs->CR1 = cr1 | (datasize & SPI_CR1_DFF) | en; + _currentSetting->dataSize = datasize; + uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_DFF); + uint8 en = spi_is_enabled(_currentSetting->spi_d); + spi_peripheral_disable(_currentSetting->spi_d); + _currentSetting->spi_d->regs->CR1 = cr1 | (datasize & SPI_CR1_DFF) | en; } void SPIClass::setDataMode(uint8_t dataMode) @@ -243,11 +392,11 @@ void SPIClass::setDataMode(uint8_t dataMode) From the AVR doc http://www.atmel.com/images/doc2585.pdf section 2.4 -SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge -0 0 0 Falling Rising -1 0 1 Rising Falling -2 1 0 Rising Falling -3 1 1 Falling Rising +SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge +0 0 0 Falling Rising +1 0 1 Rising Falling +2 1 0 Rising Falling +3 1 1 Falling Rising On the STM32 it appears to be @@ -264,262 +413,496 @@ bit 0 - CPHA : Clock phase If someone finds this is not the case or sees a logic error with this let me know ;-) */ - #ifdef SPI_DEBUG - Serial.print("Data mode set to "); Serial.println(dataMode); - #endif - _currentSetting->dataMode = dataMode; - uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_CPOL|SPI_CR1_CPHA); - _currentSetting->spi_d->regs->CR1 = cr1 | (dataMode & (SPI_CR1_CPOL|SPI_CR1_CPHA)); + _currentSetting->dataMode = dataMode; + uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_CPOL|SPI_CR1_CPHA); + _currentSetting->spi_d->regs->CR1 = cr1 | (dataMode & (SPI_CR1_CPOL|SPI_CR1_CPHA)); } void SPIClass::beginTransaction(uint8_t pin, SPISettings settings) { - #ifdef SPI_DEBUG - Serial.println("SPIClass::beginTransaction"); - #endif - setBitOrder(settings.bitOrder); - setDataMode(settings.dataMode); - setDataSize(settings.dataSize); - setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock)); - begin(); + PRINTF("spi_d, settings.clock)); + begin(); + PRINTF("-bT>"); } void SPIClass::beginTransactionSlave(SPISettings settings) { - #ifdef SPI_DEBUG - Serial.println(F("SPIClass::beginTransactionSlave")); - #endif - setBitOrder(settings.bitOrder); - setDataMode(settings.dataMode); - setDataSize(settings.dataSize); - beginSlave(); + PRINTF(""); } void SPIClass::endTransaction(void) { - #ifdef SPI_DEBUG - Serial.println("SPIClass::endTransaction"); - #endif - //digitalWrite(_SSPin,HIGH); #if false // code from SAM core - uint8_t mode = interruptMode; - if (mode > 0) { - if (mode < 16) { - if (mode & 1) PIOA->PIO_IER = interruptMask[0]; - if (mode & 2) PIOB->PIO_IER = interruptMask[1]; - if (mode & 4) PIOC->PIO_IER = interruptMask[2]; - if (mode & 8) PIOD->PIO_IER = interruptMask[3]; - } else { - if (interruptSave) interrupts(); - } - } + uint8_t mode = interruptMode; + if (mode > 0) { + if (mode < 16) { + if (mode & 1) PIOA->PIO_IER = interruptMask[0]; + if (mode & 2) PIOB->PIO_IER = interruptMask[1]; + if (mode & 4) PIOC->PIO_IER = interruptMask[2]; + if (mode & 8) PIOD->PIO_IER = interruptMask[3]; + } else { + if (interruptSave) interrupts(); + } + } #endif } - -/* - * I/O - */ - +//----------------------------------------------------------------------------- +// I/O +//----------------------------------------------------------------------------- uint16 SPIClass::read(void) { - while ( spi_is_rx_nonempty(_currentSetting->spi_d)==0 ) ; - return (uint16)spi_rx_reg(_currentSetting->spi_d); -} - -void SPIClass::read(uint8 *buf, uint32 len) -{ - if ( len == 0 ) return; - spi_rx_reg(_currentSetting->spi_d); // clear the RX buffer in case a byte is waiting on it. - spi_reg_map * regs = _currentSetting->spi_d->regs; - // start sequence: write byte 0 - regs->DR = 0x00FF; // write the first byte - // main loop - while ( (--len) ) { - while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag - noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data - regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag. - while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register - *buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag. - interrupts(); // let systick do its job - } - // read remaining last byte - while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register - *buf++ = (uint8)(regs->DR); // read and store the received byte + while ( spi_is_rx_nonempty(_currentSetting->spi_d)==0 ) ; + return (uint16)spi_rx_reg(_currentSetting->spi_d); } -void SPIClass::write(uint16 data) +//----------------------------------------------------------------------------- +// Added for 16bit data Victor Perez. Roger Clark +// Improved speed by just directly writing the single byte to the SPI data reg and wait for completion, +// by taking the Tx code from transfer(byte) +// This almost doubles the speed of this function. +//----------------------------------------------------------------------------- +void SPIClass::write(const uint16 data) { - /* Added for 16bit data Victor Perez. Roger Clark - * Improved speed by just directly writing the single byte to the SPI data reg and wait for completion, - * by taking the Tx code from transfer(byte) - * This almost doubles the speed of this function. - */ - spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." -} - -void SPIClass::write(uint16 data, uint32 n) + //Serial.write('.'); + spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) + while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." +} +//----------------------------------------------------------------------------- +// Added by stevestrong: write two consecutive bytes in 8 bit mode (DFF=0) +//----------------------------------------------------------------------------- +void SPIClass::write16(const uint16 data) { - // Added by stevstrong: Repeatedly send same data by the specified number of times - spi_reg_map * regs = _currentSetting->spi_d->regs; - while ( (n--)>0 ) { - regs->DR = data; // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) - while ( (regs->SR & SPI_SR_TXE)==0 ) ; // wait till Tx empty - } - while ( (regs->SR & SPI_SR_BSY) != 0); // wait until BSY=0 before returning + spi_tx_reg(_currentSetting->spi_d, data>>8); // write high byte + while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // Wait until TXE=1 + spi_tx_reg(_currentSetting->spi_d, data); // write low byte + while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // Wait until TXE=1 + while (spi_is_busy(_currentSetting->spi_d) != 0); // wait until BSY=0 +} +//----------------------------------------------------------------------------- +// Added by stevstrong: Repeatedly send same data by the specified number of times +//----------------------------------------------------------------------------- +void SPIClass::write(const uint16 data, uint32 n) +{ + spi_reg_map * regs = _currentSetting->spi_d->regs; + while ( (n--)>0 ) { + regs->DR = data; // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) + while ( (regs->SR & SPI_SR_TXE)==0 ) ; // wait till Tx empty + } + while ( (regs->SR & SPI_SR_BSY) != 0); // wait until BSY=0 before returning } void SPIClass::write(const void *data, uint32 length) { - spi_dev * spi_d = _currentSetting->spi_d; - spi_tx(spi_d, (void*)data, length); // data can be array of bytes or words - while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + spi_dev * spi_d = _currentSetting->spi_d; + spi_tx(spi_d, data, length); // data can be array of bytes or words + while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." } uint8 SPIClass::transfer(uint8 byte) const { - spi_dev * spi_d = _currentSetting->spi_d; - spi_rx_reg(spi_d); // read any previous data - spi_tx_reg(spi_d, byte); // Write the data item to be transmitted into the SPI_DR register - while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." - return (uint8)spi_rx_reg(spi_d); // "... and read the last received data." -} - -uint16_t SPIClass::transfer16(uint16_t wr_data) const -{ - spi_dev * spi_d = _currentSetting->spi_d; - spi_rx_reg(spi_d); // read any previous data - spi_tx_reg(spi_d, wr_data); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)." - while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." - return (uint16)spi_rx_reg(spi_d); // "... and read the last received data." -} - -#ifdef SPI_DMA -/* Roger Clark and Victor Perez, 2015 -* Performs a DMA SPI transfer with at least a receive buffer. -* If a TX buffer is not provided, FF is sent over and over for the length of the transfer. -* On exit TX buffer is not modified, and RX buffer contains the received data. -* Still in progress. -*/ -uint8 SPIClass::dmaTransfer(const void * transmitBuf, void * receiveBuf, uint16 length) -{ - if (length == 0) return 0; - - uint8 b = 0; - - dma_init(_currentSetting->spiDmaDev); -// dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event); - // RX - dma_xfer_size dma_bit_size = (_currentSetting->dataSize==SPI_DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; - dma_setup_transfer( _currentSetting->spiDmaDev, - _currentSetting->spiRxDmaStream, - _currentSetting->spiDmaChannel, - dma_bit_size, - &_currentSetting->spi_d->regs->DR, // peripheral address - receiveBuf, // memory bank 0 address - NULL, // memory bank 1 address - (DMA_MINC_MODE | DMA_FROM_PER | DMA_PRIO_VERY_HIGH) // flags - ); - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream, length); - dma_set_fifo_flags(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream, 0); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream); - - // TX - uint32 flags = (DMA_MINC_MODE | DMA_FROM_MEM); // | DMA_TRNS_CMPLT); - if ( transmitBuf==0 ) { - static uint8_t ff = 0XFF; - transmitBuf = &ff; - flags &= ~((uint32)DMA_MINC_MODE); // remove increment mode - } - dma_setup_transfer( _currentSetting->spiDmaDev, - _currentSetting->spiTxDmaStream, - _currentSetting->spiDmaChannel, - dma_bit_size, - &_currentSetting->spi_d->regs->DR, // peripheral address - (volatile void*)transmitBuf, // memory bank 0 address - NULL, // memory bank 1 address - flags - ); - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, length); - dma_set_fifo_flags(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, 0); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); - // software enable sequence, see AN4031, chapter 4.3 - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream);// enable receive - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream);// enable transmit - spi_rx_reg(_currentSetting->spi_d); //Clear the RX buffer in case a byte is waiting on it. - spi_rx_dma_enable(_currentSetting->spi_d); - spi_tx_dma_enable(_currentSetting->spi_d); // must be the last enable to avoid DMA error flag - - uint32_t m = millis(); - while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream) & DMA_ISR_TCIF)==0 ) {// wait for completion flag to be set - if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } + spi_dev * spi_d = _currentSetting->spi_d; + spi_rx_reg(spi_d); // read any previous data + spi_tx_reg(spi_d, byte); // Write the data item to be transmitted into the SPI_DR register + while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + return (uint8)spi_rx_reg(spi_d); // "... and read the last received data." +} +//----------------------------------------------------------------------------- +// Modified by stevestrong: write & read two consecutive bytes in 8 bit mode (DFF=0) +// This is more effective than two distinct byte transfers +//----------------------------------------------------------------------------- +uint16_t SPIClass::transfer16(const uint16_t data) const +{ + spi_dev * spi_d = _currentSetting->spi_d; + spi_rx_reg(spi_d); // read any previous data + spi_tx_reg(spi_d, data>>8); // write high byte + while (spi_is_tx_empty(spi_d) == 0); // wait until TXE=1 + while (spi_is_busy(spi_d) != 0); // wait until BSY=0 + uint16_t ret = spi_rx_reg(spi_d)<<8; // read and shift high byte + spi_tx_reg(spi_d, data); // write low byte + while (spi_is_tx_empty(spi_d) == 0); // wait until TXE=1 + while (spi_is_busy(spi_d) != 0); // wait until BSY=0 + ret += spi_rx_reg(spi_d); // read low byte + return ret; +} + +void SPIClass::transfer(const uint8_t * tx_buf, uint8_t * rx_buf, uint32 len) +{ +PRINTF("spi_d); // clear the RX buffer in case a byte is waiting on it. + spi_reg_map * regs = _currentSetting->spi_d->regs; + // start sequence: write byte 0 + regs->DR = *tx_buf++; // write the first byte + // main loop + while ( (--len) ) { + while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag + noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data + regs->DR = *tx_buf++; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag. + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register + *rx_buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag. + interrupts(); // let systick do its job } + // read remaining last byte + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register + *rx_buf++ = (uint8)(regs->DR); // read and store the received byte +PRINTF("-Tb>\n"); +} - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." - // software disable sequence, see AN4031, chapter 4.1 - spi_tx_dma_disable(_currentSetting->spi_d); - spi_rx_dma_disable(_currentSetting->spi_d); - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream); - return b; -} - -/* Roger Clark and Victor Perez, 2015 -* Performs a DMA SPI send using a TX buffer. -* On exit TX buffer is not modified. -* Still in progress. -* 2016 - stevstrong - reworked to automatically detect bit size from SPI setting -*/ -uint8 SPIClass::dmaSend(const void * transmitBuf, uint16 length, bool minc) -{ - if (length == 0) return 0; - uint8 b = 0; - dma_init(_currentSetting->spiDmaDev); - // TX - dma_xfer_size dma_bit_size = (_currentSetting->dataSize==SPI_DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; - dma_setup_transfer( _currentSetting->spiDmaDev, - _currentSetting->spiTxDmaStream, - _currentSetting->spiDmaChannel, - dma_bit_size, - &_currentSetting->spi_d->regs->DR, // peripheral address - (volatile void*)transmitBuf, // memory bank 0 address - NULL, // memory bank 1 address - ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM ) //| DMA_TRNS_CMPLT ) // flags - );// Transmit buffer DMA - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, length); - dma_set_fifo_flags(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, 0); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream);// enable transmit - spi_tx_dma_enable(_currentSetting->spi_d); - - uint32_t m = millis(); - while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream) & DMA_ISR_TCIF)==0 ) {// wait for completion flag to be set - if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } +void SPIClass::transfer(const uint8_t tx_data, uint8_t * rx_buf, uint32 len) +{ +PRINTF("spi_d); // clear the RX buffer in case a byte is waiting on it. + spi_reg_map * regs = _currentSetting->spi_d->regs; + // start sequence: write byte 0 + regs->DR = tx_data; // write the first byte + // main loop + while ( (--len) ) { + while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag + noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data + regs->DR = tx_data; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag. + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register + *rx_buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag. + interrupts(); // let systick do its job } + // read remaining last byte + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register + *rx_buf++ = (uint8)(regs->DR); // read and store the received byte +PRINTF("-Tc>\n"); +} - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." - spi_tx_dma_disable(_currentSetting->spi_d); - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); - return b; +void SPIClass::transfer(const uint16_t * tx_buf, uint16_t * rx_buf, uint32 len) +{ +PRINTF("spi_d); // clear the RX buffer in case a byte is waiting on it. + spi_reg_map * regs = _currentSetting->spi_d->regs; + // start sequence: write byte 0 + regs->DR = *tx_buf++; // write the first byte + // main loop + while ( (--len) ) { + while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag + noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data + regs->DR = *tx_buf++; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag. + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register + *rx_buf++ = regs->DR; // read and store the received byte. This clears the RXNE flag. + interrupts(); // let systick do its job + } + // read remaining last byte + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register + *rx_buf++ = regs->DR; // read and store the received byte +PRINTF("-Tb2>\n"); } -#endif +void SPIClass::transfer(const uint16_t tx_data, uint16_t * rx_buf, uint32 len) +{ +PRINTF("spi_d); // clear the RX buffer in case a byte is waiting on it. + spi_reg_map * regs = _currentSetting->spi_d->regs; + // start sequence: write byte 0 + regs->DR = tx_data; // write the first byte + // main loop + while ( (--len) ) { + while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag + noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data + regs->DR = tx_data; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag. + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register + *rx_buf++ = regs->DR; // read and store the received byte. This clears the RXNE flag. + interrupts(); // let systick do its job + } + // read remaining last byte + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register + *rx_buf++ = regs->DR; // read and store the received byte +PRINTF("-Tc2>\n"); +} + +//----------------------------------------------------------------------------- +// Roger Clark and Victor Perez, 2015 +// Performs a DMA SPI transfer with at least a receive buffer. +// If a TX buffer is not provided, FF is sent over and over for the lenght of the transfer. +// On exit TX buffer is not modified, and RX buffer cotains the received data. +// Still in progress. +//----------------------------------------------------------------------------- +// Changed by stevestrong: +// - DMA IRQ event will always be triggered +// - inserted yield() on waiting for DMA end +// - added half transfer monitoring +//----------------------------------------------------------------------------- +// Wait for DMA to finish its job +//----------------------------------------------------------------------------- +void SPIClass::dmaWaitCompletion(void) +{ + PRINTF("state != SPI_STATE_READY) + { + uint32_t m = millis(); + while ( _currentSetting->state != SPI_STATE_READY ) + { + yield(); // do something in main loop + + if ((millis()-m)>DMA_TIMEOUT) + { + PRINTF("DMA timeout: state="); PRINTF( (_currentSetting->state==SPI_STATE_RECEIVE)? "Rx":"Tx"); + PRINTF("\nDMA[Tx] CR: "); PRINTF((_currentSetting->spiDmaDev)->regs->STREAM[_currentSetting->spiTxDmaStream].CR, HEX); + PRINTF(", NDTR: "); PRINTF((_currentSetting->spiDmaDev)->regs->STREAM[_currentSetting->spiTxDmaStream].NDTR); + PRINTF(", LISR: "); PRINTF((_currentSetting->spiDmaDev)->regs->LISR, HEX); + PRINTF("\nDMA[Rx] CR: "); PRINTF((_currentSetting->spiDmaDev)->regs->STREAM[_currentSetting->spiRxDmaStream].CR, HEX); + PRINTF(", NDTR: "); PRINTF((_currentSetting->spiDmaDev)->regs->STREAM[_currentSetting->spiRxDmaStream].NDTR); + PRINTF(", LISR: "); PRINTF((_currentSetting->spiDmaDev)->regs->LISR, HEX); + PRINTF("\n"); + // disable DMA + while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0" + spi_tx_dma_disable(_currentSetting->spi_d); + spi_rx_dma_disable(_currentSetting->spi_d); + dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); + dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream); + //while(1); + _currentSetting->state = SPI_STATE_READY; + break; + } + } + } + PRINTF("-dWC>"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaTransferSet(void *receiveBuf, uint16 flags) +{ + PRINTF("dataSize==SPI_DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; + // RX + dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream, + _currentSetting->spiDmaChannel, dma_bit_size, + &_currentSetting->spi_d->regs->DR, // peripheral address + receiveBuf, // memory bank 0 address + NULL, // memory bank 1 address + (flags | (DMA_MINC_MODE|DMA_FROM_PER|DMA_TRNS_CMPLT|DMA_PRIO_VERY_HIGH))); + // TX + dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, + _currentSetting->spiDmaChannel, dma_bit_size, + &_currentSetting->spi_d->regs->DR, // peripheral address + _currentSetting->dmaTxBuffer, // memory bank 0 address + NULL, // memory bank 1 address + (flags | DMA_FROM_MEM)); + PRINTF("-dTS>"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaTransferRepeat() +{ + PRINTF("state = SPI_STATE_RECEIVE; + // RX + dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream, _currentSetting->dmaTrxLength); + dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream); + dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream); + // TX + dma_set_mem_addr(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, (__IO void*)_currentSetting->dmaTxBuffer); + dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, _currentSetting->dmaTrxLength); + dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); + dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); + // software enable sequence, see AN4031, chapter 4.3 + spi_rx_reg(_currentSetting->spi_d); // pre-empty Rx pipe + spi_rx_dma_enable(_currentSetting->spi_d); + spi_tx_dma_enable(_currentSetting->spi_d); + if (!_currentSetting->dmaTrxAsync) + dmaWaitCompletion(); + PRINTF("-dTR>"); +} + +//----------------------------------------------------------------------------- +// Roger Clark and Victor Perez, 2015, stevestrong 2018 +// Performs a DMA SPI transfer with at least a receive buffer. +// If a TX buffer is not provided, FF is sent over and over for the length of the transfer. +// On exit TX buffer is not modified, and RX buffer contains the received data. +// Still in progress. +//----------------------------------------------------------------------------- +void SPIClass::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16 length, uint16 flags) +{ + if ( transmitBuf==NULL ) { + if ( receiveBuf!=NULL ) { + dmaTransfer(ff, receiveBuf, length, flags); + } + return; + } else { + if ( receiveBuf==NULL ) { + dmaSend(transmitBuf, length, flags); + return; + } + PRINTF("dmaTxBuffer = transmitBuf; + _currentSetting->dmaTrxLength = length; + _currentSetting->dmaTrxAsync = (flags&DMA_ASYNC); + dmaTransferSet(receiveBuf, (flags&(DMA_CIRC_MODE|DMA_TRNS_HALF)) | DMA_MINC_MODE); + dmaTransferRepeat(); + PRINTF("-dTb>\n"); + } +} +//----------------------------------------------------------------------------- +void SPIClass::dmaTransfer(const uint16_t tx_data, void *receiveBuf, uint16 length, uint16 flags) +{ + if ( receiveBuf==NULL ) { + dmaSend(tx_data, length, flags); + return; + } + PRINTF("dmaTxBuffer = &ff; + _currentSetting->dmaTrxLength = length; + _currentSetting->dmaTrxAsync = (flags&DMA_ASYNC); + dmaTransferSet(receiveBuf, (flags&(DMA_CIRC_MODE|DMA_TRNS_HALF))); + dmaTransferRepeat(); + PRINTF("-dTc>\n"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaTransferInit(const void *transmitBuf, void *receiveBuf, uint16 length, uint16 flags) +{ + PRINTF("dmaTxBuffer = transmitBuf; + _currentSetting->dmaTrxLength = length; + _currentSetting->dmaTrxAsync = (flags&DMA_ASYNC); + dmaTransferSet(receiveBuf, (flags&(DMA_CIRC_MODE|DMA_TRNS_HALF)) | DMA_MINC_MODE); + PRINTF("-dTI>\n"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaTransferInit(const uint16_t tx_data, void *receiveBuf, uint16 length, uint16 flags) +{ + PRINTF("dmaTxBuffer = &ff; + _currentSetting->dmaTrxLength = length; + _currentSetting->dmaTrxAsync = (flags&DMA_ASYNC); + dmaTransferSet(receiveBuf, (flags&(DMA_CIRC_MODE|DMA_TRNS_HALF))); + PRINTF("-dTI>\n"); +} + +//----------------------------------------------------------------------------- +// Roger Clark and Victor Perez, 2015 +// Performs a DMA SPI send using a TX buffer. +// On exit TX buffer is not modified. +// Still in progress. +// 2016 - stevstrong - reworked to automatically detect bit size from SPI setting +//----------------------------------------------------------------------------- +void SPIClass::dmaSendSet(uint16 flags) +{ + PRINTF("dataSize==SPI_DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; + dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, + _currentSetting->spiDmaChannel, dma_bit_size, + &_currentSetting->spi_d->regs->DR, // peripheral address + _currentSetting->dmaTxBuffer, // memory bank 0 address + NULL, // memory bank 1 address + (flags | (DMA_FROM_MEM | DMA_TRNS_CMPLT))); + PRINTF("-dSS>"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaSendRepeat(void) +{ + PRINTF("state = SPI_STATE_TRANSMIT; + dma_set_mem_addr(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, (__IO void*)_currentSetting->dmaTxBuffer); + dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, _currentSetting->dmaTrxLength); + dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); + dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); + spi_tx_dma_enable(_currentSetting->spi_d); + if (!_currentSetting->dmaTrxAsync) // check async flag + dmaWaitCompletion(); + PRINTF("-dSR>"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaSend(const void * transmitBuf, uint16 length, uint16 flags) +{ + PRINTF("dmaTxBuffer = transmitBuf; + _currentSetting->dmaTrxLength = length; + _currentSetting->dmaTrxAsync = (flags&DMA_ASYNC); + dmaSendSet((flags&(DMA_CIRC_MODE|DMA_TRNS_HALF)) | DMA_MINC_MODE); + dmaSendRepeat(); + PRINTF("-dS>\n"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaSend(const uint16_t tx_data, uint16 length, uint16 flags) +{ + PRINTF("dmaTxBuffer = &ff; + _currentSetting->dmaTrxLength = length; + _currentSetting->dmaTrxAsync = (flags&DMA_ASYNC); + dmaSendSet(flags&(DMA_CIRC_MODE|DMA_TRNS_HALF)); + dmaSendRepeat(); + PRINTF("-dS>\n"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaSend(const void * transmitBuf) +{ + PRINTF("dmaTxBuffer = transmitBuf; + dmaSendRepeat(); + PRINTF("-dS>\n"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaSend(const uint16_t tx_data) +{ + PRINTF("\n"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaSendInit(const void * txBuf, uint16 length, uint16 flags) +{ + PRINTF("dmaTxBuffer = txBuf; + _currentSetting->dmaTrxLength = length; + _currentSetting->dmaTrxAsync = (flags&DMA_ASYNC); + dmaSendSet((flags&(DMA_CIRC_MODE|DMA_TRNS_HALF)) | DMA_MINC_MODE); + PRINTF("-dSI>\n"); +} +//----------------------------------------------------------------------------- +void SPIClass::dmaSendInit(const uint16_t tx_data, uint16 length, uint16 flags) +{ + PRINTF("dmaTxBuffer = &ff; + _currentSetting->dmaTrxLength = length; + _currentSetting->dmaTrxAsync = (flags&DMA_ASYNC); + dmaSendSet((flags&(DMA_CIRC_MODE|DMA_TRNS_HALF))); + PRINTF("-dSI>\n"); +} void SPIClass::attachInterrupt(void) { - // Should be enableInterrupt() + // Should be enableInterrupt() } void SPIClass::detachInterrupt(void) { - // Should be disableInterrupt() + // Should be disableInterrupt() } /* @@ -527,19 +910,19 @@ void SPIClass::detachInterrupt(void) { */ uint8 SPIClass::misoPin(void) { - return dev_to_spi_pins(_currentSetting->spi_d)->miso; + return (_currentSetting->pins)->miso; } uint8 SPIClass::mosiPin(void) { - return dev_to_spi_pins(_currentSetting->spi_d)->mosi; + return (_currentSetting->pins)->mosi; } uint8 SPIClass::sckPin(void) { - return dev_to_spi_pins(_currentSetting->spi_d)->sck; + return (_currentSetting->pins)->sck; } uint8 SPIClass::nssPin(void) { - return dev_to_spi_pins(_currentSetting->spi_d)->nss; + return (_currentSetting->pins)->nss; } /* @@ -556,99 +939,8 @@ uint8 SPIClass::send(uint8 *buf, uint32 len) { return len; } -uint8 SPIClass::recv(void) { - return this->read(); -} - - -/* - * Auxiliary functions - */ - -static const spi_pins* dev_to_spi_pins(spi_dev *dev) { - switch (dev->clk_id) { -#if BOARD_NR_SPI >= 1 - case RCC_SPI1: return board_spi_pins; -#endif -#if BOARD_NR_SPI >= 2 - case RCC_SPI2: return board_spi_pins + 1; -#endif -#if BOARD_NR_SPI >= 3 - case RCC_SPI3: return board_spi_pins + 2; +#ifndef DEFAULT_SPI_PORT + #define DEFAULT_SPI_PORT 1 #endif - default: return NULL; - } -} - -static void disable_pwm(const stm32_pin_info *i) { - if (i->timer_device) { - timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED); - } -} - -static void configure_gpios(spi_dev *dev, bool as_master) { - const spi_pins *pins = dev_to_spi_pins(dev); - - if (!pins) { - return; - } - - const stm32_pin_info *nssi = &PIN_MAP[pins->nss]; - const stm32_pin_info *scki = &PIN_MAP[pins->sck]; - const stm32_pin_info *misoi = &PIN_MAP[pins->miso]; - const stm32_pin_info *mosii = &PIN_MAP[pins->mosi]; - - disable_pwm(nssi); - disable_pwm(scki); - disable_pwm(misoi); - disable_pwm(mosii); - - #ifdef SPI_DEBUG - Serial.print("SPI configure_gpios / (nss="); - Serial.print(pins->nss); Serial.print(", sck="); Serial.print(pins->sck); - Serial.print(", miso="); Serial.print(pins->miso); - Serial.print(", mosi="); Serial.print(pins->mosi); - Serial.println(")"); - #endif - - spi_config_gpios(dev, as_master, pins->nss, pins->sck, pins->miso, pins->mosi); -} - -static const spi_baud_rate baud_rates[8] __FLASH__ = { - SPI_BAUD_PCLK_DIV_2, - SPI_BAUD_PCLK_DIV_4, - SPI_BAUD_PCLK_DIV_8, - SPI_BAUD_PCLK_DIV_16, - SPI_BAUD_PCLK_DIV_32, - SPI_BAUD_PCLK_DIV_64, - SPI_BAUD_PCLK_DIV_128, - SPI_BAUD_PCLK_DIV_256, -}; - -/* - * Note: This assumes you're on a LeafLabs-style board - * (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz). - */ -static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) { - uint32_t clock = 0, i; - #ifdef SPI_DEBUG - Serial.print("determine_baud_rate("); Serial.print(freq); Serial.println(")"); - #endif - switch (rcc_dev_clk(dev->clk_id)) - { - case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz - case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz - case RCC_AHB1: break; - default: break; - } - clock /= 2; - i = 0; - while (i < 7 && freq < clock) { - clock /= 2; - i++; - } - return baud_rates[i]; -} - -SPIClass SPI(3); // needed for external libs +SPIClass SPI(DEFAULT_SPI_PORT); diff --git a/STM32F4/libraries/SPI/src/SPI.h b/STM32F4/libraries/SPI/src/SPI.h index f46795ce3..438728599 100644 --- a/STM32F4/libraries/SPI/src/SPI.h +++ b/STM32F4/libraries/SPI/src/SPI.h @@ -40,9 +40,10 @@ #include #include #include -#include -#define SPI_DMA +#include +#include +#include // SPI_HAS_TRANSACTION means SPI has // - beginTransaction() @@ -60,23 +61,6 @@ #define SPI_CLOCK_DIV128 SPI_BAUD_PCLK_DIV_128 #define SPI_CLOCK_DIV256 SPI_BAUD_PCLK_DIV_256 -/* - * Roger Clark. 20150106 - * Commented out redundant AVR defined - * -#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR -#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR -#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR - -// define SPI_AVR_EIMSK for AVR boards with external interrupt pins -#if defined(EIMSK) - #define SPI_AVR_EIMSK EIMSK -#elif defined(GICR) - #define SPI_AVR_EIMSK GICR -#elif defined(GIMSK) - #define SPI_AVR_EIMSK GIMSK -#endif -*/ #ifndef STM32_LSBFIRST #define STM32_LSBFIRST 0 @@ -86,8 +70,7 @@ #endif // PC13 or PA4 -//#define BOARD_SPI_DEFAULT_SS PA4 -#define BOARD_SPI_DEFAULT_SS PC13 +#define BOARD_SPI_DEFAULT_SS BOARD_SPI3_NSS_PIN #define SPI_MODE0 SPI_MODE_0 #define SPI_MODE1 SPI_MODE_1 @@ -96,58 +79,85 @@ #define SPI_DATA_SIZE_8BIT SPI_CR1_DFF_8_BIT #define SPI_DATA_SIZE_16BIT SPI_CR1_DFF_16_BIT +#define DMA_ASYNC (BIT0) + +typedef void (*u32FuncPtr)(uint32_t); + +typedef enum { + SPI_STATE_IDLE = 0, + SPI_STATE_READY, + SPI_STATE_RECEIVE, + SPI_STATE_TRANSMIT, + SPI_STATE_TRANSFER +} spi_mode_t; -class SPISettings { +class SPISettings +{ +private: + inline void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) + { + this->clock = clock; + this->bitOrder = bitOrder; + this->dataMode = dataMode; + this->dataSize = dataSize; + } + inline void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) + { + init_AlwaysInline(clock, bitOrder, dataMode, dataSize); + } public: - SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) { - if (__builtin_constant_p(clock)) { - init_AlwaysInline(clock, bitOrder, dataMode, SPI_DATA_SIZE_8BIT); - } else { - init_MightInline(clock, bitOrder, dataMode, SPI_DATA_SIZE_8BIT); - } - } - SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) { - if (__builtin_constant_p(clock)) { - init_AlwaysInline(clock, bitOrder, dataMode, dataSize); - } else { - init_MightInline(clock, bitOrder, dataMode, dataSize); - } - } - SPISettings(uint32_t clock) { - if (__builtin_constant_p(clock)) { - init_AlwaysInline(clock, MSBFIRST, SPI_MODE0, SPI_DATA_SIZE_8BIT); - } else { - init_MightInline(clock, MSBFIRST, SPI_MODE0, SPI_DATA_SIZE_8BIT); - } - } - SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, SPI_DATA_SIZE_8BIT); } + SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) + { + if (__builtin_constant_p(clock)) { + init_AlwaysInline(clock, bitOrder, dataMode, SPI_DATA_SIZE_8BIT); + } else { + init_MightInline(clock, bitOrder, dataMode, SPI_DATA_SIZE_8BIT); + } + } + SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) + { + if (__builtin_constant_p(clock)) { + init_AlwaysInline(clock, bitOrder, dataMode, dataSize); + } else { + init_MightInline(clock, bitOrder, dataMode, dataSize); + } + } + SPISettings(uint32_t clock) + { + if (__builtin_constant_p(clock)) { + init_AlwaysInline(clock, MSBFIRST, SPI_MODE0, SPI_DATA_SIZE_8BIT); + } else { + init_MightInline(clock, MSBFIRST, SPI_MODE0, SPI_DATA_SIZE_8BIT); + } + } + SPISettings() { init_AlwaysInline(4200000, MSBFIRST, SPI_MODE0, SPI_DATA_SIZE_8BIT); } + private: - void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) { - init_AlwaysInline(clock, bitOrder, dataMode, dataSize); - } - void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) __attribute__((__always_inline__)) { - this->clock = clock; - this->bitOrder = bitOrder; - this->dataMode = dataMode; - this->dataSize = dataSize; - } - uint32_t clock; - BitOrder bitOrder; - uint8_t dataMode; - uint32_t dataSize; - - spi_dev *spi_d; - uint32_t clockDivider; - -#ifdef SPI_DMA - dma_dev* spiDmaDev; - dma_channel spiDmaChannel; - dma_stream spiRxDmaStream, spiTxDmaStream; -#endif + uint32_t clock; + uint32_t dataSize; + uint32_t clockDivider; +public: + spi_dev * spi_d; + const dma_dev * spiDmaDev; + const spi_pins_t * pins; + voidFuncPtr dmaIsr; + u32FuncPtr trxCallback; + dma_channel spiDmaChannel; + dma_stream spiRxDmaStream, spiTxDmaStream; + volatile spi_mode_t state; +private: + const void * dmaTxBuffer; + uint16_t dmaTrxLength; + uint8_t dmaTrxAsync; + BitOrder bitOrder; + uint8_t dataMode; +public: - friend class SPIClass; + friend class SPIClass; }; +extern SPISettings _settings[BOARD_NR_SPI]; + /** * @brief Wirish SPI interface. @@ -163,7 +173,6 @@ class SPIClass { */ SPIClass(uint32 spiPortNumber); - /** * @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0). */ @@ -189,27 +198,37 @@ class SPIClass { */ void end(void); - void beginTransaction(SPISettings settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); } - void beginTransaction(uint8_t pin, SPISettings settings); - void endTransaction(void); - - void beginTransactionSlave(SPISettings settings); - - void setClockDivider(uint32_t clockDivider); - void setBitOrder(BitOrder bitOrder); - void setDataMode(uint8_t dataMode); - - // SPI Configuration methods - void attachInterrupt(void); - void detachInterrupt(void); - - /* Victor Perez. Added to change datasize from 8 to 16 bit modes on the fly. - * Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word. - * Requires an added function spi_data_size on STM32F1 / cores / maple / libmaple / spi.c - */ + void beginTransaction(uint8_t pin, SPISettings settings); + void beginTransaction(SPISettings settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); } + void endTransaction(void); + + void beginTransactionSlave(SPISettings settings); + + void setClockDivider(uint32_t clockDivider); + void setBitOrder(BitOrder bitOrder); + void setDataMode(uint8_t dataMode); + + // SPI Configuration methods + void attachInterrupt(void); + void detachInterrupt(void); + + //------------------------------------------------------------------------- + // Victor Perez. Added to change datasize from 8 to 16 bit modes on the fly. + // Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word. + // Requires an added function spi_data_size on STM32F1 / cores / maple / libmaple / spi.c + //------------------------------------------------------------------------- void setDataSize(uint32 ds); - - + + //------------------------------------------------------------------------- + // Victor Perez 2017. Added to set and clear user callback functions + // for callback on DMA transfer completion. + // onReceive used to set the callback in case of dmaTransfer (rx), once rx is completed + // onTransmit used to set the callback in case of dmaSend (tx). + //------------------------------------------------------------------------- + void onTransferEnd(u32FuncPtr callback) { _currentSetting->trxCallback = callback; } + inline void onTransmit(u32FuncPtr callback) { onTransferEnd(callback); } + inline void onReceive(u32FuncPtr callback) { onTransferEnd(callback); } + /* * I/O */ @@ -229,20 +248,23 @@ class SPIClass { * function will block until the desired number of * bytes have been read. */ - void read(uint8 *buffer, uint32 length); + void read(uint8 *buffer, uint32 length) { + return transfer((uint8_t)0xFF, buffer, length); + } /** * @brief Transmit one byte/word. * @param data to transmit. */ - void write(uint16 data); - + void write(const uint16 data); + void write16(const uint16 data); // write 2 bytes in 8 bit mode (DFF=0) + /** * @brief Transmit one byte/word a specified number of times. * @param data to transmit. */ - void write(uint16 data, uint32 n); - + void write(const uint16 data, uint32 n); + /** * @brief Transmit multiple bytes/words. * @param buffer Bytes/words to transmit. @@ -259,32 +281,65 @@ class SPIClass { * @return Next unread byte. */ uint8 transfer(uint8 data) const; - uint16_t transfer16(uint16_t data) const; - -#ifdef SPI_DMA - /** + uint16_t transfer16(const uint16_t data) const; + void transfer(const uint8_t * tx_buf, uint8_t * rx_buf, uint32 len); + void transfer(const uint8_t tx_data, uint8_t * rx_buf, uint32 len); + void transfer(const uint16_t * tx_buf, uint16_t * rx_buf, uint32 len); + void transfer(const uint16_t tx_data, uint16_t * rx_buf, uint32 len); + inline void transfer(uint8_t * buf, uint32 len) { transfer((const uint8_t *)buf, buf, len); } + + /** * @brief Sets up a DMA Transfer for "length" bytes. - * The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting. + * The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting. * * This function transmits and receives to buffers. * * @param transmitBuf buffer Bytes to transmit. If passed as 0, it sends FF repeatedly for "length" bytes * @param receiveBuf buffer Bytes to save received data. * @param length Number of bytes in buffer to transmit. - */ - uint8 dmaTransfer(const void * transmitBuf, void * receiveBuf, uint16 length); + */ +private: + void dmaTransferSet(void * receiveBuf, uint16 flags); + void dmaTransferRepeat(); +public: + void dmaTransferInit(const void * transmitBuf, void * receiveBuf, uint16 length, uint16 flags = 0); + void dmaTransferInit(const uint16_t tx_data, void * receiveBuf, uint16 length, uint16 flags = 0); + void dmaTransfer(const void * transmitBuf, void * receiveBuf, uint16 length, uint16 flags = 0); + void dmaTransfer(const uint16_t tx_data, void * receiveBuf, uint16 length, uint16 flags = 0); + void dmaTransfer(void) { dmaTransferRepeat(); } + uint8_t dmaTransferReady() { return (_currentSetting->state == SPI_STATE_READY) ? 1 : 0; } + uint8_t dmaTransferState() { return (_currentSetting->state); } + uint16_t dmaTransferRemaining(void) { + return dma_get_count(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream); + } - /** + /** * @brief Sets up a DMA Transmit for SPI 8 or 16 bit transfer mode. - * The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting. + * The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting. * * This function only transmits and does not care about the RX fifo. * * @param data buffer half words to transmit, * @param length Number of bytes in buffer to transmit. + * @param minc Set to use Memory Increment mode, clear to use Circular mode. */ - uint8 dmaSend(const void * transmitBuf, uint16 length, bool minc = 1); -#endif +private: + void dmaSendSet(uint16 flags); + void dmaSendRepeat(); +public: + void dmaSendInit(const void * transmitBuf, uint16 length, uint16 flags = 0); + void dmaSendInit(const uint16_t tx_dat, uint16 length, uint16 flags = 0); + void dmaSend(const void * transmitBuf, uint16 length, uint16 flags = 0); + void dmaSend(const uint16_t tx_data, uint16 length, uint16 flags = 0); + void dmaSend(const void * transmitBuf); + void dmaSend(const uint16_t tx_data); + void dmaSend(void) { dmaSendRepeat(); } + uint8_t dmaSendReady() { return (_currentSetting->state == SPI_STATE_READY) ? 1 : 0; } + uint16_t dmaSendRemaining(void) { + return dma_get_count(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream); + } + + #define dmaSendAsync(transmit, length, minc) ( dmaSend(transmit, length, (minc&BIT0)) ) /* * Pin accessors @@ -317,23 +372,15 @@ class SPIClass { * this HardwareSPI instance. */ spi_dev* c_dev(void) { return _currentSetting->spi_d; } - - - spi_dev *dev(){ return _currentSetting->spi_d;} - - /** - * @brief Sets the number of the SPI peripheral to be used by - * this HardwareSPI instance. - * - * @param spi_num Number of the SPI port. 1-2 in low density devices - * or 1-3 in high density devices. - */ - - void setModule(int spi_num) - { - _currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed - } + spi_dev *dev(){ return _currentSetting->spi_d; } + + /** + * @brief Sets the number of the SPI peripheral to be used by this HardwareSPI instance. + * + * @param spi_num Number of the SPI port. 1-2 in low density devices or 1-3 in high density devices. + */ + void setModule(int spi_num, uint8_t alt_pins = 0); /* -- The following methods are deprecated --------------------------- */ @@ -358,22 +405,17 @@ class SPIClass { */ uint8 send(uint8 *data, uint32 length); - /** - * @brief Deprecated. - * - * Use HardwareSPI::read() instead. - * - * @see HardwareSPI::read() - */ - uint8 recv(void); - + void EventCallback(uint16_t spi_num); + private: - SPISettings _settings[BOARD_NR_SPI]; - SPISettings *_currentSetting; - - void updateSettings(void); + SPISettings *_currentSetting; + + void updateSettings(void); + + void dmaWaitCompletion(void); + }; -extern SPIClass SPI; // needed bx SdFat(EX) lib +extern SPIClass SPI; #endif diff --git a/STM32F4/libraries/STM32F4_ADC/examples/MultiChannel_noDMA/MultiChannel_noDMA.ino b/STM32F4/libraries/STM32F4_ADC/examples/MultiChannel_noDMA/MultiChannel_noDMA.ino new file mode 100644 index 000000000..931bdc8cd --- /dev/null +++ b/STM32F4/libraries/STM32F4_ADC/examples/MultiChannel_noDMA/MultiChannel_noDMA.ino @@ -0,0 +1,86 @@ +/* + Analog input example. + + Uasge: + - define an array of analog input pins according to the wanted channels. + Possible values: + ---------------- + ADC_CH0 = PA0 + ADC_CH1 = PA1 + ADC_CH2 = PA2 // PF0 + ADC_CH3 = PA3 + ADC_CH4 = PA4 // PF6 + ADC_CH5 = PA5 // PF7 + ADC_CH6 = PA6 // PF8 + ADC_CH7 = PA7 // PF9 + ADC_CH8 = PB0 // PF10 + ADC_CH9 = PB1 // PF3 + ADC_CH10 = PC0 + ADC_CH11 = PC1 + ADC_CH12 = PC2 + ADC_CH13 = PC3 + ADC_CH14 = PC4 // PF4 + ADC_CH15 = PC5 // PF5 + ADC_CH16 = temperature sensor (intern) + ADC_CH17 = Vref (intern) + ADC_CH18 = Vbat (intern) + + - when using channels 16/17 you need to call: myADC.enableTsVref(); + - when using channel 18 you need to call: myADC.enableVbat() + - specify the number of inputs to be sampled + - select the sampling mode (single, continuous, scan, ...) + - start acquisition. + +*/ +#include + +STM32ADC myADC(ADC1); + +// Array of analog input pins +uint8_t analog_pins[] = { PA0, PA1, PA2, PA3, PA4, PA5 }; + +//----------------------------------------------------------------------------- +void blink() +{ + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); +} + +//----------------------------------------------------------------------------- +void setup() +{ + // Declare the LED_BUILTIN's pin as an OUTPUT. + pinMode(LED_BUILTIN, OUTPUT); + // Declare the sensorPin as INPUT_ANALOG: + for (uint8_t i = 0; i + + +#define ADC_CHANNELS 4 // Channels to be sampled. + +const uint8 adcPins[ADC_CHANNELS] = {PA0, PA1, PA2, PA3}; + +#define maxSamples 200 +#define BUFF_SIZE (maxSamples*ADC_CHANNELS) + +uint16_t buffer[BUFF_SIZE]; // stores the values sampled by ADC + // make it uint32_t for dual ADC. + +uint16_t * volatile readPtr; // pointer from where to start read out the values + +#define sampleFreqHz 1000 // !!! minimum = 20 Hz !!! +#define samplePeriod ( 1000000 / sampleFreqHz ) // µs resolution + +STM32ADC myADC(ADC1); + +#define ADC_DEVICE_SINGLE 0 // use this if only one device is needed +#define ADC_DEVICE_DUAL 1 // use this to activate both ADC1 and 2 + // The DMA will store 32 bits per sample. + +#define ADC_CONVERSION_MODE_SINGLE 0 // use this for a single conversion sequence + // ADC stops after the buffer is full. +#define ADC_CONVERSION_MODE_CIRCULAR 1 // use this for continuous conversion + // ADC overwrites the buffer in circular mode. + +uint8_t secondPart; +uint8_t adcConversionMode; +//----------------------------------------------------------------------------- +void blink(uint16_t dly) +{ + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); + if (dly) delay(dly); +} +//----------------------------------------------------------------------------- +void Timer_setup(void) +{ + Serial.println("Setup Timer3"); + // setup to generate pulses for sampling + Timer3.pause(); // stop timer + Timer3.setPeriod(samplePeriod); + Timer3.setMasterMode(TIMER_MASTER_MODE_UPDATE); // update will be used as TRGO + Timer3.refresh(); // will trigger the first sample + Timer3.resume(); +} +//----------------------------------------------------------------------------- +void DMA_setup(void) +{ + Serial.println("Configure DMA"); + //myADC.setSampleTime(ADC_SMPR_144); // same as default setting = 1µsecond. + myADC.setPins(adcPins, ADC_CHANNELS); + myADC.setDMA(buffer, (maxSamples*ADC_CHANNELS), + ADC_DEVICE_SINGLE, adcConversionMode, + (DMA_FROM_PER | DMA_MINC_MODE | DMA_CIRC_MODE | DMA_TRNS_HALF | DMA_TRNS_CMPLT), + DMA_ISR); + myADC.setTrigger(ADC_EXTSEL_TIM3_TRGO); + myADC.startConversion(); +} +//----------------------------------------------------------------------------- +void DMA_ISR(void) +{ + if ( myADC.getDMAHalfFlag() ) + { + readPtr = &buffer[0]; + secondPart = 0; + } + else if ( myADC.getDMACompleteFlag() ) + { + readPtr = &buffer[maxSamples/2]; + secondPart = 1; + } + myADC.clearDMAIsrBits(); // mandatory +} +//----------------------------------------------------------------------------- +void setup() +{ + pinMode(LED_BUILTIN, OUTPUT); + + for (uint8_t i=0; i + +#define LEDON 0 +#define LEDOFF 1 + +bool adc_overrun = false; +bool awd_triggered = false; + +void overrun_handler(); +void awd_handler(); +void setADCprescaler(); +void toggle_awd(); +float temp_convert(int data); +void setup_awd(uint16_t data); + +void setup() { + + //note this turns 'on' the led, as active low is assumed + pinMode(LED_BUILTIN, OUTPUT); + Serial.begin(); // USB serial + + while(!Serial); // wait for terminal to connect + + // setup the ADC prescaler + setADCprescaler(); + // use a long sample time - measure temperature + // if we assume pclk = 84 mhz, prescaler = 4, so adcclock = 84 / 4 = 21 mhz + // from rm0009 + // Tconv = sample time + 12 cycles = 480 + 12 = 492 cycles ~ 42 k samples per sec ! + adc_set_sampling_time(ADC1, ADC_SMPR_480); + // use single mode + adc_clear_continuous(ADC1); + + //enable temp sensor + adc_enable_tsvref(); + + //setup the AWD to test threshold triggering + //in this case it is using the AWD to detect high (i.e. max) temperatures + //delay(1); + //uint16_t data = adc_read(ADC1, 18); + uint16_t data = 800; //set a low threshold so that awd would trigger + setup_awd(data); + adc_awd_enable_channel(ADC1, 18); + Serial.print("Temp (C):"); + Serial.println(temp_convert(data)); + + // attach overrun interrupt, this is for the overrun interrupt test + adc_attach_interrupt(ADC1, ADC_OVR, overrun_handler); + ADC1->regs->CR2 |= ADC_CR2_EOCS; + + // attach awd interrupt, this is for awd tests + adc_attach_interrupt(ADC1, ADC_AWD, awd_handler); + + digitalWrite(LED_BUILTIN, LEDOFF); + Serial.println("enter 'w' to toggle AWD"); + adc_awd_enable(ADC1); +} + +void loop() { + + if(Serial.available()) { + uint8_t c = Serial.read(); + if(c == 'w') + toggle_awd(); + } + + if(adc_overrun) { + Serial.println("ADC overrun!"); + digitalWrite(LED_BUILTIN, LEDON); + delay(100); + digitalWrite(LED_BUILTIN, LEDOFF); + delay(100); + adc_overrun = false; + } + + // this is the call to read adc voltages. + // uint18_t data = adc_read(ADC1, 18); + // as both awd and adc is being used, when awd triggers + // AWD is set but EOC may not be set, hence adc_read() is not used + // and we'd need to do some additional handling for AWD trigger + adc_start_single_convert(ADC1, 18); + while (!adc_is_end_of_convert(ADC1)) { + if(awd_triggered) { + //if awd is triggered we disable awd and read + //the adc again + adc_awd_disable(ADC1); + adc_start_single_convert(ADC1, 18); + } + //wait for systick, delay(1) + asm("wfi"); + } + uint16_t data = adc_get_data(ADC1); + + // uncomment next 3 statements to test overrun + //ADC1->regs->CR2 |= ADC_CR2_SWSTART; + //delay(1); + //ADC1->regs->CR2 |= ADC_CR2_SWSTART; + + if(awd_triggered) { + Serial.println("New High Temp"); + setup_awd(data); + adc_awd_enable(ADC1); + awd_triggered = false; + } + + Serial.print("Temp (C):"); + Serial.println(temp_convert(data)); + + // sleep 1-2s wait for systick, not accurate + for(int i=0; i<2000; i++) asm("wfi"); +} + +void overrun_handler() { + adc_overrun = true; +} + +void awd_handler() { + ADC1->regs->SR &= ~ ADC_SR_AWD; + awd_triggered = true; +} + +void setup_awd(uint16_t data) { + adc_awd_set_high_limit(ADC1, data); + adc_awd_set_low_limit(ADC1, 0); + ADC1->regs->SR &= ~ ADC_SR_AWD; +} + +void toggle_awd() { + uint8_t awden = bb_peri_get_bit(&(ADC1->regs->CR1), ADC_CR1_AWDEN_BIT); + if(awden) { + adc_awd_disable(ADC1); + Serial.println("AWD disabled"); + } else { + adc_awd_enable(ADC1); + Serial.println("AWD enabled"); + } + +} + +void setADCprescaler() { + // in datasheet ADC max freq, e.g. F401/F411/F405/F407/F429 + const int ADC_MAX_MHZ = 36; + + // note CLOCK_SPEED_MHZ is defined in the variant board specific .h file + // to get a 2.4 Msps speeds for each ADC a cpu clock speeds of 144 mhz or 72 mhz needs to be used + // so that a pclk2 runs at 72 mhz and adc prescaler = 2 so max adc clock = 36 mhz can be achieved + int pclk2 = CLOCK_SPEED_MHZ > 100 ? CLOCK_SPEED_MHZ / 2 : CLOCK_SPEED_MHZ; + + int prescaler_sel = 1; + // find the pre-scaler divisor that gives adc clock frequency less than or + // equal to ADC_MAX_MHZ + while( pclk2 / ( prescaler_sel * 2) > ADC_MAX_MHZ ) + prescaler_sel++; + + Serial.print("Setting ADC clock to: "); + Serial.print(pclk2 / (prescaler_sel * 2)); + Serial.println(" Mhz"); + + adc_prescaler prescaler; + switch (prescaler_sel * 2) { + case 2: + prescaler = ADC_PRE_PCLK2_DIV_2; + break; + case 4: + prescaler = ADC_PRE_PCLK2_DIV_4; + break; + case 6: + prescaler = ADC_PRE_PCLK2_DIV_6; + break; + case 8: + prescaler = ADC_PRE_PCLK2_DIV_8; + break; + default: + // we make an assumption pclk2 = 84mhz, so if 'all else fails' + // we make the adc clock run at 21 mhz + prescaler = ADC_PRE_PCLK2_DIV_4; + } + + adc_set_prescaler(prescaler); +} + + +float temp_convert(int data) { + + const float averageSlope = 2.5; // mV/°C + const float v25 = 760.0; // [mV] + + float vSense = (3300.0*data)/4096; // mV + float temperature = ((vSense-v25)/averageSlope) + 25.0; + return temperature; +} diff --git a/STM32F4/libraries/STM32F4_ADC/examples/PR784F4AdcTest/readme.md b/STM32F4/libraries/STM32F4_ADC/examples/PR784F4AdcTest/readme.md new file mode 100644 index 000000000..53b190c34 --- /dev/null +++ b/STM32F4/libraries/STM32F4_ADC/examples/PR784F4AdcTest/readme.md @@ -0,0 +1,65 @@ +## This sketch is a test for some functions added to the F4 core in adc.h and adc.c added in PR 784 + +ref: [PR 784 F4: updates in adc.h and adc.c #784](https://github.com/rogerclarkmelbourne/Arduino_STM32/pull/784) + +### How to run this sketch + +Build the sketch against the F4 libmaple core and install it on the board. The boards that should work +may include STM32F4xx( STM32F401, STM32F411, STM32F405, STM32F407, STM32F427, STM32F429) boards. + +Connect to the serial terminal and it should start printing the core temperature. +it responds to a single char command 'w' which toggles the analog watch dog on and off. + +### * ADC_PRESCALER + +The function adc_set_prescaler() has been added in adc.h, adc.c +adc.h +``` +/** + * @brief STM32F1/F4 ADC prescalers, as divisors of PCLK2. + */ +typedef enum adc_prescaler { + /** PCLK2 divided by 2 */ + ADC_PRE_PCLK2_DIV_2 = 0, + /** PCLK2 divided by 4 */ + ADC_PRE_PCLK2_DIV_4 = 1, + /** PCLK2 divided by 6 */ + ADC_PRE_PCLK2_DIV_6 = 2, + /** PCLK2 divided by 8 */ + ADC_PRE_PCLK2_DIV_8 = 3, +} adc_prescaler; + +void adc_set_prescaler(adc_prescaler pre); +``` +### How is this tested in the sketch + +The function in the sketch void ``setADCprescaler()`` selects a prescalar to get the highest +adc clocks based on the define CLOCK_SPEED_MHZ defined in the variant specific include file. + + +### * additional fixes and support for overrun interrupt and awd interrupt, added adc_awd_disable() + +Updated codes in ``adc_attach_interrupt()`` and ``adc_irq_handler()`` to support overrun interrupt and awd +(analog watch dog) interrupt. +added missing function ``adc_awd_disable()`` in adc.h, adc.c + + +### How is this tested in the sketch + +This sketch sets up an analog watch dog to test an upper threshold voltage. in this case it reads +the internal temperature sensor and triggers when a higher temperature is detected + +### How is the overrun interrupt tested in the sketch + +To test the overrun interrupt you need to uncomment the statements in ``loop()``: +``` + } + uint16_t data = adc_get_data(ADC1); + + // uncomment next 3 statements to test overrun + ADC1->regs->CR2 |= ADC_CR2_SWSTART; + delay(1); + ADC1->regs->CR2 |= ADC_CR2_SWSTART; +``` +The sketch would respond with printing a "ADC Overrun!" and blinks the led. + diff --git a/STM32F4/libraries/STM32F4_ADC/examples/SingleChannel_withDMA/SingleChannelDMA.ino b/STM32F4/libraries/STM32F4_ADC/examples/SingleChannel_withDMA/SingleChannelDMA.ino new file mode 100644 index 000000000..98aa76b53 --- /dev/null +++ b/STM32F4/libraries/STM32F4_ADC/examples/SingleChannel_withDMA/SingleChannelDMA.ino @@ -0,0 +1,152 @@ +/* + Single channel analog input stored in circular buffer example. + The sampling rate is given by timer 3 update frequency. + At each timer overflow the DMA will store the ADC value to buffer. + Data is output to serial as soon as a half (upper or lower) buffer is full. + + Usage: + - define an array of analog input pins according to the wanted channels. + Possible values: + ---------------- + ADC_CH0 = PA0 + ... + ADC_CH7 = PA7 + ADC_CH8 = PB0 + ADC_CH9 = PB1 + ADC_CH10 = PC0 + ... + ADC_CH15 = PC5 + ADC_CH16 = temperature sensor + ADC_CH17 = Vref + ADC_CH18 = Vbat + + - when using channels 16/17 you need to call: myADC.enableTsVref(); + - when using channel 18 you need to call: myADC.enableVbat() + - specify the number of inputs to be sampled + - select the sampling mode (single, continuous, scan, ...) + - start acquisition. + +*/ + +#include + + +// Channel to be sampled. +const uint8 adcPin = PA0; + +#define maxSamples 200 +uint16_t buffer[maxSamples]; // stores the values sampled by ADC + // make it uint32_t for dual ADC. +uint16_t * volatile readPtr; // pointer from where to start read out the values + +#define sampleFreqHz 1000 // !!! minimum = 20 Hz !!! +#define samplePeriod ( 1000000 / sampleFreqHz ) // µs resolution + +STM32ADC myADC(ADC1); + +#define ADC_DEVICE_SINGLE 0 // use this if only one device is needed +#define ADC_DEVICE_DUAL 1 // use this to activate both ADC1 and 2 + // The buffer will store 32 bits per sample. + +#define ADC_CONVERSION_MODE_SINGLE 0 // use this for a single conversion sequence + // ADC stops after the buffer is full. +#define ADC_CONVERSION_MODE_CIRCULAR 1 // use this for continuous conversion + // ADC overwrites the buffer in circular mode. + +uint8_t secondPart; +uint8_t adcConversionMode; +//----------------------------------------------------------------------------- +void blink(uint16_t dly) +{ + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); + if (dly) delay(dly); +} +//----------------------------------------------------------------------------- +void Timer_setup(void) +{ + Serial.println("Setup Timer3"); + // setup to generate pulses for sampling + Timer3.pause(); // stop timer + Timer3.setPeriod(samplePeriod); + Timer3.setMasterMode(TIMER_MASTER_MODE_UPDATE); // update will be used as TRGO + Timer3.refresh(); + Timer3.resume(); +} +//----------------------------------------------------------------------------- +void DMA_setup(void) +{ + Serial.println("Configure DMA"); + //myADC.setSampleTime(ADC_SMPR_144); // same as default setting = 1µsecond. + myADC.setPins(&adcPin, 1); + myADC.setDMA(buffer, maxSamples, + ADC_DEVICE_SINGLE, adcConversionMode, + (DMA_FROM_PER | DMA_MINC_MODE | DMA_CIRC_MODE | DMA_TRNS_HALF | DMA_TRNS_CMPLT), + DMA_ISR); + myADC.setTrigger(ADC_EXTSEL_TIM3_TRGO); + myADC.startConversion(); +} +//----------------------------------------------------------------------------- +void DMA_ISR(void) +{ + if ( myADC.getDMAHalfFlag() ) + { + readPtr = &buffer[0]; + secondPart = 0; + } + else if ( myADC.getDMACompleteFlag() ) + { + readPtr = &buffer[maxSamples/2]; + secondPart = 1; + } + myADC.clearDMAIsrBits(); // mandatory +} +//----------------------------------------------------------------------------- +void setup() +{ + pinMode(LED_BUILTIN, OUTPUT); + + pinMode(adcPin, INPUT_ANALOG); + + readPtr = NULL; + secondPart = 0; + // possible values: ADC_CONVERSION_MODE_SINGLE or ADC_CONVERSION_MODE_CIRCULAR + adcConversionMode = ADC_CONVERSION_MODE_CIRCULAR; + + Serial.begin(115200); + while (!Serial); delay(10); + + Serial.println("START Single channel at sample rate circular buffer example"); + + DMA_setup(); + Timer_setup(); + + Serial.println("Conversion started.\n"); +} + +//----------------------------------------------------------------------------- +void loop() +{ + if ( readPtr!=NULL ) + { + uint16_t * p = readPtr; + readPtr = NULL; // clear it here to detect overflow + // process data - send to serial + for (uint16_t i=0; i<(maxSamples/2); i++ ) + { + Serial.write('x'); Serial.print((secondPart*(maxSamples/2))+i); + Serial.print(" = "); Serial.print(*p++); + Serial.write('\n'); + } + if ( secondPart ) Serial.write('\n'); + + blink(0); + // detect overflow: pointer updated before data processing is finished + if ( readPtr!=NULL ) + { + Serial.println("*** Overflow ***"); + while(1); // halt + } + if ( secondPart && (adcConversionMode == ADC_CONVERSION_MODE_SINGLE) ) + Serial.println("Conversion finished."); + } +} diff --git a/STM32F4/libraries/STM32F4_ADC/library.properties b/STM32F4/libraries/STM32F4_ADC/library.properties new file mode 100644 index 000000000..e2a80160c --- /dev/null +++ b/STM32F4/libraries/STM32F4_ADC/library.properties @@ -0,0 +1,10 @@ +name=STM32F4ADC +version=1.0 +author=stevestrong +email= +sentence=Analog to Digital Converter library +paragraph=ADC for STM32F4 +url=www.stmduino.com +architectures=STM32F4 +maintainer=stevestrong +category=Device Control diff --git a/STM32F4/libraries/STM32F4_ADC/src/STM32F4ADC.cpp b/STM32F4/libraries/STM32F4_ADC/src/STM32F4ADC.cpp new file mode 100644 index 000000000..e950f75e3 --- /dev/null +++ b/STM32F4/libraries/STM32F4_ADC/src/STM32F4ADC.cpp @@ -0,0 +1,102 @@ +#include "STM32F4ADC.h" + +// for debug only +extern "C" void STM32ADC_PrintRegs(const adc_dev * dev, const char * p) { +// if (p) Serial.print(p); +// Serial.print("\nSR: "); Serial.print(dev->regs->SR, HEX); +// Serial.print(", CR1: "); Serial.print(dev->regs->CR1, HEX); +// Serial.print(", CR2: "); Serial.print(dev->regs->CR2, HEX); +// Serial.print(", SMPR1: "); Serial.print(dev->regs->SMPR1, HEX); +// Serial.print(", SMPR2: "); Serial.print(dev->regs->SMPR2, HEX); +// Serial.print(", CCR: "); Serial.print(ADC_COMMON->CCR, HEX); +// Serial.print(", CSR: "); Serial.println(ADC_COMMON->CSR, HEX); +} + +/* + This will read the Vcc and return something useful. + Polling is being used. +*/ +float STM32ADC::readVref() +{ + uint16_t result = adc_read(ADC1, 17); + float vref = (3300.0*result)/4096; // mV + return vref/1000; +} + +/* + This will read the internal Temperature sensor. +*/ +float STM32ADC::readTemp() +{ + uint16_t result = adc_read(ADC1, 16); + //Serial.print("Res: "); Serial.print(result); + float vSense = (3300.0*result)/4096; // mV + //Serial.print(", mV: "); Serial.print(vSense); Serial.print(", temp: "); + float temperature = ((vSense-v25)/averageSlope) + 25.0; + return temperature; +} + +/* + This function will set the number of Pins to sample and which PINS to convert. + This uses the IO port numbers and not the ADC channel numbers. Do not confuse. +*/ +void STM32ADC::setPins(const uint8 * pins, uint8 length) +{ + extern const uint8 adc_map[]; + //convert pins to channels. + uint8 channels[length]; + for (uint8 i = 0; i < length; i++) { //convert the pins to channels + uint8_t adc_chan = adc_map[i]; + if (adc_chan==0xFF) adc_chan = 0; + channels[i] = adc_chan; + } + + adc_set_reg_sequence(_dev, channels, length); + if ( length>1 ) adc_set_scan_mode(_dev); +} + +/* + This function is used to setup DMA2 with the ADC. + Used in both continuous and scan mode. +*/ +void STM32ADC::setDMA(void * buf, uint16 bufLen, uint8 dual, uint8 continous, uint32 dmaFlags, voidFuncPtr func) +{ + //initialize DMA + dma_init(DMA2); + dma_setup_transfer(DMA2, _dev->dmaStream, _dev->dmaChannel, (dual?DMA_SIZE_32BITS:DMA_SIZE_16BITS), &_dev->regs->DR, buf, NULL, dmaFlags); + dma_set_num_transfers(DMA2, _dev->dmaStream, bufLen); + dma_set_fifo_flags(DMA2, _dev->dmaStream, 0); + dma_clear_isr_bits(DMA2, _dev->dmaStream); + //if there is an int handler to be attached + if (func != NULL) + dma_attach_interrupt(DMA2, _dev->dmaStream, func); + if ( continous ) + adc_dma_continuous(_dev); + else + adc_dma_single(_dev); + + enableDMA(); +} + +/* + This will set an Analog Watchdog on a channel. + It must be used with a channel that is being converted. +*/ +void STM32ADC::setWD(uint8 channel, uint32 highLimit, uint32 lowLimit, voidFuncPtr func) +{ + adc_awd_set_low_limit(_dev, lowLimit); + adc_awd_set_high_limit(_dev, highLimit); + adc_awd_enable_channel(_dev, channel); + if ( func!=NULL ) + adc_attach_interrupt(_dev, ADC_AWD, func); + adc_awd_enable(_dev); +} + +/* + check analog watchdog + Poll the status on the watchdog. This will return and reset the bit. +*/ +uint8 STM32ADC::getWDActiveFlag() +{ + return 1; +} diff --git a/STM32F4/libraries/STM32F4_ADC/src/STM32F4ADC.h b/STM32F4/libraries/STM32F4_ADC/src/STM32F4ADC.h new file mode 100644 index 000000000..8f84a2fbc --- /dev/null +++ b/STM32F4/libraries/STM32F4_ADC/src/STM32F4ADC.h @@ -0,0 +1,174 @@ +#include +#include +#include +#include + + +class STM32ADC +{ +public: + +/* + Constructor + Choose which ADC to use. + Start it up... +*/ + STM32ADC(const adc_dev * dev) { _dev = dev; } + + uint16 readInput(uint8 pin) { return analogReadDev(pin, _dev); } + + uint32 getData() { return adc_get_data(_dev); } + + void enableTsVref(void) { adc_enable_tsvref(); } + + void enableVBAT(void) { adc_enable_vbat(); } + +/* + Set the ADC sampling time. + + ADC_SMPR_3, < 3 ADC cycles + ADC_SMPR_15, < 15 ADC cycles + ADC_SMPR_28, < 28 ADC cycles + ADC_SMPR_56, < 56 ADC cycles + ADC_SMPR_84, < 84 ADC cycles + ADC_SMPR_112, < 112 ADC cycles + ADC_SMPR_144, < 144 ADC cycles + ADC_SMPR_480, < 480 ADC cycles +*/ + void setSamplingTime(adc_smp_rate samplingTime) + { + adc_set_sampling_time(_dev, samplingTime); + } + +/* + Attach an interrupt to the ADC completion. +*/ + void attachInterrupt(voidFuncPtr func, adc_irq_id irq_id) + { + adc_attach_interrupt(_dev, irq_id, func); + } + +/* + This function is used to setup DMA with the ADC. + Used in continuous or scan mode. +*/ + void enableDMA() + { + dma_enable(DMA2, _dev->dmaStream); // enable DMA stream + adc_dma_enable(_dev); // enable ADC DMA transfer + } + void disableDMA() + { + adc_dma_disable(_dev); // disable ADC DMA transfer + dma_disable(DMA2, _dev->dmaStream); // disable DMA stream + } + + void setDMASingle() + { + adc_dma_single(_dev); // single DMA buffer + } + void setDMACircular() + { + adc_dma_continuous(_dev); // continuous DMA buffer + } + + void setDMA(void * Buf, uint16 BufLen, uint8 dual, uint8 cont, uint32 dmaFlags, voidFuncPtr func); + + uint8_t getDMAHalfFlag() { return dma_get_isr_bit(DMA2, _dev->dmaStream, DMA_ISR_HTIF); } + uint8_t getDMACompleteFlag() { return dma_get_isr_bit(DMA2, _dev->dmaStream, DMA_ISR_TCIF); } + + void clearDMAIsrBits() { dma_clear_isr_bits(DMA2, _dev->dmaStream); } + +/* + This will read the Vcc and return something useful. + Polling is being used. +*/ + float readVref(); + +/* + This will read the Temperature and return something useful. + Polling is being used. +*/ + float readTemp(); + +/* + This function will set the number of channels to convert + And which channels. + For pin numbers, see setPins below +*/ + void setChannels(uint8 * channels, uint8 length) + { + adc_set_reg_sequence(_dev, channels, length); + } + +/* + This function will specify the pins to convert. +*/ + void setPins(const uint8 * pins, uint8 length); + +/* + This function will set the trigger to start the conversion. + + ADC_EXTSEL_TIM1_CC1 + ADC_EXTSEL_TIM1_CC2 + ADC_EXTSEL_TIM1_CC3 + ADC_EXTSEL_TIM2_CC2 + ADC_EXTSEL_TIM2_CC3 + ADC_EXTSEL_TIM2_CC4 + ADC_EXTSEL_TIM2_TRGO + ADC_EXTSEL_TIM3_CC1 + ADC_EXTSEL_TIM3_TRGO + ADC_EXTSEL_TIM4_CC4 + ADC_EXTSEL_TIM5_CC1 + ADC_EXTSEL_TIM5_CC2 + ADC_EXTSEL_TIM5_CC3 + ADC_EXTSEL_TIM8_CC1 + ADC_EXTSEL_TIM8_TRGO + ADC_EXTSEL_EXTI11 +*/ + void setTrigger(adc_extsel_event trigger) + { + adc_set_extsel(_dev, trigger); + adc_set_exttrig(_dev, ADC_EXT_TRIGGER_ON_RISING_EDGE); + } + +/* + this function will set the continuous conversion bit. +*/ + void setContinuous() { adc_set_continuous(_dev); } + +/* + this function will reset the continuous bit. +*/ + void resetContinuous() { adc_clear_continuous(_dev); } + +/* + This will be used to start conversions +*/ + void startConversion() { adc_start_convert(_dev); } + +/* + This will set the Scan Mode on. + This will use DMA. +*/ + void setScanMode() { adc_set_scan_mode(_dev); } + +/* + This will set an Analog Watchdog on a channel. + It must be used with a channel that is being converted. +*/ + void setWD(uint8 channel, uint32 highLimit, uint32 lowLimit, voidFuncPtr func); + +/* + check analog watchdog + Poll the status on the watchdog. This will return and reset the bit. +*/ + uint8 getWDActiveFlag(); + + +private: + + const adc_dev * _dev; + static constexpr float averageSlope = 2.5; // mV/°C + static constexpr float v25 = 760.0; // [mV] +}; diff --git a/STM32F4/libraries/Wire/SoftWire.cpp b/STM32F4/libraries/Wire/SoftWire.cpp new file mode 100644 index 000000000..852cb0c84 --- /dev/null +++ b/STM32F4/libraries/Wire/SoftWire.cpp @@ -0,0 +1,246 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file Wire.cpp + * @author Trystan Jones + * @brief Wire library, uses the WireBase to create the primary interface + * while keeping low level interactions invisible to the user. + */ + +/* + * Library updated by crenn to follow new Wire system. + * Code was derived from the original Wire for maple code by leaflabs and the + * modifications by gke and ala42. + */ + /* + * Updated by Roger Clark. 20141111. Fixed issue when process() returned because of missing ACK (often caused by invalid device address being used), caused SCL to be left + * LOW so that in the next call to process() , the first clock pulse was not sent, because SCL was LOW when it should have been high. + */ + /* + * Updated by Brandon Green. 20172306. Implementing the repeated start functionality. + */ + +#include "SoftWire.h" + +#define I2C_WRITE 0 +#define I2C_READ 1 + +/* low level conventions: + * - SDA/SCL idle high (expected high) + * - always start with i2c_delay rather than end + */ + +void SoftWire::set_scl(bool state) { + I2C_DELAY(this->i2c_delay); + + gpio_write_bit(sclDevice,sclBit, state); +// digitalWrite(this->scl_pin,state); + //Allow for clock stretching - dangerous currently + if (state == HIGH) { + while(digitalRead(this->scl_pin) == 0); + } +} + +void SoftWire::set_sda(bool state) { + I2C_DELAY(this->i2c_delay); + gpio_write_bit(sdaDevice,sdaBit, state); + //digitalWrite(this->sda_pin, state); +} + +void SoftWire::i2c_start() { + set_sda(LOW); + set_scl(LOW); +} + +void SoftWire::i2c_stop() { + set_sda(LOW); + set_scl(HIGH); + set_sda(HIGH); +} + +void SoftWire::i2c_repeated_start() { + set_sda(HIGH); + set_scl(HIGH); + set_sda(LOW); +} + +bool SoftWire::i2c_get_ack() { + set_scl(LOW); + set_sda(HIGH); + set_scl(HIGH); + + bool ret = !digitalRead(this->sda_pin); + set_scl(LOW); + return ret; +} + +void SoftWire::i2c_send_ack() { + set_sda(LOW); + set_scl(HIGH); + set_scl(LOW); +} + +void SoftWire::i2c_send_nack() { + set_sda(HIGH); + set_scl(HIGH); + set_scl(LOW); +} + +uint8 SoftWire::i2c_shift_in() { + uint8 data = 0; + set_sda(HIGH); + + int i; + for (i = 0; i < 8; i++) { + set_scl(HIGH); + data |= digitalRead(this->sda_pin) << (7-i); + set_scl(LOW); + } + + return data; +} + +void SoftWire::i2c_shift_out(uint8 val) { + int i; + for (i = 0; i < 8; i++) { + set_sda(!!(val & (1 << (7 - i)) ) ); + set_scl(HIGH); + set_scl(LOW); + } +} + +//process needs to be updated for repeated start. +uint8 SoftWire::process(uint8 stop) { + itc_msg.xferred = 0; + + uint8 sla_addr = (itc_msg.addr << 1); + if (itc_msg.flags == I2C_MSG_READ) { + sla_addr |= I2C_READ; + } + i2c_start(); + // shift out the address we're transmitting to + i2c_shift_out(sla_addr); + if (!i2c_get_ack()) + { + i2c_stop();// Roger Clark. 20141110 added to set clock high again, as it will be left in a low state otherwise + return ENACKADDR; + } + // Recieving + if (itc_msg.flags == I2C_MSG_READ) { + while (itc_msg.xferred < itc_msg.length) { + itc_msg.data[itc_msg.xferred++] = i2c_shift_in(); + if (itc_msg.xferred < itc_msg.length) + { + i2c_send_ack(); + } + else + { + i2c_send_nack(); + } + } + } + // Sending + else { + for (uint8 i = 0; i < itc_msg.length; i++) { + i2c_shift_out(itc_msg.data[i]); + if (!i2c_get_ack()) + { + i2c_stop();// Roger Clark. 20141110 added to set clock high again, as it will be left in a low state otherwise + return ENACKTRNS; + } + itc_msg.xferred++; + } + } + if(stop == true) + i2c_stop(); + else i2c_repeated_start(); + + return SUCCESS; +} + +// For compatibility with legacy code +uint8 SoftWire::process(){ + return process(true); +} + +// TODO: Add in Error Handling if pins is out of range for other Maples +// TODO: Make delays more capable +SoftWire::SoftWire(uint8 scl, uint8 sda, uint8 delay) : i2c_delay(delay) { + this->scl_pin=scl; + this->sda_pin=sda; +} + +void SoftWire::begin(uint8 self_addr) { + tx_buf_idx = 0; + tx_buf_overflow = false; + rx_buf_idx = 0; + rx_buf_len = 0; + pinMode(this->scl_pin, OUTPUT_OPEN_DRAIN); + pinMode(this->sda_pin, OUTPUT_OPEN_DRAIN); + + sclDevice = (gpio_dev*)digitalPinToPort(this->scl_pin); + sclBit = digitalPinToBit(this->scl_pin); + sdaDevice = (gpio_dev*)digitalPinToPort(this->sda_pin); + sdaBit = digitalPinToBit(this->sda_pin); + set_scl(HIGH); + set_sda(HIGH); +} + +void SoftWire::end() +{ + if (this->scl_pin) + { + pinMode(this->scl_pin, INPUT); + } + if (this->sda_pin) + { + pinMode(this->sda_pin, INPUT); + } +} + +void SoftWire::setClock(uint32_t frequencyHz) +{ + switch(frequencyHz) + { + case 400000: + i2c_delay = SOFT_FAST; + break; + case 100000: + default: + i2c_delay = SOFT_STANDARD; + break; + } +} + +SoftWire::~SoftWire() { + this->scl_pin=0; + this->sda_pin=0; +} + +// Declare the instance that the users of the library can use +//SoftWire Wire(SCL, SDA, SOFT_STANDARD); +//SoftWire Wire(PB6, PB7, SOFT_FAST); diff --git a/STM32F4/libraries/Wire/SoftWire.h b/STM32F4/libraries/Wire/SoftWire.h new file mode 100644 index 000000000..0c3a39cd0 --- /dev/null +++ b/STM32F4/libraries/Wire/SoftWire.h @@ -0,0 +1,164 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file SoftWire.h + * @author Trystan Jones + * @brief Wire library, uses the WireBase to create the primary interface + * while keeping low level interactions invisible to the user. + */ + +/* + * Library updated by crenn to follow new Wire system. + * Code was derived from the original Wire for maple code by leaflabs and the + * modifications by gke and ala42. + */ + +#ifndef _SOFTWIRE_H_ +#define _SOFTWIRE_H_ + +#include "WireBase.h" +#include "wirish.h" + +/* + * On the Maple, let the default pins be in the same location as the Arduino + * pins + */ +#define SDA PB7 +#define SCL PB6 + +#define SOFT_STANDARD 85 +#define SOFT_FAST 15 +#define SOFT_HSPEED 0 + + +//#define I2C_DELAY(x) {uint32 time=micros(); while(time>(micros()+x));} +#define I2C_DELAY(x) do{for(int i=0;i + * @brief Wire library, uses the hardware I2C available in the Maple to + * interact with I2C slave devices. + */ + +/* + * Library created by crenn to use the new WireBase system and allow Arduino + * users easy interaction with the I2C Hardware in a familiar method. + */ + +#include "Wire.h" + +uint8 TwoWire::process(uint8 stop) { + int8 res = i2c_master_xfer(sel_hard, &itc_msg, 1, 0); + if (res == I2C_ERROR_PROTOCOL) { + if (sel_hard->error_flags & I2C_SR1_AF) { /* NACK */ + res = (sel_hard->error_flags & I2C_SR1_ADDR ? ENACKADDR : + ENACKTRNS); + } else if (sel_hard->error_flags & I2C_SR1_OVR) { /* Over/Underrun */ + res = EDATA; + } else { /* Bus or Arbitration error */ + res = EOTHER; + } + i2c_master_enable(sel_hard, (I2C_BUS_RESET | dev_flags)); + } + return res; +} + +uint8 TwoWire::process(){ + return process(true); +} + +// TODO: Add in Error Handling if devsel is out of range for other Maples +TwoWire::TwoWire(uint8 dev_sel, uint8 flags) { + if (dev_sel == 1) { + sel_hard = I2C1; + } +#if BOARD_NR_I2C>1 + else if (dev_sel == 2) { + sel_hard = I2C2; + } +#endif +#if BOARD_NR_I2C>2 + else if (dev_sel == 3) { + sel_hard = I2C3; + } +#endif + else { + ASSERT(1); + } + dev_flags = flags; +} + +TwoWire::~TwoWire() { + i2c_disable(sel_hard); + sel_hard = 0; +} + +void TwoWire::begin(void) { + i2c_master_enable(sel_hard, dev_flags); +} + +void TwoWire::end() { + i2c_disable(sel_hard); + sel_hard = 0; +} + +void TwoWire::setClock(uint32_t frequencyHz) +{ + switch(frequencyHz) + { + case 400000: + dev_flags |= I2C_FAST_MODE;// set FAST_MODE bit + break; + case 100000: + default: + dev_flags &= ~I2C_FAST_MODE;// clear FAST_MODE bit + break; + } + i2c_master_enable(sel_hard, dev_flags); +} + +TwoWire Wire(1); diff --git a/STM32F3/cores/maple/wirish/usb_serial.h b/STM32F4/libraries/Wire/Wire.h similarity index 54% rename from STM32F3/cores/maple/wirish/usb_serial.h rename to STM32F4/libraries/Wire/Wire.h index f36671b77..f8a540fa7 100644 --- a/STM32F3/cores/maple/wirish/usb_serial.h +++ b/STM32F4/libraries/Wire/Wire.h @@ -1,7 +1,7 @@ /****************************************************************************** * The MIT License * - * Copyright (c) 2010 Perry Hung. + * Copyright (c) 2010 LeafLabs LLC. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -25,43 +25,53 @@ *****************************************************************************/ /** - * @brief Wirish USB virtual serial port (SerialUSB). + * @file Wire.h + * @brief Wire library, uses the hardware I2C available in the Maple to + * interact with I2C slave devices. */ -#ifndef _WIRISH_USB_SERIAL_H_ -#define _WIRISH_USB_SERIAL_H_ - -#include -#include - -/** - * @brief Virtual serial terminal. +/* + * Library created by crenn to use the new WireBase system and allow Arduino + * users easy interaction with the I2C Hardware in a familiar method. */ -class USBSerial : public Print { -public: - USBSerial(void); - void begin(void); - void end(void); +#ifndef _HARDWIRE_H_ +#define _HARDWIRE_H_ - uint32 available(void); +#include "WireBase.h" +#include "wirish.h" +#include - uint32 read(void *buf, uint32 len); - uint8 read(void); +class TwoWire : public WireBase { +private: + i2c_dev* sel_hard; + uint8 dev_flags; +protected: + /* + * Processes the incoming I2C message defined by WireBase to the + * hardware. If an error occured, restart the I2C device. + */ + uint8 process(uint8); + uint8 process(); +public: + /* + * Check if devsel is within range and enable selected I2C interface with + * passed flags + */ + TwoWire(uint8, uint8 = 0); + + /* + * Shuts down (disables) the hardware I2C + */ + void end(); - void write(uint8); - void write(const char *str); - void write(const void*, uint32); + void setClock(uint32_t frequencyHz); + /* + * Disables the I2C device and remove the device address. + */ + ~TwoWire(); - uint8 getRTS(); - uint8 getDTR(); - uint8 isConnected(); - uint8 pending(); + void begin(void); }; - -#if BOARD_HAVE_SERIALUSB -extern USBSerial SerialUSB; -#endif - -#endif - +extern TwoWire Wire; +#endif // _HARDWIRE_H_ diff --git a/STM32F4/libraries/Wire/WireBase.cpp b/STM32F4/libraries/Wire/WireBase.cpp new file mode 100644 index 000000000..c697e0790 --- /dev/null +++ b/STM32F4/libraries/Wire/WireBase.cpp @@ -0,0 +1,165 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file WireBase.cpp + * @author Trystan Jones + * @brief Wire library, following the majority of the interface from Arduino. + * Provides a 'standard' interface to I2C (two-wire) communication for + * derived classes. + */ + +/* + * Library created by crenn to allow a system which would provide users the + * 'standardised' Arduino method for interfacing with I2C devices regardless of + * whether it is I2C hardware or emulating software. + */ + +#include "WireBase.h" +#include "wirish.h" + +void WireBase::begin(void) { + tx_buf_idx = 0; + tx_buf_overflow = false; + rx_buf_idx = 0; + rx_buf_len = 0; +} + +void WireBase::beginTransmission(uint8 slave_address) { + itc_msg.addr = slave_address; + itc_msg.data = &tx_buf[tx_buf_idx]; + itc_msg.length = 0; + itc_msg.flags = 0; +} + +void WireBase::beginTransmission(int slave_address) { + beginTransmission((uint8)slave_address); +} + +uint8 WireBase::endTransmission(bool stop) { + uint8 retVal; + if (tx_buf_overflow) { + return EDATA; + } + retVal = process(stop);// Changed so that the return value from process is returned by this function see also the return line below + tx_buf_idx = 0; + tx_buf_overflow = false; + return retVal;//SUCCESS; +} + +uint8 WireBase::endTransmission(){ + return endTransmission(true); +} + +//TODO: Add the ability to queue messages (adding a boolean to end of function +// call, allows for the Arduino style to stay while also giving the flexibility +// to bulk send +uint8 WireBase::requestFrom(uint8 address, int num_bytes) { + if (num_bytes > BUFFER_LENGTH) { + num_bytes = BUFFER_LENGTH; + } + itc_msg.addr = address; + itc_msg.flags = I2C_MSG_READ; + itc_msg.length = num_bytes; + itc_msg.data = &rx_buf[rx_buf_idx]; + process(); + rx_buf_len += itc_msg.xferred; + itc_msg.flags = 0; + return rx_buf_len; +} + +uint8 WireBase::requestFrom(int address, int numBytes) { + return WireBase::requestFrom((uint8)address, numBytes); +} + +uint8 WireBase::requestFrom(int address, int numBytes, uint8 stop) { + UNUSED(stop); + return WireBase::requestFrom((uint8)address, numBytes); +} + +uint WireBase::write(uint8 value) { + if (tx_buf_idx == BUFFER_LENGTH) { + tx_buf_overflow = true; + return 0; + } + tx_buf[tx_buf_idx++] = value; + itc_msg.length++; + return 1; +} + +uint WireBase::write(uint8* buf, int len) { + uint result = 0; + for (uint8 i = 0; i < len; i++) { + result += write(buf[i]); + } + return result; +} + +uint WireBase::write(const uint8* buf, int len) { + uint result = 0; + for (uint8 i = 0; i < len; i++) { + uint8_t v = buf[i]; + result += write(v); + } + return result; +} + + +uint WireBase::write(int value) { + return write((uint8)value); +} + +uint WireBase::write(int* buf, int len) { + return write((uint8*)buf, (uint8)len); +} + +uint WireBase::write(char* buf) { + uint8 *ptr = (uint8*)buf; + uint result = 0; + while (*ptr) { + result += write(*ptr); + ptr++; + } + return result; +} + +uint8 WireBase::available() { + return rx_buf_len - rx_buf_idx; +} + +uint8 WireBase::read() { + if (rx_buf_idx == rx_buf_len) { + rx_buf_idx = 0; + rx_buf_len = 0; + return 0; + } else if (rx_buf_idx == (rx_buf_len-1)) { + uint8 temp = rx_buf[rx_buf_idx]; + rx_buf_idx = 0; + rx_buf_len = 0; + return temp; + } + return rx_buf[rx_buf_idx++]; +} diff --git a/STM32F4/libraries/Wire/WireBase.h b/STM32F4/libraries/Wire/WireBase.h new file mode 100644 index 000000000..011c8b6da --- /dev/null +++ b/STM32F4/libraries/Wire/WireBase.h @@ -0,0 +1,150 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file WireBase.h + * @author Trystan Jones + * @brief Wire library, following the majority of the interface from Arduino. + * Provides a 'standard' interface to I2C (two-wire) communication for + * derived classes. + */ + +/* + * Library created by crenn to allow a system which would provide users the + * 'standardised' Arduino method for interfacing with I2C devices regardless of + * whether it is I2C hardware or emulating software. + */ + +#ifndef _WIREBASE_H_ +#define _WIREBASE_H_ +#define UNUSED(x) (void)x; +#include "wirish.h" +#include + +#define BUFFER_LENGTH 32 + +/* return codes from endTransmission() */ +#define SUCCESS 0 /* transmission was successful */ +#define EDATA 1 /* too much data */ +#define ENACKADDR 2 /* received nack on transmit of address */ +#define ENACKTRNS 3 /* received nack on transmit of data */ +#define EOTHER 4 /* other error */ + +class WireBase { // Abstraction is awesome! +protected: + i2c_msg itc_msg; + uint8 rx_buf[BUFFER_LENGTH]; /* receive buffer */ + uint8 rx_buf_idx; /* first unread idx in rx_buf */ + uint8 rx_buf_len; /* number of bytes read */ + + uint8 tx_buf[BUFFER_LENGTH]; /* transmit buffer */ + uint8 tx_buf_idx; // next idx available in tx_buf, -1 overflow + boolean tx_buf_overflow; + + // Force derived classes to define process function + virtual uint8 process(uint8) = 0; + virtual uint8 process() = 0; +public: + WireBase() {} + ~WireBase() {} + + /* + * Initialises the class interface + */ + // Allow derived classes to overwrite begin function + virtual void begin(void); + + /* + * Sets up the transmission message to be processed + */ + void beginTransmission(uint8); + + /* + * Allow only 8 bit addresses to be used + */ + void beginTransmission(int); + + /* + * Call the process function to process the message if the TX + * buffer has not overflowed. + */ + uint8 endTransmission(bool); + uint8 endTransmission(void); + + /* + * Request bytes from a slave device and process the request, + * storing into the receiving buffer. + */ + uint8 requestFrom(uint8, int); + + /* + * Allow only 8 bit addresses to be used when requesting bytes + */ + uint8 requestFrom(int, int); + uint8 requestFrom(int, int, uint8); + /* + * Stack up bytes to be sent when transmitting + */ + uint write(uint8); + + /* + * Stack up bytes from the array to be sent when transmitting + */ + uint write(uint8*, int); + + /* + * Stack up bytes from the array to be sent when transmitting + */ + uint write(const uint8*, int); + + /* + * Ensure that a sending data will only be 8-bit bytes + */ + uint write(int); + + /* + * Ensure that an array sending data will only be 8-bit bytes + */ + uint write(int*, int); + + /* + * Stack up bytes from a string to be sent when transmitting + */ + uint write(char*); + + /* + * Return the amount of bytes that is currently in the receiving buffer + */ + uint8 available(); + + /* + * Return the value of byte in the receiving buffer that is currently being + * pointed to + */ + uint8 read(); +}; + +#endif // _WIREBASE_H_ diff --git a/STM32F4/libraries/Wire/examples/i2c_scanner_hardwire/i2c_scanner_hardwire.ino b/STM32F4/libraries/Wire/examples/i2c_scanner_hardwire/i2c_scanner_hardwire.ino new file mode 100644 index 000000000..b62904396 --- /dev/null +++ b/STM32F4/libraries/Wire/examples/i2c_scanner_hardwire/i2c_scanner_hardwire.ino @@ -0,0 +1,81 @@ +// -------------------------------------- +// i2c_scanner +// +// Version 1 +// This program (or code that looks like it) +// can be found in many places. +// For example on the Arduino.cc forum. +// The original author is not know. +// Version 2, Juni 2012, Using Arduino 1.0.1 +// Adapted to be as simple as possible by Arduino.cc user Krodal +// Version 3, Feb 26 2013 +// V3 by louarnold +// Version 4, March 3, 2013, Using Arduino 1.0.3 +// by Arduino.cc user Krodal. +// Changes by louarnold removed. +// Scanning addresses changed from 0...127 to 1...119, +// according to the i2c scanner by Nick Gammon +// http://www.gammon.com.au/forum/?id=10896 +// Version 5, March 28, 2013 +// As version 4, but address scans now to 127. +// A sensor seems to use address 120. +// Version 6, August 1, 2015 +// Modified to support HardWire for STM32duino +// +// This sketch tests the standard 7-bit addresses +// Devices with higher bit address might not be seen properly. +// + +#include + +TwoWire HWire(1, I2C_FAST_MODE); // I2c1 +// optionally, it is possible to use the default declared Wire(1) instance with normal speed +//#define HWire Wire + +void setup() { + Serial.begin(115200); + while(!Serial); delay(1000); + HWire.begin(); + Serial.println("\nI2C Scanner"); +} + +uint32_t counter; + +void loop() { + byte error, address; + int nDevices; + + Serial.print(counter++); + Serial.println(": Scanning..."); + + nDevices = 0; + for(address = 1; address < 127; address++) { + // The i2c_scanner uses the return value of + // the Write.endTransmisstion to see if + // a device did acknowledge to the address. + + HWire.beginTransmission(address); + error = HWire.endTransmission(); + + if (error == 0) { + Serial.print("I2C device found at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.println(address, HEX); + + nDevices++; + } + else if (error == 4) { + Serial.print("Unknown error at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.println(address, HEX); + } + } + if (nDevices == 0) + Serial.println("No I2C devices found"); + else + Serial.println("done"); + + delay(5000); // wait 5 seconds for next scan +} diff --git a/STM32F4/libraries/Wire/examples/i2c_scanner_softwire/i2c_scanner_softwire.ino b/STM32F4/libraries/Wire/examples/i2c_scanner_softwire/i2c_scanner_softwire.ino new file mode 100644 index 000000000..0f61c6ce9 --- /dev/null +++ b/STM32F4/libraries/Wire/examples/i2c_scanner_softwire/i2c_scanner_softwire.ino @@ -0,0 +1,57 @@ +// -------------------------------------- +// i2c_scanner +// +// + +#include + +SoftWire SWire(PB6, PB7, SOFT_FAST); // use one of SOFT_STANDARD, SOFT_FAST or SOFT_HSPEED + + +void setup() { + Serial.begin(115200); + while(!Serial); delay(1000); + SWire.begin(); + Serial.println("\nSoftware I2C.. Scanner"); +} + +uint32_t counter; + +void loop() { + byte error, address; + int nDevices; + + Serial.print(counter++); + Serial.println(": Scanning..."); + + nDevices = 0; + for(address = 1; address < 127; address++) { + // The i2c_scanner uses the return value of + // the Write.endTransmisstion to see if + // a device did acknowledge to the address. + + SWire.beginTransmission(address); + error = SWire.endTransmission(); + + if (error == 0) { + Serial.print("I2C device found at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.println(address, HEX); + + nDevices++; + } + else if (error == 4) { + Serial.print("Unknown error at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.println(address, HEX); + } + } + if (nDevices == 0) + Serial.println("No I2C devices found"); + else + Serial.println("done"); + + delay(5000); // wait 5 seconds for next scan +} \ No newline at end of file diff --git a/STM32F4/libraries/Wire/examples/i2c_scanner_wire/i2c_scanner_wire.ino b/STM32F4/libraries/Wire/examples/i2c_scanner_wire/i2c_scanner_wire.ino new file mode 100644 index 000000000..0988ce639 --- /dev/null +++ b/STM32F4/libraries/Wire/examples/i2c_scanner_wire/i2c_scanner_wire.ino @@ -0,0 +1,77 @@ +// -------------------------------------- +// i2c_scanner +// +// Version 1 +// This program (or code that looks like it) +// can be found in many places. +// For example on the Arduino.cc forum. +// The original author is not know. +// Version 2, Juni 2012, Using Arduino 1.0.1 +// Adapted to be as simple as possible by Arduino.cc user Krodal +// Version 3, Feb 26 2013 +// V3 by louarnold +// Version 4, March 3, 2013, Using Arduino 1.0.3 +// by Arduino.cc user Krodal. +// Changes by louarnold removed. +// Scanning addresses changed from 0...127 to 1...119, +// according to the i2c scanner by Nick Gammon +// http://www.gammon.com.au/forum/?id=10896 +// Version 5, March 28, 2013 +// As version 4, but address scans now to 127. +// A sensor seems to use address 120. +// +// This sketch tests the standard 7-bit addresses +// Devices with higher bit address might not be seen properly. +// + +#include + + +void setup() { + + Serial.begin(115200); + while(!Serial); delay(1000); + Wire.begin(); + Serial.println("\nI2C Scanner"); +} + +uint32_t counter; + +void loop() { + byte error, address; + int nDevices; + + Serial.print(counter++); + Serial.println(": Scanning..."); + + nDevices = 0; + for(address = 1; address < 127; address++) { + // The i2c_scanner uses the return value of + // the Write.endTransmisstion to see if + // a device did acknowledge to the address. + + Wire.beginTransmission(address); + error = Wire.endTransmission(); + + if (error == 0) { + Serial.print("I2C device found at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.println(address, HEX); + + nDevices++; + } + else if (error == 4) { + Serial.print("Unknown error at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.println(address, HEX); + } + } + if (nDevices == 0) + Serial.println("No I2C devices found"); + else + Serial.println("done"); + + delay(5000); // wait 5 seconds for next scan +} \ No newline at end of file diff --git a/STM32F4/libraries/Wire/rules.mk b/STM32F4/libraries/Wire/rules.mk new file mode 100644 index 000000000..e16f4db93 --- /dev/null +++ b/STM32F4/libraries/Wire/rules.mk @@ -0,0 +1,29 @@ +# Standard things +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) +BUILDDIRS += $(BUILD_PATH)/$(d) + +# Local flags +CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) + +# Local rules and targets +cSRCS_$(d) := + +cppSRCS_$(d) := WireBase.cpp HardWire.cpp Wire.cpp + +cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) + +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ + $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) +DEPS_$(d) := $(OBJS_$(d):%.o=%.d) + +$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) + +TGT_BIN += $(OBJS_$(d)) + +# Standard things +-include $(DEPS_$(d)) +d := $(dirstack_$(sp)) +sp := $(basename $(sp)) \ No newline at end of file diff --git a/STM32F4/libraries/arduino_uip/utility/Enc28J60Network.h b/STM32F4/libraries/arduino_uip/utility/Enc28J60Network.h index 73a793492..ca2de5971 100644 --- a/STM32F4/libraries/arduino_uip/utility/Enc28J60Network.h +++ b/STM32F4/libraries/arduino_uip/utility/Enc28J60Network.h @@ -29,7 +29,7 @@ #include "mempool.h" -#ifdef ARDUINO_STM32F4_NETDUINO2PLUS +#ifdef BOARD_STM32F4_NETDUINO2PLUS #define ENC28J60_CONTROL_CS PC8 #else #define ENC28J60_CONTROL_CS SPI.nssPin() diff --git a/STM32F4/platform.txt b/STM32F4/platform.txt index d115210cc..8a329007e 100755 --- a/STM32F4/platform.txt +++ b/STM32F4/platform.txt @@ -3,54 +3,56 @@ # For more info: # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification -name=STM32F4 boards +name=STM32F4 Boards (Arduino_STM32) version=0.1.0 # compiler variables # ---------------------- compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/ compiler.c.cmd=arm-none-eabi-gcc -compiler.c.flags=-c -g {build.flags.optimize} -Wall -MMD -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -DBOARD_{build.variant} {build.vect_flags} -DERROR_LED_PORT={build.error_led_port} -DERROR_LED_PIN={build.error_led_pin} +compiler.c.flags=-c -g {build.flags.optimize} -Wall -MMD -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -DERROR_LED_PIN={build.error_led_pin} compiler.c.elf.cmd=arm-none-eabi-g++ compiler.c.elf.flags={build.flags.optimize} -Wl,--gc-sections {build.flags.ldspecs} compiler.S.cmd=arm-none-eabi-gcc compiler.S.flags=-c -g -x assembler-with-cpp -MMD compiler.cpp.cmd=arm-none-eabi-g++ -compiler.cpp.flags=-c -g {build.flags.optimize} -Wall -MMD -std=gnu++11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -DBOARD_{build.variant} {build.vect_flags} -DERROR_LED_PORT={build.error_led_port} -DERROR_LED_PIN={build.error_led_pin} +compiler.cpp.flags=-c -g {build.flags.optimize} -Wall -MMD -std=gnu++11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -DERROR_LED_PIN={build.error_led_pin} compiler.ar.cmd=arm-none-eabi-ar compiler.ar.flags=rcs compiler.objcopy.cmd=arm-none-eabi-objcopy compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 compiler.elf2hex.flags=-O binary compiler.elf2hex.cmd=arm-none-eabi-objcopy +compiler.elf2lst.flags=-M reg-names-std -d -C +compiler.elf2lst.cmd=arm-none-eabi-objdump compiler.ldflags={build.flags.ldspecs} compiler.size.cmd=arm-none-eabi-size -compiler.define=-DARDUINO= +compiler.define=-DARDUINO= # this can be overriden in boards.txt -build.f_cpu=168000000L build.mcu=cortex-m4 build.cpu_flags= build.hs_flag= -build.common_flags=-mthumb -D__STM32F4__ +build.common_flags=-mthumb -D__STM32F4__ -DSTM32F4 build.extra_flags= {build.cpu_flags} {build.hs_flag} {build.common_flags} +build.flags.optimize=-Os +build.flags.ldspecs= # These can be overridden in platform.local.txt compiler.c.extra_flags= -compiler.c.elf.extra_flags="-L{build.variant.path}/ld" +compiler.combine.flags=-u _printf_float -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid +#compiler.c.elf.extra_flags="-L{build.variant.path}/ld" -specs=nosys.specs -specs=nano.specs {compiler.combine.flags} +compiler.c.elf.extra_flags="-L{build.variant.path}/ld" "-Wl,--wrap=atexit,--wrap=__cxa_atexit,--wrap=exit" -specs=nano.specs compiler.cpp.extra_flags= compiler.S.extra_flags= compiler.ar.extra_flags= compiler.elf2hex.extra_flags= - -##compiler.libs.c.flags="-I{build.system.path}/libmaple" "-I{build.system.path}/libmaple/include" "-I{build.system.path}/libmaple/stm32f1/include" "-I{build.system.path}/libmaple/usb/stm32f1" "-I{build.system.path}/libmaple/usb/usb_lib" #compiler.libs.c.flags="-I{build.core.path}" "-I{build.core.path}/libmaple" "-I{build.core.path}/libmaple/usbF4" "-I{build.core.path}/libmaple/usbF4/STM32_USB_Device_Library/Core/inc" "-I{build.core.path}/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc" "-I{build.core.path}/libmaple/usbF4/STM32_USB_OTG_Driver/inc" "-I{build.core.path}/libmaple/usbF4/VCP" compiler.libs.c.flags="-I{build.system.path}/libmaple" "-I{build.core.path}/libmaple/usbF4" - # USB Flags # --------- ## build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' @@ -64,22 +66,20 @@ compiler.libs.c.flags="-I{build.system.path}/libmaple" "-I{build.core.path}/libm # --------------------- ## Compile c files -recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.cpu_flags} {build.vect_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}" +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mcpu={build.mcu} -DARDUINO={runtime.ide.version} -DVARIANT_{build.variant} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.cpu_flags} {build.vect_flags} {build.common_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}" ## Compile c++ files -recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.cpu_flags} {build.vect_flags} {build.hs_flag} {build.common_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}" +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mcpu={build.mcu} -DARDUINO={runtime.ide.version} -DVARIANT_{build.variant} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.cpu_flags} {build.vect_flags} {build.hs_flag} {build.common_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}" ## Compile S files -recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.cpu_flags} {build.vect_flags} {build.hs_flag} {build.common_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}" +recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mcpu={build.mcu} -DARDUINO={runtime.ide.version} -DVARIANT_{build.variant} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.cpu_flags} {build.vect_flags} {build.hs_flag} {build.common_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}" ## Create archives recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" ## Combine gc-sections, archives, and objects -##recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group "{build.path}/syscalls_sam3.c.o" {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group -#-Wl,--entry=__start__ -#recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} -Wl,--whole-archive "{build.path}/{archive_file}" -Wl,--no-whole-archive -Wl,--end-group +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} -Wl,--whole-archive "{archive_file_path}" -Wl,--no-whole-archive -Wl,--end-group + ## Create eeprom recipe.objcopy.eep.pattern= @@ -87,9 +87,12 @@ recipe.objcopy.eep.pattern= ## Create hex recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" +## Create assembly S file +#recipe.objcopy.lst.pattern=cmd /C "{compiler.path}{compiler.elf2lst.cmd}" {compiler.elf2lst.flags} "{build.path}/{build.project_name}.elf" > "{build.path}/{build.project_name}.lst" + ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" -recipe.size.regex=^(?:\.text|\.rodata|\.ARM.exidx)\s+([0-9]+).* +recipe.size.regex=^(?:\.text|\.data|\.rodata|\.text.align|\.ARM.exidx)\s+([0-9]+).* recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* ## Save Compiled Binary @@ -102,13 +105,13 @@ recipe.output.save_file={build.project_name}.{build.variant}.bin # Upload using Maple bootloader over DFU tools.maple_upload.cmd=maple_upload tools.maple_upload.cmd.windows=maple_upload.bat -tools.maple_upload.path={runtime.hardware.path}/tools/win +tools.maple_upload.path.windows={runtime.hardware.path}/tools/win tools.maple_upload.path.macosx={runtime.hardware.path}/tools/macosx tools.maple_upload.path.linux={runtime.hardware.path}/tools/linux tools.maple_upload.path.linux64={runtime.hardware.path}/tools/linux64 tools.maple_upload.upload.params.verbose=-d tools.maple_upload.upload.params.quiet= -tools.maple_upload.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}.bin" {upload.dfuse_addr} +tools.maple_upload.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}.bin" "{runtime.ide.path}" {upload.dfuse_addr} # Generic STM32 upload via serial to Serial Port 1 (pins PA9 and PA10) - note. Boot0 line needs to high on board reset to enable upload via serial # at the end of the upload the program is automatically run, without the board being reset @@ -122,4 +125,15 @@ tools.stlink_upload.path.linux={runtime.hardware.path}/tools/linux tools.stlink_upload.path.linux64={runtime.hardware.path}/tools/linux64 tools.stlink_upload.upload.params.verbose=-d tools.stlink_upload.upload.params.quiet= -tools.stlink_upload.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}.bin" +tools.stlink_upload.upload.pattern="{path}/{cmd}" "{build.path}/{build.project_name}.bin" + +# HID upload 2.0 (HID bootloader 2.0 This bootloader will cover the STM32F1 and STM32F4 MCUs) +tools.hid_upload.cmd=hid_upload +tools.hid_upload.cmd.windows=hid_upload.bat +tools.hid_upload.path.windows={runtime.hardware.path}/tools/win +tools.hid_upload.path.macosx={runtime.hardware.path}/tools/macosx +tools.hid_upload.path.linux={runtime.hardware.path}/tools/linux +tools.hid_upload.path.linux64={runtime.hardware.path}/tools/linux64 +tools.hid_upload.upload.params.verbose=-d +tools.hid_upload.upload.params.quiet=n +tools.hid_upload.upload.pattern="{path}/{cmd}" "{build.path}/{build.project_name}.bin" {serial.port.file} diff --git a/STM32F4/system/libmaple/Arduino.h b/STM32F4/system/libmaple/Arduino.h index d445126b0..c48b4d49a 100644 --- a/STM32F4/system/libmaple/Arduino.h +++ b/STM32F4/system/libmaple/Arduino.h @@ -28,10 +28,9 @@ #define _WIRISH_ARDUINO_H_ -#include "wirish.h" +#include "WProgram.h" + -void setup(); -void loop(); #ifdef __cplusplus extern "C"{ #endif // __cplusplus diff --git a/STM32F3/cores/maple/libmaple/flash.c b/STM32F4/variants/arch_max/arch_max.cpp similarity index 56% rename from STM32F3/cores/maple/libmaple/flash.c rename to STM32F4/variants/arch_max/arch_max.cpp index c57bbbf66..e93ae7415 100644 --- a/STM32F3/cores/maple/libmaple/flash.c +++ b/STM32F4/variants/arch_max/arch_max.cpp @@ -1,8 +1,7 @@ /****************************************************************************** * The MIT License * - * Copyright (c) 2010 Perry Hung. - * Copyright (c) 2011, 2012 LeafLabs, LLC. + * Copyright (c) 2011 LeafLabs, LLC. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -26,30 +25,40 @@ *****************************************************************************/ /** - * @file libmaple/flash.c - * @brief Flash management functions + * @file arch_max.cpp + * @author stevestrong + * @brief Arch Max 1.1 board file. */ -#include -#include +#include "arch_max.h" -/** - * @brief Set flash wait states - * - * Note that not all wait states are available on every MCU. See the - * Flash programming manual for your MCU for restrictions on the - * allowed value of wait_states for a given system clock (SYSCLK) - * frequency. - * - * @param wait_states number of wait states (one of - * FLASH_WAIT_STATE_0, FLASH_WAIT_STATE_1, - * ..., FLASH_WAIT_STATE_7). - */ -void flash_set_latency(uint32 wait_states) { - uint32 val = FLASH_BASE->ACR; +#include - val &= ~FLASH_ACR_LATENCY; - val |= wait_states; +/*****************************************************************************/ +// Alternate functions, see DocID022152 Rev 8, Table 9. +/*****************************************************************************/ +void boardInit(void) +{ + // TODO + // remap SPI1 to alternative pins - FLASH_BASE->ACR = val; + // remap I2C1 to alternative pins + return; } + +/* to be defined +const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 +}; +*/ +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] = { + PA0, PA3, PA4, PA5, PA6, PB0, PB1, PC0, +}; + +const uint8 boardUsedPins[BOARD_NR_USED_PINS] = { + BOARD_LED_PIN, //BOARD_LED2_PIN, BOARD_LED3_PIN, + BOARD_JTMS_SWDIO_PIN, BOARD_JTCK_SWCLK_PIN, + BOARD_SDIO_D0, BOARD_SDIO_D1, BOARD_SDIO_D2, BOARD_SDIO_D3, BOARD_SDIO_CLK, BOARD_SDIO_CMD, + USB_DM_PIN, USB_DP_PIN +}; + diff --git a/STM32F4/variants/arch_max/arch_max.h b/STM32F4/variants/arch_max/arch_max.h new file mode 100644 index 000000000..9a47dd93c --- /dev/null +++ b/STM32F4/variants/arch_max/arch_max.h @@ -0,0 +1,196 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file arch_max.h + * @author stevestrong + * @brief Private include file for Maple Native in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARD_ARCH_MAX_H_ +#define _BOARD_ARCH_MAX_H_ + + +#define CLOCK_SPEED_MHZ 168 + +//----------------------------------------------------------------------------- +// Board pin definitions +//----------------------------------------------------------------------------- +// Ethernet pins - may not overlap with any other pin definition !!! +//----------------------------------------------------------------------------- +#define ETH_REF_CLK PA1 // * (reserved) +#define ETH_MDIO PA2 // * +#define ETH_CRS_DV PA7 // * +#define ETH_TX_EN PB11 // * +#define ETH_TX_D0 PB12 // * +#define ETH_TX_D1 PB13 // * +#define ETH_MDC PC1 // * +#define ETH_RX_D0 PC4 // * +#define ETH_RX_D1 PC5 // * +//----------------------------------------------------------------------------- +// USB pins +#define BOARD_USB_DT_PIN PA9 // detect +#define BOARD_USB_ID_PIN PA10 +#define BOARD_USB_DM_PIN PA11 +#define BOARD_USB_DP_PIN PA12 + +#define BOARD_LED_PIN PB3 // ! BOARD_SPI1A_SCK_PIN +#define BOARD_LED2_PIN PC6 // ! BOARD_USART6_TX_PIN, DCMI_D0 +#define BOARD_LED3_PIN PC7 // ! BOARD_USART6_RX_PIN, DCMI_D1 + +#define BOARD_NR_USARTS 6 +#define BOARD_USART1_TX_PIN PB6 +#define BOARD_USART1_RX_PIN PB7 +#define BOARD_USART2_TX_PIN PD5 +#define BOARD_USART2_RX_PIN PD6 +#define BOARD_USART3_TX_PIN PD8 +#define BOARD_USART3_RX_PIN PD9 +#define BOARD_UART4_TX_PIN PC10 +#define BOARD_UART4_RX_PIN PC11 +#define BOARD_UART5_TX_PIN PC12 +#define BOARD_UART5_RX_PIN PD2 +#define BOARD_USART6_TX_PIN PC6 // ! BOARD_LED2_PIN, DCMI_D0 +#define BOARD_USART6_RX_PIN PC7 // ! BOARD_LED3_PIN, DCMI_D1 + +// I2C pins +#define BOARD_NR_I2C 1 +#define BOARD_I2C1_SCL_PIN PB8 +#define BOARD_I2C1_SDA_PIN PB9 + +// SPI pins +#define BOARD_NR_SPI 3 +#define BOARD_SPI1_NSS_PIN PA15 +#define BOARD_SPI1_SCK_PIN PB3 // ! LED +#define BOARD_SPI1_MISO_PIN PB4 +#define BOARD_SPI1_MOSI_PIN PB5 + +#define BOARD_SPI2_NSS_PIN PB9 +#define BOARD_SPI2_SCK_PIN PB10 +#define BOARD_SPI2_MISO_PIN PC2 +#define BOARD_SPI2_MOSI_PIN PC3 + +#define BOARD_SPI3_NSS_PIN PA4 +#define BOARD_SPI3_SCK_PIN PC10 // ! BOARD_SDIO_D2, BOARD_UART4_TX_PIN +#define BOARD_SPI3_MISO_PIN PC11 // ! BOARD_SDIO_D3, BOARD_UART4_RX_PIN +#define BOARD_SPI3_MOSI_PIN PC12 + +#define DEFAULT_SPI_PORT 1 // valid selections 1, 2 or 3 + +// SDIO pins +#define BOARD_SDIO_D0 PC8 +#define BOARD_SDIO_D1 PC9 +#define BOARD_SDIO_D2 PC10 +#define BOARD_SDIO_D3 PC11 +#define BOARD_SDIO_CLK PC12 +#define BOARD_SDIO_CMD PD2 + +// FSMC pins +#define FSMC_NOE PD4 +#define FSMC_NWE PD5 +#define FSMC_NE1 PD7 +#define FSMC_A16 PD11 +#define FSMC_A17 PD12 +#define FSMC_A18 PD13 +#define FSMC_D0 PD14 +#define FSMC_D1 PD15 +#define FSMC_D2 PD0 +#define FSMC_D3 PD1 +#define FSMC_D4 PE7 +#define FSMC_D5 PE8 +#define FSMC_D6 PE9 +#define FSMC_D7 PE10 +#define FSMC_D8 PE11 +#define FSMC_D9 PE12 +#define FSMC_D10 PE13 +#define FSMC_D11 PE14 +#define FSMC_D12 PE15 +#define FSMC_D13 PD8 +#define FSMC_D14 PD9 +#define FSMC_D15 PD10 + +// DCMI pins +#define DCMI_PCLK PA6 +#define DCMI_HSYNC PA4 // PA4/PH8 +#define DCMI_VSYNC PB7 // PB7/PI5 +#define DCMI_D0 PC6 // PA9/PC6/PH9 +#define DCMI_D1 PC7 // PA10/PC7/PH10 +#define DCMI_D2 PC8 // PC8/PE0/PH11 +#define DCMI_D3 PC9 // PC9/PE1/PH12 +#define DCMI_D4 PE4 // PC11/PE4/PH14 +#define DCMI_D5 PB6 // PB6/PI4 +#define DCMI_D6 PE5 // PB8/PE5/PI6 +#define DCMI_D7 PE6 // PB9/PE6/PI7 +#define DCMI_D8 PC10 // PC10/PI1 +#define DCMI_D9 PC12 // PC12/PI2 +#define DCMI_D10 PB5 // PB5/PI3 +#define DCMI_D11 PD2 // PD2/PH15 + +// JTAG/SWD pins +#define BOARD_JTMS_SWDIO_PIN PA13 +#define BOARD_JTCK_SWCLK_PIN PA14 +//#define BOARD_JTDI_PIN PA15 +//#define BOARD_JTDO_PIN PB3 +//#define BOARD_NJTRST_PIN PB4 + +#define BOARD_NR_PWM_PINS 24 +#define BOARD_NR_ADC_PINS 8 +#define BOARD_NR_USED_PINS 40 +/*****************************************************************************/ +// Pins reserved for the on-board hardware +#define USB_DM_PIN BOARD_USB_DM_PIN // PA11 +#define USB_DP_PIN BOARD_USB_DP_PIN // PA12 + +// SD card, SDIO mode +//#define SD_DAT0 BOARD_SDIO_D0 // PC8 +//#define SD_DAT1 BOARD_SDIO_D1 // PC9 +//#define SD_DAT2 BOARD_SDIO_D2 // PC10 +//#define SD_DAT3 BOARD_SDIO_D3 // PC11 +//#define SD_CLK BOARD_SDIO_CK // PC12 +//#define SD_CMD BOARD_SDIO_CMD // PD2 +// SD card, only usable in SPI mode +#define SD_CS PE2 +#define SD_SCLK BOARD_SPI2_SCK_PIN // PC8 +#define SD_DO BOARD_SPI2_MISO_PIN // PC11 +#define SD_DI BOARD_SPI2_MOSI_PIN // PC12 + +/*****************************************************************************/ + +enum { +PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PA8,PA9,PA10,PA11,PA12,PA13,PA14,PA15, +PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15, +PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PC8,PC9,PC10,PC11,PC12,PC13,PC14,PC15, +PD0,PD1,PD2,PD3,PD4,PD5,PD6,PD7,PD8,PD9,PD10,PD11,PD12,PD13,PD14,PD15, +PE0,PE1,PE2,PE3,PE4,PE5,PE6,PE7,PE8,PE9,PE10,PE11,PE12,PE13,PE14,PE15, +#ifdef PACKAGE_LQFP144 +PF0,PF1,PF2,PF3,PF4,PF5,PF6,PF7,PF8,PF9,PF10,PF11,PF12,PF13,PF14,PF15, +PG0,PG1,PG2,PG3,PG4,PG5,PG6,PG7,PG8,PG9,PG10,PG11,PG12,PG13,PG14,PG15, +#endif +BOARD_NR_GPIO_PINS +}; + +#endif // _BOARD_ARCH_MAX_H_ diff --git a/STM32F4/variants/arch_max/ld/bootloader_8004000.ld b/STM32F4/variants/arch_max/ld/bootloader_8004000.ld new file mode 100644 index 000000000..40386248f --- /dev/null +++ b/STM32F4/variants/arch_max/ld/bootloader_8004000.ld @@ -0,0 +1,22 @@ +/* + * STM32F4xx high density linker script for + * JTAG (bare metal, no bootloader) builds. + */ + +MEMORY +{ + ccmram (rw): ORIGIN = 0x10000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K + rom (rx) : ORIGIN = 0x08004000, LENGTH = 496K +} + +/* GROUP(libcs3_stm32_high_density.a) */ + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); +REGION_ALIAS("REGION_CCMRAM", ccmram); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/STM32F4/variants/arch_max/ld/common.inc b/STM32F4/variants/arch_max/ld/common.inc new file mode 100644 index 000000000..acaeb3dc6 --- /dev/null +++ b/STM32F4/variants/arch_max/ld/common.inc @@ -0,0 +1,237 @@ +/* + * Linker script for libmaple. + * + * Original author "lanchon" from ST forums, with modifications by LeafLabs. + */ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* + * Configure other libraries we want in the link. + * + * libgcc, libc, and libm are common across supported toolchains. + * However, some toolchains require additional archives which aren't + * present everywhere (e.g. ARM's gcc-arm-embedded releases). + * + * To hack around this, we let the build system specify additional + * archives by putting the right extra_libs.inc (in a directory under + * toolchains/) in our search path. + */ +GROUP(libgcc.a libc.a libm.a) +INCLUDE extra_libs.inc + +/* + * These force the linker to search for vector table symbols. + * + * These symbols vary by STM32 family (and also within families). + * It's up to the build system to configure the link's search path + * properly for the target MCU. + */ +INCLUDE vector_symbols.inc + +/* STM32 vector table. */ +EXTERN(__stm32_vector_table) + +/* C runtime initialization function. */ +EXTERN(start_c) + +/* main entry point */ +EXTERN(main) + +/* Initial stack pointer value. Relocated to CCMRAM */ +EXTERN(__msp_init) +PROVIDE(__msp_init = ORIGIN(ccmram) + LENGTH(ccmram)); + +/* Reset vector and chip reset entry point */ +EXTERN(__start__) +ENTRY(__start__) +PROVIDE(__exc_reset = __start__); + +/* Heap boundaries, for libmaple */ +EXTERN(_lm_heap_start); +EXTERN(_lm_heap_end); + +SECTIONS +{ + .text : + { + __text_start__ = .; + /* + * STM32 vector table. Leave this here. Yes, really. + */ + *(.stm32.interrupt_vector) + + /* + * Program code and vague linking + */ + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(0x4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > REGION_TEXT + + /* + * End of text + */ + .text.align : + { + . = ALIGN(8); + __text_end__ = .; + } > REGION_TEXT + + /* + * .ARM.exidx exception unwinding; mandated by ARM's C++ ABI + */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > REGION_RODATA + __exidx_end = .; + + /* + * Read-only data + */ + .rodata : + { + *(.rodata .rodata.* .gnu.linkonce.r.*) + /* .USER_FLASH: We allow users to allocate into Flash here */ + *(.USER_FLASH) + /* ROM image configuration; for C startup */ + . = ALIGN(4); + _lm_rom_img_cfgp = .; + LONG(LOADADDR(.data)); + LONG(LOADADDR(.ccmdata)); + /* + * Heap: Linker scripts may choose a custom heap by overriding + * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in + * internal SRAM, beginning after .bss, and growing towards + * the stack. + * + * I'm shoving these here naively; there's probably a cleaner way + * to go about this. [mbolivar] + */ + _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : __ccmdata_end__; + _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init; + } > REGION_RODATA + + /* + * .data + */ + .data : + { + . = ALIGN(8); + __data_start__ = .; + + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + + . = ALIGN(8); + __data_end__ = .; + } > REGION_DATA AT> REGION_RODATA + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * The startup code is modified to copy the init-values from flash to ccmram + * at startup + */ + .ccmdata : + { + . = ALIGN(4); + __ccmdata_start__ = .; /* create a global symbol at ccmram start */ + *(.ccmdata) + *(.ccmram*) + + . = ALIGN(4); + __ccmdata_end__ = .; /* create a global symbol at ccmram end */ + } >REGION_CCMRAM AT> REGION_RODATA + + /* + * .bss + */ + .bss : + { + . = ALIGN(8); + __bss_start__ = .; + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = __bss_end__; + } > REGION_BSS + + /* + * Debugging sections + */ + .stab 0 (NOLOAD) : { *(.stab) } + .stabstr 0 (NOLOAD) : { *(.stabstr) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/STM32F4/variants/arch_max/ld/extra_libs.inc b/STM32F4/variants/arch_max/ld/extra_libs.inc new file mode 100644 index 000000000..dd2c84fa4 --- /dev/null +++ b/STM32F4/variants/arch_max/ld/extra_libs.inc @@ -0,0 +1,7 @@ +/* + * Extra archives needed by ARM's GCC ARM Embedded arm-none-eabi- + * releases (https://launchpad.net/gcc-arm-embedded/). + */ + +/* This is for the provided newlib. */ +GROUP(libnosys.a) diff --git a/STM32F4/variants/arch_max/ld/flash.ld b/STM32F4/variants/arch_max/ld/flash.ld new file mode 100644 index 000000000..c753a786c --- /dev/null +++ b/STM32F4/variants/arch_max/ld/flash.ld @@ -0,0 +1,20 @@ +/* + * Discovery F4 (STM32F407VGT6, high density) linker script for + * Flash builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 125K + rom (rx) : ORIGIN = 0x08010000, LENGTH = 960K /* ala42 */ +} + +/* GROUP(libcs4_stm32_high_density.a) */ + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/STM32F4/variants/arch_max/ld/jtag.ld b/STM32F4/variants/arch_max/ld/jtag.ld new file mode 100644 index 000000000..891e06069 --- /dev/null +++ b/STM32F4/variants/arch_max/ld/jtag.ld @@ -0,0 +1,22 @@ +/* + * STM32F4xx high density linker script for + * JTAG (bare metal, no bootloader) builds. + */ + +MEMORY +{ + ccmram (rw): ORIGIN = 0x10000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +/* GROUP(libcs3_stm32_high_density.a) */ + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); +REGION_ALIAS("REGION_CCMRAM", ccmram); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/STM32F4/variants/arch_max/ld/ram.ld b/STM32F4/variants/arch_max/ld/ram.ld new file mode 100644 index 000000000..b57060c92 --- /dev/null +++ b/STM32F4/variants/arch_max/ld/ram.ld @@ -0,0 +1,19 @@ +/* + * aeroquad32 (STM32F103VET6, high density) linker script for + * RAM builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + rom (rx) : ORIGIN = 0x08010000, LENGTH = 0K /* ala42 */ +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +INCLUDE common.inc diff --git a/STM32F3/variants/discovery_f3/ld/names.inc b/STM32F4/variants/arch_max/ld/vector_symbols.inc similarity index 56% rename from STM32F3/variants/discovery_f3/ld/names.inc rename to STM32F4/variants/arch_max/ld/vector_symbols.inc index 6d7ff6e94..853c4f50b 100644 --- a/STM32F3/variants/discovery_f3/ld/names.inc +++ b/STM32F4/variants/arch_max/ld/vector_symbols.inc @@ -1,5 +1,5 @@ -EXTERN(__cs3_stack) -EXTERN(__cs3_reset) +EXTERN(__msp_init) +EXTERN(__exc_reset) EXTERN(__exc_nmi) EXTERN(__exc_hardfault) EXTERN(__exc_memmanage) @@ -26,18 +26,18 @@ EXTERN(__irq_exti1) EXTERN(__irq_exti2) EXTERN(__irq_exti3) EXTERN(__irq_exti4) -EXTERN(__irq_dma1_channel1) -EXTERN(__irq_dma1_channel2) -EXTERN(__irq_dma1_channel3) -EXTERN(__irq_dma1_channel4) -EXTERN(__irq_dma1_channel5) -EXTERN(__irq_dma1_channel6) -EXTERN(__irq_dma1_channel7) +EXTERN(__irq_dma1_stream0) +EXTERN(__irq_dma1_stream1) +EXTERN(__irq_dma1_stream2) +EXTERN(__irq_dma1_stream3) +EXTERN(__irq_dma1_stream4) +EXTERN(__irq_dma1_stream5) +EXTERN(__irq_dma1_stream6) EXTERN(__irq_adc) -EXTERN(__irq_usb_hp_can_tx) -EXTERN(__irq_usb_lp_can_rx0) -EXTERN(__irq_can_rx1) -EXTERN(__irq_can_sce) +EXTERN(__irq_can1_tx) +EXTERN(__irq_can1_rx0) +EXTERN(__irq_can1_rx1) +EXTERN(__irq_can1_sce) EXTERN(__irq_exti9_5) EXTERN(__irq_tim1_brk) EXTERN(__irq_tim1_up) @@ -58,21 +58,42 @@ EXTERN(__irq_usart3) EXTERN(__irq_exti15_10) EXTERN(__irq_rtcalarm) EXTERN(__irq_usbwakeup) - EXTERN(__irq_tim8_brk) EXTERN(__irq_tim8_up) EXTERN(__irq_tim8_trg_com) EXTERN(__irq_tim8_cc) -EXTERN(__irq_adc3) +EXTERN(__irq_dma1_stream7) EXTERN(__irq_fsmc) EXTERN(__irq_sdio) EXTERN(__irq_tim5) EXTERN(__irq_spi3) EXTERN(__irq_uart4) EXTERN(__irq_uart5) -EXTERN(__irq_tim6) +EXTERN(__irq_tim6_dac) EXTERN(__irq_tim7) -EXTERN(__irq_dma2_channel1) -EXTERN(__irq_dma2_channel2) -EXTERN(__irq_dma2_channel3) -EXTERN(__irq_dma2_channel4_5) +EXTERN(__irq_dma2_stream0) +EXTERN(__irq_dma2_stream1) +EXTERN(__irq_dma2_stream2) +EXTERN(__irq_dma2_stream3) +EXTERN(__irq_dma2_stream4) +EXTERN(__irq_eth) +EXTERN(__irq_eth_wkup) +EXTERN(__irq_can2_tx) +EXTERN(__irq_can2_rx0) +EXTERN(__irq_can2_rx1) +EXTERN(__irq_can2_sce) +EXTERN(__irq_usb_fs) +EXTERN(__irq_dma2_stream5) +EXTERN(__irq_dma2_stream6) +EXTERN(__irq_dma2_stream7) +EXTERN(__irq_usart6) +EXTERN(__irq_i2c3_ev) +EXTERN(__irq_i2c3_er) +EXTERN(__irq_usb_hs_ep1_out) +EXTERN(__irq_usb_hs_ep1_in) +EXTERN(__irq_usb_hs_wkup) +EXTERN(__irq_usb_hs) +EXTERN(__irq_dcmi) +EXTERN(__irq_cryp) +EXTERN(__irq_hash_rng) +EXTERN(__irq_fpu) diff --git a/STM32F4/variants/arch_max/pins_arduino.h b/STM32F4/variants/arch_max/pins_arduino.h new file mode 100644 index 000000000..3052f2eb2 --- /dev/null +++ b/STM32F4/variants/arch_max/pins_arduino.h @@ -0,0 +1,6 @@ + + + + +// API compatibility +#include "variant.h" \ No newline at end of file diff --git a/STM32F4/variants/arch_max/variant.h b/STM32F4/variants/arch_max/variant.h new file mode 100644 index 000000000..081f85cf2 --- /dev/null +++ b/STM32F4/variants/arch_max/variant.h @@ -0,0 +1,12 @@ +// variant.h + +#ifndef _VARIANT_ARDUINO_STM32_ +#define _VARIANT_ARDUINO_STM32_ + +static const uint8_t SS = BOARD_SPI1_NSS_PIN; +static const uint8_t SS1 = BOARD_SPI2_NSS_PIN; +static const uint8_t MOSI = BOARD_SPI1_MOSI_PIN; +static const uint8_t MISO = BOARD_SPI1_MISO_PIN; +static const uint8_t SCK = BOARD_SPI1_SCK_PIN; + +#endif /* _VARIANT_ARDUINO_STM32_ */ \ No newline at end of file diff --git a/STM32F3/cores/maple/libmaple/include/libmaple/delay.h b/STM32F4/variants/blackpill_f401/blackpill_f401.cpp similarity index 61% rename from STM32F3/cores/maple/libmaple/include/libmaple/delay.h rename to STM32F4/variants/blackpill_f401/blackpill_f401.cpp index 472a208aa..2e7c7062c 100644 --- a/STM32F3/cores/maple/libmaple/include/libmaple/delay.h +++ b/STM32F4/variants/blackpill_f401/blackpill_f401.cpp @@ -1,7 +1,6 @@ /****************************************************************************** * The MIT License * - * Copyright (c) 2010 Perry Hung. * Copyright (c) 2011 LeafLabs, LLC. * * Permission is hereby granted, free of charge, to any person @@ -26,40 +25,36 @@ *****************************************************************************/ /** - * @file libmaple/include/libmaple/delay.h - * @brief Delay implementation + * @file blackpill_f401.cpp + * @author stevestrong + * @brief blackpill_f401 board file. */ -#ifndef _LIBMAPLE_DELAY_H_ -#define _LIBMAPLE_DELAY_H_ +#include "blackpill_f401.h" -#ifdef __cplusplus -extern "C" { -#endif +#include +#include #include -#include -/** - * @brief Delay the given number of microseconds. - * - * @param us Number of microseconds to delay. - */ -static inline void delay_us(uint32 us) { - us *= STM32_DELAY_US_MULT; - /* fudge for function call overhead */ - us--; - asm volatile(" mov r0, %[us] \n\t" - "1: subs r0, #1 \n\t" - " bhi 1b \n\t" - : - : [us] "r" (us) - : "r0"); +void boardInit(void) +{ } -#ifdef __cplusplus -} -#endif -#endif +//extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { +// 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 +//}; +// +//extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { +// 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 32, 33, 34, 35, 36, 37 +//}; +// +//extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { +// BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, +// BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN, +// 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 78, 79, 81, +// 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 +//}; + diff --git a/STM32F4/variants/blackpill_f401/blackpill_f401.h b/STM32F4/variants/blackpill_f401/blackpill_f401.h new file mode 100644 index 000000000..87e28c9f5 --- /dev/null +++ b/STM32F4/variants/blackpill_f401/blackpill_f401.h @@ -0,0 +1,96 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file blackpill_f401.h + * @author stevestrong + * @brief Private include file + */ + +#ifndef _BOARD_BLACKPILL_F401_H_ +#define _BOARD_BLACKPILL_F401_H_ + + +//#define Port2Pin(port, bit) ((port-'A')*16+bit) + +#define CLOCK_SPEED_MHZ 84 + + +#define BOARD_LED_PIN PC13 + +#define BOARD_USB_DM_PIN PA11 +#define BOARD_USB_DP_PIN PA12 + +#define BOARD_NR_USARTS 3 +#define BOARD_USART1_TX_PIN PA9 +#define BOARD_USART1_RX_PIN PA10 +#define BOARD_USART2_TX_PIN PA2 +#define BOARD_USART2_RX_PIN PA3 +//#define BOARD_USART6_TX_PIN PA11 // USB_DM +//#define BOARD_USART6_RX_PIN PA12 // USB_DP + +#define BOARD_NR_I2C 3 +#define BOARD_I2C1_SCL_PIN PB6 +#define BOARD_I2C1_SDA_PIN PB7 +#define BOARD_I2C1A_SCL_PIN PB8 +#define BOARD_I2C1A_SDA_PIN PB9 +#define BOARD_I2C2_SCL_PIN PB10 +#define BOARD_I2C2_SDA_PIN PB3 +#define BOARD_I2C3_SCL_PIN PA8 +#define BOARD_I2C3_SDA_PIN PB4 + +#define BOARD_NR_SPI 3 +#define BOARD_SPI1_NSS_PIN PA4 +#define BOARD_SPI1_SCK_PIN PA5 +#define BOARD_SPI1_MISO_PIN PA6 +#define BOARD_SPI1_MOSI_PIN PA7 + +#define BOARD_SPI2_NSS_PIN PB12 +#define BOARD_SPI2_SCK_PIN PB13 +#define BOARD_SPI2_MISO_PIN PB14 +#define BOARD_SPI2_MOSI_PIN PB15 + +#define BOARD_SPI3_NSS_PIN PA15 +#define BOARD_SPI3_SCK_PIN PB3 +#define BOARD_SPI3_MISO_PIN PB4 +#define BOARD_SPI3_MOSI_PIN PB5 + +//#define BOARD_NR_GPIO_PINS 32 +#define BOARD_NR_PWM_PINS 22 +#define BOARD_NR_ADC_PINS 16 +#define BOARD_NR_USED_PINS 43 // ala42 not set yet +#define BOARD_JTMS_SWDIO_PIN PA13 +#define BOARD_JTCK_SWCLK_PIN PA14 + + +enum { +PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PA8,PA9,PA10,PA11,PA12,PA13,PA14,PA15, +PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB12=(PB10+2),PB13,PB14,PB15, +PC13=(32+13),PC14,PC15, +BOARD_NR_GPIO_PINS +}; + +#endif diff --git a/STM32F4/variants/blackpill_f401/ld/common.inc b/STM32F4/variants/blackpill_f401/ld/common.inc new file mode 100644 index 000000000..b73266e8c --- /dev/null +++ b/STM32F4/variants/blackpill_f401/ld/common.inc @@ -0,0 +1,219 @@ +/* + * Linker script for libmaple. + * + * Original author "lanchon" from ST forums, with modifications by LeafLabs. + */ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* + * Configure other libraries we want in the link. + * + * libgcc, libc, and libm are common across supported toolchains. + * However, some toolchains require additional archives which aren't + * present everywhere (e.g. ARM's gcc-arm-embedded releases). + * + * To hack around this, we let the build system specify additional + * archives by putting the right extra_libs.inc (in a directory under + * toolchains/) in our search path. + */ +GROUP(libgcc.a libc.a libm.a) +INCLUDE extra_libs.inc + +/* + * These force the linker to search for vector table symbols. + * + * These symbols vary by STM32 family (and also within families). + * It's up to the build system to configure the link's search path + * properly for the target MCU. + */ +INCLUDE vector_symbols.inc + +/* STM32 vector table. */ +EXTERN(__stm32_vector_table) + +/* C runtime initialization function. */ +EXTERN(start_c) + +/* main entry point */ +EXTERN(main) + +/* Initial stack pointer value. Relocated to RAM */ +EXTERN(__msp_init) +PROVIDE(__msp_init = ORIGIN(ram) + LENGTH(ram)); + +/* Reset vector and chip reset entry point */ +EXTERN(__start__) +ENTRY(__start__) +PROVIDE(__exc_reset = __start__); + +/* Heap boundaries, for libmaple */ +EXTERN(_lm_heap_start); +EXTERN(_lm_heap_end); + +SECTIONS +{ + .text : + { + __text_start__ = .; + /* + * STM32 vector table. Leave this here. Yes, really. + */ + *(.stm32.interrupt_vector) + + /* + * Program code and vague linking + */ + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(0x4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > REGION_TEXT + + /* + * End of text + */ + .text.align : + { + . = ALIGN(8); + __text_end__ = .; + } > REGION_TEXT + + /* + * .ARM.exidx exception unwinding; mandated by ARM's C++ ABI + */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > REGION_RODATA + __exidx_end = .; + + /* + * Read-only data + */ + .rodata : + { + *(.rodata .rodata.* .gnu.linkonce.r.*) + /* .USER_FLASH: We allow users to allocate into Flash here */ + *(.USER_FLASH) + /* ROM image configuration; for C startup */ + . = ALIGN(4); + _lm_rom_img_cfgp = .; + LONG(LOADADDR(.data)); + /* + * Heap: Linker scripts may choose a custom heap by overriding + * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in + * internal SRAM, beginning after .bss, and growing towards + * the stack. + * + * I'm shoving these here naively; there's probably a cleaner way + * to go about this. [mbolivar] + */ + _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : __bss_end__; + _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init; + } > REGION_RODATA + + /* + * .data + */ + .data : + { + . = ALIGN(8); + __data_start__ = .; + + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + + . = ALIGN(8); + __data_end__ = .; + } > REGION_DATA AT> REGION_RODATA + + /* + * .bss + */ + .bss : + { + . = ALIGN(8); + __bss_start__ = .; + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = __bss_end__; + } > REGION_BSS + + /* + * Debugging sections + */ + .stab 0 (NOLOAD) : { *(.stab) } + .stabstr 0 (NOLOAD) : { *(.stabstr) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/STM32F4/variants/blackpill_f401/ld/extra_libs.inc b/STM32F4/variants/blackpill_f401/ld/extra_libs.inc new file mode 100644 index 000000000..dd2c84fa4 --- /dev/null +++ b/STM32F4/variants/blackpill_f401/ld/extra_libs.inc @@ -0,0 +1,7 @@ +/* + * Extra archives needed by ARM's GCC ARM Embedded arm-none-eabi- + * releases (https://launchpad.net/gcc-arm-embedded/). + */ + +/* This is for the provided newlib. */ +GROUP(libnosys.a) diff --git a/STM32F4/variants/blackpill_f401/ld/jtag.ld b/STM32F4/variants/blackpill_f401/ld/jtag.ld new file mode 100644 index 000000000..10672cab6 --- /dev/null +++ b/STM32F4/variants/blackpill_f401/ld/jtag.ld @@ -0,0 +1,19 @@ +/* + * STM32F401 linker script for JTAG (bare metal, no bootloader) builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K +} + +/* GROUP(libcs3_stm32_high_density.a) */ + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/STM32F4/variants/generic_f407v/ld/names.inc b/STM32F4/variants/blackpill_f401/ld/vector_symbols.inc similarity index 56% rename from STM32F4/variants/generic_f407v/ld/names.inc rename to STM32F4/variants/blackpill_f401/ld/vector_symbols.inc index 6d7ff6e94..853c4f50b 100644 --- a/STM32F4/variants/generic_f407v/ld/names.inc +++ b/STM32F4/variants/blackpill_f401/ld/vector_symbols.inc @@ -1,5 +1,5 @@ -EXTERN(__cs3_stack) -EXTERN(__cs3_reset) +EXTERN(__msp_init) +EXTERN(__exc_reset) EXTERN(__exc_nmi) EXTERN(__exc_hardfault) EXTERN(__exc_memmanage) @@ -26,18 +26,18 @@ EXTERN(__irq_exti1) EXTERN(__irq_exti2) EXTERN(__irq_exti3) EXTERN(__irq_exti4) -EXTERN(__irq_dma1_channel1) -EXTERN(__irq_dma1_channel2) -EXTERN(__irq_dma1_channel3) -EXTERN(__irq_dma1_channel4) -EXTERN(__irq_dma1_channel5) -EXTERN(__irq_dma1_channel6) -EXTERN(__irq_dma1_channel7) +EXTERN(__irq_dma1_stream0) +EXTERN(__irq_dma1_stream1) +EXTERN(__irq_dma1_stream2) +EXTERN(__irq_dma1_stream3) +EXTERN(__irq_dma1_stream4) +EXTERN(__irq_dma1_stream5) +EXTERN(__irq_dma1_stream6) EXTERN(__irq_adc) -EXTERN(__irq_usb_hp_can_tx) -EXTERN(__irq_usb_lp_can_rx0) -EXTERN(__irq_can_rx1) -EXTERN(__irq_can_sce) +EXTERN(__irq_can1_tx) +EXTERN(__irq_can1_rx0) +EXTERN(__irq_can1_rx1) +EXTERN(__irq_can1_sce) EXTERN(__irq_exti9_5) EXTERN(__irq_tim1_brk) EXTERN(__irq_tim1_up) @@ -58,21 +58,42 @@ EXTERN(__irq_usart3) EXTERN(__irq_exti15_10) EXTERN(__irq_rtcalarm) EXTERN(__irq_usbwakeup) - EXTERN(__irq_tim8_brk) EXTERN(__irq_tim8_up) EXTERN(__irq_tim8_trg_com) EXTERN(__irq_tim8_cc) -EXTERN(__irq_adc3) +EXTERN(__irq_dma1_stream7) EXTERN(__irq_fsmc) EXTERN(__irq_sdio) EXTERN(__irq_tim5) EXTERN(__irq_spi3) EXTERN(__irq_uart4) EXTERN(__irq_uart5) -EXTERN(__irq_tim6) +EXTERN(__irq_tim6_dac) EXTERN(__irq_tim7) -EXTERN(__irq_dma2_channel1) -EXTERN(__irq_dma2_channel2) -EXTERN(__irq_dma2_channel3) -EXTERN(__irq_dma2_channel4_5) +EXTERN(__irq_dma2_stream0) +EXTERN(__irq_dma2_stream1) +EXTERN(__irq_dma2_stream2) +EXTERN(__irq_dma2_stream3) +EXTERN(__irq_dma2_stream4) +EXTERN(__irq_eth) +EXTERN(__irq_eth_wkup) +EXTERN(__irq_can2_tx) +EXTERN(__irq_can2_rx0) +EXTERN(__irq_can2_rx1) +EXTERN(__irq_can2_sce) +EXTERN(__irq_usb_fs) +EXTERN(__irq_dma2_stream5) +EXTERN(__irq_dma2_stream6) +EXTERN(__irq_dma2_stream7) +EXTERN(__irq_usart6) +EXTERN(__irq_i2c3_ev) +EXTERN(__irq_i2c3_er) +EXTERN(__irq_usb_hs_ep1_out) +EXTERN(__irq_usb_hs_ep1_in) +EXTERN(__irq_usb_hs_wkup) +EXTERN(__irq_usb_hs) +EXTERN(__irq_dcmi) +EXTERN(__irq_cryp) +EXTERN(__irq_hash_rng) +EXTERN(__irq_fpu) diff --git a/STM32F4/variants/blackpill_f401/pins_arduino.h b/STM32F4/variants/blackpill_f401/pins_arduino.h new file mode 100644 index 000000000..3052f2eb2 --- /dev/null +++ b/STM32F4/variants/blackpill_f401/pins_arduino.h @@ -0,0 +1,6 @@ + + + + +// API compatibility +#include "variant.h" \ No newline at end of file diff --git a/STM32F4/variants/blackpill_f401/variant.h b/STM32F4/variants/blackpill_f401/variant.h new file mode 100644 index 000000000..74719a979 --- /dev/null +++ b/STM32F4/variants/blackpill_f401/variant.h @@ -0,0 +1,10 @@ +#ifndef _VARIANT_ARDUINO_STM32_ +#define _VARIANT_ARDUINO_STM32_ + +static const uint8_t SS = BOARD_SPI1_NSS_PIN; +static const uint8_t SS1 = BOARD_SPI2_NSS_PIN; +static const uint8_t MOSI = BOARD_SPI1_MOSI_PIN; +static const uint8_t MISO = BOARD_SPI1_MISO_PIN; +static const uint8_t SCK = BOARD_SPI1_SCK_PIN; + +#endif /* _VARIANT_ARDUINO_STM32_ */ \ No newline at end of file diff --git a/STM32F3/cores/maple/wirish/wirish_debug.h b/STM32F4/variants/blackpill_f411/blackpill_f411.cpp similarity index 59% rename from STM32F3/cores/maple/wirish/wirish_debug.h rename to STM32F4/variants/blackpill_f411/blackpill_f411.cpp index 4edfd2772..b3e7872f1 100644 --- a/STM32F3/cores/maple/wirish/wirish_debug.h +++ b/STM32F4/variants/blackpill_f411/blackpill_f411.cpp @@ -25,33 +25,37 @@ *****************************************************************************/ /** - * @file wirish/include/wirish/wirish_debug.h - * @brief High level debug port configuration + * @file blackpill_f411.cpp + * @author stevestrong + * @modified by board707 + * @brief blackpill_f411 board file. */ -#ifndef _WIRISH_WIRISH_DEBUG_H_ -#define _WIRISH_WIRISH_DEBUG_H_ +#include "blackpill_f411.h" #include +#include -/** - * @brief Disable the JTAG and Serial Wire (SW) debug ports. - * - * You can call this function in order to use the JTAG and SW debug - * pins as ordinary GPIOs. - * - * @see enableDebugPorts() - */ -void disableDebugPorts(void); +#include -/** - * @brief Enable the JTAG and Serial Wire (SW) debug ports. - * - * After you call this function, the JTAG and SW debug pins will no - * longer be usable as GPIOs. - * - * @see disableDebugPorts() - */ -void enableDebugPorts(void); -#endif +void boardInit(void) +{ +} + + +//extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { +// 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 +//}; +// +//extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { +// 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 32, 33, 34, 35, 36, 37 +//}; +// +//extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { +// BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, +// BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN, +// 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 78, 79, 81, +// 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 +//}; + diff --git a/STM32F4/variants/blackpill_f411/blackpill_f411.h b/STM32F4/variants/blackpill_f411/blackpill_f411.h new file mode 100644 index 000000000..5d7b5cb34 --- /dev/null +++ b/STM32F4/variants/blackpill_f411/blackpill_f411.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file blackpill_f411.h + * @author stevestrong + * @modified by board707 + * @brief Private include file + */ + +#ifndef _BOARD_BLACKPILL_F411_H_ +#define _BOARD_BLACKPILL_F411_H_ + + +//#define Port2Pin(port, bit) ((port-'A')*16+bit) + +#define CLOCK_SPEED_MHZ 96 + + +#define BOARD_LED_PIN PC13 + +#define BOARD_USB_DM_PIN PA11 +#define BOARD_USB_DP_PIN PA12 + +#define BOARD_NR_USARTS 3 +#define BOARD_USART1_TX_PIN PA9 +#define BOARD_USART1_RX_PIN PA10 +#define BOARD_USART2_TX_PIN PA2 +#define BOARD_USART2_RX_PIN PA3 +//#define BOARD_USART6_TX_PIN PA11 // USB_DM +//#define BOARD_USART6_RX_PIN PA12 // USB_DP + +#define BOARD_NR_I2C 3 +#define BOARD_I2C1_SCL_PIN PB6 +#define BOARD_I2C1_SDA_PIN PB7 +#define BOARD_I2C1A_SCL_PIN PB8 +#define BOARD_I2C1A_SDA_PIN PB9 +#define BOARD_I2C2_SCL_PIN PB10 +#define BOARD_I2C2_SDA_PIN PB3 +#define BOARD_I2C3_SCL_PIN PA8 +#define BOARD_I2C3_SDA_PIN PB4 + +#define BOARD_NR_SPI 3 +#define BOARD_SPI1_NSS_PIN PA4 +#define BOARD_SPI1_SCK_PIN PA5 +#define BOARD_SPI1_MISO_PIN PA6 +#define BOARD_SPI1_MOSI_PIN PA7 + +#define BOARD_SPI2_NSS_PIN PB12 +#define BOARD_SPI2_SCK_PIN PB13 +#define BOARD_SPI2_MISO_PIN PB14 +#define BOARD_SPI2_MOSI_PIN PB15 + +#define BOARD_SPI3_NSS_PIN PA15 +#define BOARD_SPI3_SCK_PIN PB3 +#define BOARD_SPI3_MISO_PIN PB4 +#define BOARD_SPI3_MOSI_PIN PB5 + +//#define BOARD_NR_GPIO_PINS 32 +#define BOARD_NR_PWM_PINS 22 +#define BOARD_NR_ADC_PINS 16 +#define BOARD_NR_USED_PINS 43 // ala42 not set yet +#define BOARD_JTMS_SWDIO_PIN PA13 +#define BOARD_JTCK_SWCLK_PIN PA14 + + +enum { +PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PA8,PA9,PA10,PA11,PA12,PA13,PA14,PA15, +PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB12=(PB10+2),PB13,PB14,PB15, +PC13=(32+13),PC14,PC15, +BOARD_NR_GPIO_PINS +}; + +#endif diff --git a/STM32F4/variants/blackpill_f411/ld/common.inc b/STM32F4/variants/blackpill_f411/ld/common.inc new file mode 100644 index 000000000..b73266e8c --- /dev/null +++ b/STM32F4/variants/blackpill_f411/ld/common.inc @@ -0,0 +1,219 @@ +/* + * Linker script for libmaple. + * + * Original author "lanchon" from ST forums, with modifications by LeafLabs. + */ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* + * Configure other libraries we want in the link. + * + * libgcc, libc, and libm are common across supported toolchains. + * However, some toolchains require additional archives which aren't + * present everywhere (e.g. ARM's gcc-arm-embedded releases). + * + * To hack around this, we let the build system specify additional + * archives by putting the right extra_libs.inc (in a directory under + * toolchains/) in our search path. + */ +GROUP(libgcc.a libc.a libm.a) +INCLUDE extra_libs.inc + +/* + * These force the linker to search for vector table symbols. + * + * These symbols vary by STM32 family (and also within families). + * It's up to the build system to configure the link's search path + * properly for the target MCU. + */ +INCLUDE vector_symbols.inc + +/* STM32 vector table. */ +EXTERN(__stm32_vector_table) + +/* C runtime initialization function. */ +EXTERN(start_c) + +/* main entry point */ +EXTERN(main) + +/* Initial stack pointer value. Relocated to RAM */ +EXTERN(__msp_init) +PROVIDE(__msp_init = ORIGIN(ram) + LENGTH(ram)); + +/* Reset vector and chip reset entry point */ +EXTERN(__start__) +ENTRY(__start__) +PROVIDE(__exc_reset = __start__); + +/* Heap boundaries, for libmaple */ +EXTERN(_lm_heap_start); +EXTERN(_lm_heap_end); + +SECTIONS +{ + .text : + { + __text_start__ = .; + /* + * STM32 vector table. Leave this here. Yes, really. + */ + *(.stm32.interrupt_vector) + + /* + * Program code and vague linking + */ + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(0x4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > REGION_TEXT + + /* + * End of text + */ + .text.align : + { + . = ALIGN(8); + __text_end__ = .; + } > REGION_TEXT + + /* + * .ARM.exidx exception unwinding; mandated by ARM's C++ ABI + */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > REGION_RODATA + __exidx_end = .; + + /* + * Read-only data + */ + .rodata : + { + *(.rodata .rodata.* .gnu.linkonce.r.*) + /* .USER_FLASH: We allow users to allocate into Flash here */ + *(.USER_FLASH) + /* ROM image configuration; for C startup */ + . = ALIGN(4); + _lm_rom_img_cfgp = .; + LONG(LOADADDR(.data)); + /* + * Heap: Linker scripts may choose a custom heap by overriding + * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in + * internal SRAM, beginning after .bss, and growing towards + * the stack. + * + * I'm shoving these here naively; there's probably a cleaner way + * to go about this. [mbolivar] + */ + _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : __bss_end__; + _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init; + } > REGION_RODATA + + /* + * .data + */ + .data : + { + . = ALIGN(8); + __data_start__ = .; + + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + + . = ALIGN(8); + __data_end__ = .; + } > REGION_DATA AT> REGION_RODATA + + /* + * .bss + */ + .bss : + { + . = ALIGN(8); + __bss_start__ = .; + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = __bss_end__; + } > REGION_BSS + + /* + * Debugging sections + */ + .stab 0 (NOLOAD) : { *(.stab) } + .stabstr 0 (NOLOAD) : { *(.stabstr) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/STM32F4/variants/blackpill_f411/ld/extra_libs.inc b/STM32F4/variants/blackpill_f411/ld/extra_libs.inc new file mode 100644 index 000000000..dd2c84fa4 --- /dev/null +++ b/STM32F4/variants/blackpill_f411/ld/extra_libs.inc @@ -0,0 +1,7 @@ +/* + * Extra archives needed by ARM's GCC ARM Embedded arm-none-eabi- + * releases (https://launchpad.net/gcc-arm-embedded/). + */ + +/* This is for the provided newlib. */ +GROUP(libnosys.a) diff --git a/STM32F4/variants/blackpill_f411/ld/jtag.ld b/STM32F4/variants/blackpill_f411/ld/jtag.ld new file mode 100644 index 000000000..a5fc4de3d --- /dev/null +++ b/STM32F4/variants/blackpill_f411/ld/jtag.ld @@ -0,0 +1,19 @@ +/* + * STM32F411 linker script for JTAG (bare metal, no bootloader) builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +/* GROUP(libcs3_stm32_high_density.a) */ + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/STM32F4/variants/blackpill_f411/ld/vector_symbols.inc b/STM32F4/variants/blackpill_f411/ld/vector_symbols.inc new file mode 100644 index 000000000..853c4f50b --- /dev/null +++ b/STM32F4/variants/blackpill_f411/ld/vector_symbols.inc @@ -0,0 +1,99 @@ +EXTERN(__msp_init) +EXTERN(__exc_reset) +EXTERN(__exc_nmi) +EXTERN(__exc_hardfault) +EXTERN(__exc_memmanage) +EXTERN(__exc_busfault) +EXTERN(__exc_usagefault) +EXTERN(__stm32reservedexception7) +EXTERN(__stm32reservedexception8) +EXTERN(__stm32reservedexception9) +EXTERN(__stm32reservedexception10) +EXTERN(__exc_svc) +EXTERN(__exc_debug_monitor) +EXTERN(__stm32reservedexception13) +EXTERN(__exc_pendsv) +EXTERN(__exc_systick) + +EXTERN(__irq_wwdg) +EXTERN(__irq_pvd) +EXTERN(__irq_tamper) +EXTERN(__irq_rtc) +EXTERN(__irq_flash) +EXTERN(__irq_rcc) +EXTERN(__irq_exti0) +EXTERN(__irq_exti1) +EXTERN(__irq_exti2) +EXTERN(__irq_exti3) +EXTERN(__irq_exti4) +EXTERN(__irq_dma1_stream0) +EXTERN(__irq_dma1_stream1) +EXTERN(__irq_dma1_stream2) +EXTERN(__irq_dma1_stream3) +EXTERN(__irq_dma1_stream4) +EXTERN(__irq_dma1_stream5) +EXTERN(__irq_dma1_stream6) +EXTERN(__irq_adc) +EXTERN(__irq_can1_tx) +EXTERN(__irq_can1_rx0) +EXTERN(__irq_can1_rx1) +EXTERN(__irq_can1_sce) +EXTERN(__irq_exti9_5) +EXTERN(__irq_tim1_brk) +EXTERN(__irq_tim1_up) +EXTERN(__irq_tim1_trg_com) +EXTERN(__irq_tim1_cc) +EXTERN(__irq_tim2) +EXTERN(__irq_tim3) +EXTERN(__irq_tim4) +EXTERN(__irq_i2c1_ev) +EXTERN(__irq_i2c1_er) +EXTERN(__irq_i2c2_ev) +EXTERN(__irq_i2c2_er) +EXTERN(__irq_spi1) +EXTERN(__irq_spi2) +EXTERN(__irq_usart1) +EXTERN(__irq_usart2) +EXTERN(__irq_usart3) +EXTERN(__irq_exti15_10) +EXTERN(__irq_rtcalarm) +EXTERN(__irq_usbwakeup) +EXTERN(__irq_tim8_brk) +EXTERN(__irq_tim8_up) +EXTERN(__irq_tim8_trg_com) +EXTERN(__irq_tim8_cc) +EXTERN(__irq_dma1_stream7) +EXTERN(__irq_fsmc) +EXTERN(__irq_sdio) +EXTERN(__irq_tim5) +EXTERN(__irq_spi3) +EXTERN(__irq_uart4) +EXTERN(__irq_uart5) +EXTERN(__irq_tim6_dac) +EXTERN(__irq_tim7) +EXTERN(__irq_dma2_stream0) +EXTERN(__irq_dma2_stream1) +EXTERN(__irq_dma2_stream2) +EXTERN(__irq_dma2_stream3) +EXTERN(__irq_dma2_stream4) +EXTERN(__irq_eth) +EXTERN(__irq_eth_wkup) +EXTERN(__irq_can2_tx) +EXTERN(__irq_can2_rx0) +EXTERN(__irq_can2_rx1) +EXTERN(__irq_can2_sce) +EXTERN(__irq_usb_fs) +EXTERN(__irq_dma2_stream5) +EXTERN(__irq_dma2_stream6) +EXTERN(__irq_dma2_stream7) +EXTERN(__irq_usart6) +EXTERN(__irq_i2c3_ev) +EXTERN(__irq_i2c3_er) +EXTERN(__irq_usb_hs_ep1_out) +EXTERN(__irq_usb_hs_ep1_in) +EXTERN(__irq_usb_hs_wkup) +EXTERN(__irq_usb_hs) +EXTERN(__irq_dcmi) +EXTERN(__irq_cryp) +EXTERN(__irq_hash_rng) +EXTERN(__irq_fpu) diff --git a/STM32F4/variants/blackpill_f411/pins_arduino.h b/STM32F4/variants/blackpill_f411/pins_arduino.h new file mode 100644 index 000000000..3052f2eb2 --- /dev/null +++ b/STM32F4/variants/blackpill_f411/pins_arduino.h @@ -0,0 +1,6 @@ + + + + +// API compatibility +#include "variant.h" \ No newline at end of file diff --git a/STM32F4/variants/blackpill_f411/variant.h b/STM32F4/variants/blackpill_f411/variant.h new file mode 100644 index 000000000..74719a979 --- /dev/null +++ b/STM32F4/variants/blackpill_f411/variant.h @@ -0,0 +1,10 @@ +#ifndef _VARIANT_ARDUINO_STM32_ +#define _VARIANT_ARDUINO_STM32_ + +static const uint8_t SS = BOARD_SPI1_NSS_PIN; +static const uint8_t SS1 = BOARD_SPI2_NSS_PIN; +static const uint8_t MOSI = BOARD_SPI1_MOSI_PIN; +static const uint8_t MISO = BOARD_SPI1_MISO_PIN; +static const uint8_t SCK = BOARD_SPI1_SCK_PIN; + +#endif /* _VARIANT_ARDUINO_STM32_ */ \ No newline at end of file diff --git a/STM32F4/variants/disco_f411/disco_f411.cpp b/STM32F4/variants/disco_f411/disco_f411.cpp new file mode 100644 index 000000000..d4c69df10 --- /dev/null +++ b/STM32F4/variants/disco_f411/disco_f411.cpp @@ -0,0 +1,94 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file disc_f411.cpp + * @author stevestrong + * @brief disco_f411e board file. + */ + +#include "disco_f411.h" + +#include +#include + +#include + + +void boardInit(void) +{ +return; + // remap TIMER8 to PC6-9 + gpio_set_af_mode(PC6, GPIO_AFMODE_TIM8_11); + gpio_set_af_mode(PC7, GPIO_AFMODE_TIM8_11); + gpio_set_af_mode(PC8, GPIO_AFMODE_TIM8_11); + gpio_set_af_mode(PC9, GPIO_AFMODE_TIM8_11); + + // remap TIMER1 to PE9,11,13,14 + gpio_set_af_mode(PE9, GPIO_AFMODE_TIM1_2); + gpio_set_af_mode(PE11, GPIO_AFMODE_TIM1_2); + gpio_set_af_mode(PE13, GPIO_AFMODE_TIM1_2); + gpio_set_af_mode(PE14, GPIO_AFMODE_TIM1_2); + + // remap TIMER3 to PB4,5,0,1 + gpio_set_af_mode(PB4, GPIO_AFMODE_TIM3_5); + gpio_set_af_mode(PB5, GPIO_AFMODE_TIM3_5); + gpio_set_af_mode(PB0, GPIO_AFMODE_TIM3_5); + gpio_set_af_mode(PB1, GPIO_AFMODE_TIM3_5); + + //gpio_set_af_mode(GPIOA, 2, GPIO_AFMODE_UASRT1_3); + //gpio_set_af_mode(GPIOA, 3, GPIO_AFMODE_UASRT1_3); + +#ifdef BOARD_STM32F4_NETDUINO2PLUS + // PA8 Output the Master Clock MCO1 + gpio_set_af_mode(PA8, GPIO_AFMODE_SYSTEM); + gpio_set_mode(PA8, (gpio_pin_mode)(GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ)); + // PB4 as alternate MISO Input + gpio_set_af_mode(PB4, GPIO_AFMODE_SPI1_2); + // PA5 as alternate SCK Output + gpio_set_af_mode(PA5, GPIO_AFMODE_SPI1_2); + // PA7 as alternate MOSI Output + gpio_set_af_mode(PA7, GPIO_AFMODE_SPI1_2); +#endif + return; +} + + +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 +}; + +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 32, 33, 34, 35, 36, 37 +}; + +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN, + 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 78, 79, 81, + 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 +}; + diff --git a/STM32F4/variants/disco_f411/disco_f411.h b/STM32F4/variants/disco_f411/disco_f411.h new file mode 100644 index 000000000..5c95c0eb1 --- /dev/null +++ b/STM32F4/variants/disco_f411/disco_f411.h @@ -0,0 +1,137 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file disco_f411.h + * @author stevestrong + * @brief Private include file for Maple Native in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARD_DISCO_F411_H_ +#define _BOARD_DISCO_F411_H_ + + +//#define Port2Pin(port, bit) ((port-'A')*16+bit) + +#define CLOCK_SPEED_MHZ 96 + + +#define BOARD_LED_PIN PD12 +#define BOARD_LED_PIN2 PD13 +#define BOARD_LED_PIN3 PD14 +#define BOARD_LED_PIN4 PD15 + +#define BOARD_BUTTON_PIN PA0 + +#define BOARD_USB_DM_PIN PA11 +#define BOARD_USB_DP_PIN PA12 + +#define BOARD_NR_USARTS 3 +#define BOARD_USART1_TX_PIN PA9 +#define BOARD_USART1_RX_PIN PA10 +#define BOARD_USART2_TX_PIN PA2 +#define BOARD_USART2_RX_PIN PA3 +#define BOARD_USART6_TX_PIN PC6 +#define BOARD_USART6_RX_PIN PC7 + +#define BOARD_NR_I2C 3 +#define BOARD_I2C1_SCL_PIN PB6 +#define BOARD_I2C1_SDA_PIN PB7 +#define BOARD_I2C1A_SCL_PIN PB8 +#define BOARD_I2C1A_SDA_PIN PB9 +#define BOARD_I2C2_SCL_PIN PB10 +#define BOARD_I2C2_SDA_PIN PB11 +#ifdef PACKAGE_LQFP144 +#define BOARD_I2C2A_SCL_PIN PF1 +#define BOARD_I2C2A_SDA_PIN PF0 +#endif +#define BOARD_I2C3_SCL_PIN PA8 +#define BOARD_I2C3_SDA_PIN PC9 +#ifdef PACKAGE_LQFP144 +#define BOARD_I2C3A_SCL_PIN PH7 +#define BOARD_I2C3A_SDA_PIN PH8 +#endif + +#define BOARD_NR_SPI 5 +#define BOARD_SPI1_NSS_PIN PA4 +#define BOARD_SPI1_SCK_PIN PA5 +#define BOARD_SPI1_MISO_PIN PA6 +#define BOARD_SPI1_MOSI_PIN PA7 +#define BOARD_SPI1A_NSS_PIN PA15 +#define BOARD_SPI1A_SCK_PIN PB3 +#define BOARD_SPI1A_MISO_PIN PB4 +#define BOARD_SPI1A_MOSI_PIN PB5 + +#define BOARD_SPI2_NSS_PIN PB12 +#define BOARD_SPI2_SCK_PIN PB13 +#define BOARD_SPI2_MISO_PIN PB14 +#define BOARD_SPI2_MOSI_PIN PB15 +#define BOARD_SPI2A_NSS_PIN PB9 +#define BOARD_SPI2A_SCK_PIN PB10 // PC7 // PB7 +#define BOARD_SPI2A_MISO_PIN PC2 +#define BOARD_SPI2A_MOSI_PIN PC3 + +#define BOARD_SPI3_NSS_PIN PA15 +#define BOARD_SPI3_SCK_PIN PB3 +#define BOARD_SPI3_MISO_PIN PB4 +#define BOARD_SPI3_MOSI_PIN PB5 +#define BOARD_SPI3A_NSS_PIN PA4 +#define BOARD_SPI3A_SCK_PIN PC10 +#define BOARD_SPI3A_MISO_PIN PC11 +#define BOARD_SPI3A_MOSI_PIN PC12 + +#define BOARD_SPI4_NSS_PIN PE4 +#define BOARD_SPI4_SCK_PIN PE2 +#define BOARD_SPI4_MISO_PIN PE5 +#define BOARD_SPI4_MOSI_PIN PE6 + +#define BOARD_SPI5_NSS_PIN PE11 +#define BOARD_SPI5_SCK_PIN PE12 +#define BOARD_SPI5_MISO_PIN PE13 +#define BOARD_SPI5_MOSI_PIN PE14 + +#define BOARD_NR_PWM_PINS 22 +#define BOARD_NR_ADC_PINS 16 +#define BOARD_NR_USED_PINS 43 // ala42 not set yet +#define BOARD_JTMS_SWDIO_PIN PA13 +#define BOARD_JTCK_SWCLK_PIN PA14 +#define BOARD_JTDI_PIN PA15 +#define BOARD_JTDO_PIN PB3 +#define BOARD_NJTRST_PIN PB4 + + +enum { +PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PA8,PA9,PA10,PA11,PA12,PA13,PA14,PA15, +PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15, +PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PC8,PC9,PC10,PC11,PC12,PC13,PC14,PC15, +PD0,PD1,PD2,PD3,PD4,PD5,PD6,PD7,PD8,PD9,PD10,PD11,PD12,PD13,PD14,PD15, +PE0,PE1,PE2,PE3,PE4,PE5,PE6,PE7,PE8,PE9,PE10,PE11,PE12,PE13,PE14,PE15, +BOARD_NR_GPIO_PINS +}; + +#endif diff --git a/STM32F4/variants/disco_f411/ld/common.inc b/STM32F4/variants/disco_f411/ld/common.inc new file mode 100644 index 000000000..4874a34e9 --- /dev/null +++ b/STM32F4/variants/disco_f411/ld/common.inc @@ -0,0 +1,219 @@ +/* + * Linker script for libmaple. + * + * Original author "lanchon" from ST forums, with modifications by LeafLabs. + */ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* + * Configure other libraries we want in the link. + * + * libgcc, libc, and libm are common across supported toolchains. + * However, some toolchains require additional archives which aren't + * present everywhere (e.g. ARM's gcc-arm-embedded releases). + * + * To hack around this, we let the build system specify additional + * archives by putting the right extra_libs.inc (in a directory under + * toolchains/) in our search path. + */ +GROUP(libgcc.a libc.a libm.a) +INCLUDE extra_libs.inc + +/* + * These force the linker to search for vector table symbols. + * + * These symbols vary by STM32 family (and also within families). + * It's up to the build system to configure the link's search path + * properly for the target MCU. + */ +INCLUDE vector_symbols.inc + +/* STM32 vector table. */ +EXTERN(__stm32_vector_table) + +/* C runtime initialization function. */ +EXTERN(start_c) + +/* main entry point */ +EXTERN(main) + +/* Initial stack pointer value. Relocated to RAM */ +EXTERN(__msp_init) +PROVIDE(__msp_init = ORIGIN(ram) + LENGTH(ram)); + +/* Reset vector and chip reset entry point */ +EXTERN(__start__) +ENTRY(__start__) +PROVIDE(__exc_reset = __start__); + +/* Heap boundaries, for libmaple */ +EXTERN(_lm_heap_start); +EXTERN(_lm_heap_end); + +SECTIONS +{ + .text : + { + __text_start__ = .; + /* + * STM32 vector table. Leave this here. Yes, really. + */ + *(.stm32.interrupt_vector) + + /* + * Program code and vague linking + */ + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(0x4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > REGION_TEXT + + /* + * End of text + */ + .text.align : + { + . = ALIGN(8); + __text_end__ = .; + } > REGION_TEXT + + /* + * .ARM.exidx exception unwinding; mandated by ARM's C++ ABI + */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > REGION_RODATA + __exidx_end = .; + + /* + * Read-only data + */ + .rodata : + { + *(.rodata .rodata.* .gnu.linkonce.r.*) + /* .USER_FLASH: We allow users to allocate into Flash here */ + *(.USER_FLASH) + /* ROM image configuration; for C startup */ + . = ALIGN(4); + _lm_rom_img_cfgp = .; + LONG(LOADADDR(.data)); + /* + * Heap: Linker scripts may choose a custom heap by overriding + * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in + * internal SRAM, beginning after .bss, and growing towards + * the stack. + * + * I'm shoving these here naively; there's probably a cleaner way + * to go about this. [mbolivar] + */ + _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : __data_end__; + _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init; + } > REGION_RODATA + + /* + * .data + */ + .data : + { + . = ALIGN(8); + __data_start__ = .; + + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + + . = ALIGN(8); + __data_end__ = .; + } > REGION_DATA AT> REGION_RODATA + + /* + * .bss + */ + .bss : + { + . = ALIGN(8); + __bss_start__ = .; + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = __bss_end__; + } > REGION_BSS + + /* + * Debugging sections + */ + .stab 0 (NOLOAD) : { *(.stab) } + .stabstr 0 (NOLOAD) : { *(.stabstr) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/STM32F4/variants/disco_f411/ld/extra_libs.inc b/STM32F4/variants/disco_f411/ld/extra_libs.inc new file mode 100644 index 000000000..dd2c84fa4 --- /dev/null +++ b/STM32F4/variants/disco_f411/ld/extra_libs.inc @@ -0,0 +1,7 @@ +/* + * Extra archives needed by ARM's GCC ARM Embedded arm-none-eabi- + * releases (https://launchpad.net/gcc-arm-embedded/). + */ + +/* This is for the provided newlib. */ +GROUP(libnosys.a) diff --git a/STM32F4/variants/disco_f411/ld/flash.ld b/STM32F4/variants/disco_f411/ld/flash.ld new file mode 100644 index 000000000..c753a786c --- /dev/null +++ b/STM32F4/variants/disco_f411/ld/flash.ld @@ -0,0 +1,20 @@ +/* + * Discovery F4 (STM32F407VGT6, high density) linker script for + * Flash builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 125K + rom (rx) : ORIGIN = 0x08010000, LENGTH = 960K /* ala42 */ +} + +/* GROUP(libcs4_stm32_high_density.a) */ + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/STM32F4/variants/disco_f411/ld/jtag.ld b/STM32F4/variants/disco_f411/ld/jtag.ld new file mode 100644 index 000000000..5cc62ee5f --- /dev/null +++ b/STM32F4/variants/disco_f411/ld/jtag.ld @@ -0,0 +1,20 @@ +/* + * STM32F4xx high density linker script for + * JTAG (bare metal, no bootloader) builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K +} + +/* GROUP(libcs3_stm32_high_density.a) */ + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/STM32F4/variants/disco_f411/ld/ram.ld b/STM32F4/variants/disco_f411/ld/ram.ld new file mode 100644 index 000000000..b57060c92 --- /dev/null +++ b/STM32F4/variants/disco_f411/ld/ram.ld @@ -0,0 +1,19 @@ +/* + * aeroquad32 (STM32F103VET6, high density) linker script for + * RAM builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + rom (rx) : ORIGIN = 0x08010000, LENGTH = 0K /* ala42 */ +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +INCLUDE common.inc diff --git a/STM32F4/variants/disco_f411/ld/vector_symbols.inc b/STM32F4/variants/disco_f411/ld/vector_symbols.inc new file mode 100644 index 000000000..853c4f50b --- /dev/null +++ b/STM32F4/variants/disco_f411/ld/vector_symbols.inc @@ -0,0 +1,99 @@ +EXTERN(__msp_init) +EXTERN(__exc_reset) +EXTERN(__exc_nmi) +EXTERN(__exc_hardfault) +EXTERN(__exc_memmanage) +EXTERN(__exc_busfault) +EXTERN(__exc_usagefault) +EXTERN(__stm32reservedexception7) +EXTERN(__stm32reservedexception8) +EXTERN(__stm32reservedexception9) +EXTERN(__stm32reservedexception10) +EXTERN(__exc_svc) +EXTERN(__exc_debug_monitor) +EXTERN(__stm32reservedexception13) +EXTERN(__exc_pendsv) +EXTERN(__exc_systick) + +EXTERN(__irq_wwdg) +EXTERN(__irq_pvd) +EXTERN(__irq_tamper) +EXTERN(__irq_rtc) +EXTERN(__irq_flash) +EXTERN(__irq_rcc) +EXTERN(__irq_exti0) +EXTERN(__irq_exti1) +EXTERN(__irq_exti2) +EXTERN(__irq_exti3) +EXTERN(__irq_exti4) +EXTERN(__irq_dma1_stream0) +EXTERN(__irq_dma1_stream1) +EXTERN(__irq_dma1_stream2) +EXTERN(__irq_dma1_stream3) +EXTERN(__irq_dma1_stream4) +EXTERN(__irq_dma1_stream5) +EXTERN(__irq_dma1_stream6) +EXTERN(__irq_adc) +EXTERN(__irq_can1_tx) +EXTERN(__irq_can1_rx0) +EXTERN(__irq_can1_rx1) +EXTERN(__irq_can1_sce) +EXTERN(__irq_exti9_5) +EXTERN(__irq_tim1_brk) +EXTERN(__irq_tim1_up) +EXTERN(__irq_tim1_trg_com) +EXTERN(__irq_tim1_cc) +EXTERN(__irq_tim2) +EXTERN(__irq_tim3) +EXTERN(__irq_tim4) +EXTERN(__irq_i2c1_ev) +EXTERN(__irq_i2c1_er) +EXTERN(__irq_i2c2_ev) +EXTERN(__irq_i2c2_er) +EXTERN(__irq_spi1) +EXTERN(__irq_spi2) +EXTERN(__irq_usart1) +EXTERN(__irq_usart2) +EXTERN(__irq_usart3) +EXTERN(__irq_exti15_10) +EXTERN(__irq_rtcalarm) +EXTERN(__irq_usbwakeup) +EXTERN(__irq_tim8_brk) +EXTERN(__irq_tim8_up) +EXTERN(__irq_tim8_trg_com) +EXTERN(__irq_tim8_cc) +EXTERN(__irq_dma1_stream7) +EXTERN(__irq_fsmc) +EXTERN(__irq_sdio) +EXTERN(__irq_tim5) +EXTERN(__irq_spi3) +EXTERN(__irq_uart4) +EXTERN(__irq_uart5) +EXTERN(__irq_tim6_dac) +EXTERN(__irq_tim7) +EXTERN(__irq_dma2_stream0) +EXTERN(__irq_dma2_stream1) +EXTERN(__irq_dma2_stream2) +EXTERN(__irq_dma2_stream3) +EXTERN(__irq_dma2_stream4) +EXTERN(__irq_eth) +EXTERN(__irq_eth_wkup) +EXTERN(__irq_can2_tx) +EXTERN(__irq_can2_rx0) +EXTERN(__irq_can2_rx1) +EXTERN(__irq_can2_sce) +EXTERN(__irq_usb_fs) +EXTERN(__irq_dma2_stream5) +EXTERN(__irq_dma2_stream6) +EXTERN(__irq_dma2_stream7) +EXTERN(__irq_usart6) +EXTERN(__irq_i2c3_ev) +EXTERN(__irq_i2c3_er) +EXTERN(__irq_usb_hs_ep1_out) +EXTERN(__irq_usb_hs_ep1_in) +EXTERN(__irq_usb_hs_wkup) +EXTERN(__irq_usb_hs) +EXTERN(__irq_dcmi) +EXTERN(__irq_cryp) +EXTERN(__irq_hash_rng) +EXTERN(__irq_fpu) diff --git a/STM32F4/variants/disco_f411/pins_arduino.h b/STM32F4/variants/disco_f411/pins_arduino.h new file mode 100644 index 000000000..3052f2eb2 --- /dev/null +++ b/STM32F4/variants/disco_f411/pins_arduino.h @@ -0,0 +1,6 @@ + + + + +// API compatibility +#include "variant.h" \ No newline at end of file diff --git a/STM32F4/variants/disco_f411/variant.h b/STM32F4/variants/disco_f411/variant.h new file mode 100644 index 000000000..74719a979 --- /dev/null +++ b/STM32F4/variants/disco_f411/variant.h @@ -0,0 +1,10 @@ +#ifndef _VARIANT_ARDUINO_STM32_ +#define _VARIANT_ARDUINO_STM32_ + +static const uint8_t SS = BOARD_SPI1_NSS_PIN; +static const uint8_t SS1 = BOARD_SPI2_NSS_PIN; +static const uint8_t MOSI = BOARD_SPI1_MOSI_PIN; +static const uint8_t MISO = BOARD_SPI1_MISO_PIN; +static const uint8_t SCK = BOARD_SPI1_SCK_PIN; + +#endif /* _VARIANT_ARDUINO_STM32_ */ \ No newline at end of file diff --git a/STM32F4/variants/discovery_f407/discovery_f4.cpp b/STM32F4/variants/discovery_f407/discovery_f4.cpp index 7d288d583..fe0839f8e 100644 --- a/STM32F4/variants/discovery_f407/discovery_f4.cpp +++ b/STM32F4/variants/discovery_f407/discovery_f4.cpp @@ -30,193 +30,51 @@ * @brief discovery_f4 board file. */ -#ifdef BOARD_discovery_f4 - #include "discovery_f4.h" #include #include -#include "wirish_types.h" +#include + -//static void initSRAMChip(void); void boardInit(void) { // remap TIMER8 to PC6-9 - gpio_set_af_mode(PC6, 3); - gpio_set_af_mode(PC7, 3); - gpio_set_af_mode(PC8, 3); - gpio_set_af_mode(PC9, 3); + gpio_set_af_mode(PC6, GPIO_AFMODE_TIM8_11); + gpio_set_af_mode(PC7, GPIO_AFMODE_TIM8_11); + gpio_set_af_mode(PC8, GPIO_AFMODE_TIM8_11); + gpio_set_af_mode(PC9, GPIO_AFMODE_TIM8_11); // remap TIMER1 to PE9,11,13,14 - gpio_set_af_mode(PE9, 1); - gpio_set_af_mode(PE11, 1); - gpio_set_af_mode(PE13, 1); - gpio_set_af_mode(PE14, 1); + gpio_set_af_mode(PE9, GPIO_AFMODE_TIM1_2); + gpio_set_af_mode(PE11, GPIO_AFMODE_TIM1_2); + gpio_set_af_mode(PE13, GPIO_AFMODE_TIM1_2); + gpio_set_af_mode(PE14, GPIO_AFMODE_TIM1_2); // remap TIMER3 to PB4,5,0,1 - gpio_set_af_mode(PB4, 2); - gpio_set_af_mode(PB5, 2); - gpio_set_af_mode(PB0, 2); - gpio_set_af_mode(PB1, 2); + gpio_set_af_mode(PB4, GPIO_AFMODE_TIM3_5); + gpio_set_af_mode(PB5, GPIO_AFMODE_TIM3_5); + gpio_set_af_mode(PB0, GPIO_AFMODE_TIM3_5); + gpio_set_af_mode(PB1, GPIO_AFMODE_TIM3_5); - //gpio_set_af_mode(GPIOA, 2, 7); - //gpio_set_af_mode(GPIOA, 3, 7); + //gpio_set_af_mode(GPIOA, 2, GPIO_AFMODE_UASRT1_3); + //gpio_set_af_mode(GPIOA, 3, GPIO_AFMODE_UASRT1_3); -#ifdef ARDUINO_STM32F4_NETDUINO2PLUS +#ifdef BOARD_STM32F4_NETDUINO2PLUS // PA8 Output the Master Clock MCO1 - gpio_set_af_mode(PA8, 0); + gpio_set_af_mode(PA8, GPIO_AFMODE_SYSTEM); + gpio_set_mode(PA8, (gpio_pin_mode)(GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ)); // PB4 as alternate MISO Input - gpio_set_af_mode(PB4, 5); + gpio_set_af_mode(PB4, GPIO_AFMODE_SPI1_2); // PA5 as alternate SCK Output - gpio_set_af_mode(PA5, 5); + gpio_set_af_mode(PA5, GPIO_AFMODE_SPI1_2); // PA7 as alternate MOSI Output - gpio_set_af_mode(PA7, 5); + gpio_set_af_mode(PA7, GPIO_AFMODE_SPI1_2); #endif return; } -extern timer_dev timer1; -extern timer_dev timer2; -extern timer_dev timer3; -extern timer_dev timer4; -extern timer_dev timer5; -extern timer_dev timer6; -extern timer_dev timer7; -extern timer_dev timer8; - -#if 0 -typedef struct stm32_pin_info { - gpio_dev *gpio_device; /**< Maple pin's GPIO device */ - timer_dev *timer_device; /**< Pin's timer device, if any. */ - const adc_dev *adc_device; /**< ADC device, if any. */ - uint8 timer_channel; /**< Timer channel, or 0 if none. */ - uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ -} stm32_pin_info; -#endif - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - {&GPIOA, &timer5, &ADC1, 1, 0}, /* D00/PA0 */ - {&GPIOA, &timer5, &ADC1, 2, 1}, /* D01/PA1 */ - {&GPIOA, &timer5, &ADC1, 3, 2}, /* D02/PA2 */ - {&GPIOA, &timer5, &ADC1, 4, 3}, /* D03/PA3 */ - {&GPIOA, NULL, &ADC1, 0, 4}, /* D04/PA4 */ - {&GPIOA, NULL, &ADC1, 0, 5}, /* D05/PA5 */ - {&GPIOA, NULL, &ADC1, 1, 6}, /* D06/PA6 */ // ala check TIMER3 - {&GPIOA, NULL, &ADC1, 0, 7}, /* D07/PA7 */ - {&GPIOA, NULL, NULL, 0, ADCx}, /* D08/PA8 */ // remap out - {&GPIOA, NULL, NULL, 0, ADCx}, /* D09/PA9 */ // remap out - {&GPIOA, NULL, NULL, 0, ADCx}, /* D10/PA10 */ // remap out - {&GPIOA, NULL, NULL, 0, ADCx}, /* D11/PA11 */ // remap out - {&GPIOA, NULL, NULL, 0, ADCx}, /* D12/PA12 */ - {&GPIOA, NULL, NULL, 0, ADCx}, /* D13/PA13 */ - {&GPIOA, NULL, NULL, 0, ADCx}, /* D14/PA14 */ - {&GPIOA, &timer2, NULL, 1, ADCx}, /* D15/PA15 */ // remap in - - {&GPIOB, &timer3, &ADC1, 3, 8}, /* D16/PB0 */ - {&GPIOB, &timer3, &ADC1, 4, 9}, /* D17/PB1 */ - {&GPIOB, NULL, NULL, 0, ADCx}, /* D18/PB2 */ - {&GPIOB, &timer2, NULL, 2, ADCx}, /* D19/PB3 */ // remap in - {&GPIOB, &timer3, NULL, 1, ADCx}, /* D20/PB4 */ // remap in - {&GPIOB, &timer3, NULL, 2, ADCx}, /* D21/PB5 */ // remap in - {&GPIOB, NULL, NULL, 0, ADCx}, /* D22/PB6 */ // remap out - {&GPIOB, NULL, NULL, 0, ADCx}, /* D23/PB7 */ // remap out - {&GPIOB, NULL, NULL, 0, ADCx}, /* D24/PB8 */ // remap out - {&GPIOB, NULL, NULL, 0, ADCx}, /* D25/PB9 */ // remap out - {&GPIOB, NULL, NULL, 0, ADCx}, /* D26/PB10 */ - {&GPIOB, NULL, NULL, 0, ADCx}, /* D27/PB11 */ - {&GPIOB, NULL, NULL, 0, ADCx}, /* D28/PB12 */ - {&GPIOB, NULL, NULL, 0, ADCx}, /* D29/PB13 */ - {&GPIOB, NULL, NULL, 0, ADCx}, /* D30/PB14 */ - {&GPIOB, NULL, NULL, 0, ADCx}, /* D31/PB15 */ - - {&GPIOC, NULL, &ADC1, 0, 10}, /* D32/PC0 */ - {&GPIOC, NULL, &ADC1, 0, 11}, /* D33/PC1 */ - {&GPIOC, NULL, &ADC1, 0, 12}, /* D34/PC2 */ - {&GPIOC, NULL, &ADC1, 0, 13}, /* D35/PC3 */ - {&GPIOC, NULL, &ADC1, 0, 14}, /* D36/PC4 */ - {&GPIOC, NULL, &ADC1, 0, 15}, /* D37/PC5 */ - {&GPIOC, &timer8, NULL, 1, ADCx}, /* D38/PC6 */ - {&GPIOC, &timer8, NULL, 2, ADCx}, /* D39/PC7 */ - {&GPIOC, &timer8, NULL, 3, ADCx}, /* D40/PC8 */ - {&GPIOC, &timer8, NULL, 4, ADCx}, /* D41/PC9 */ - {&GPIOC, NULL, NULL, 0, ADCx}, /* D42/PC10 */ - {&GPIOC, NULL, NULL, 0, ADCx}, /* D43/PC11 */ - {&GPIOC, NULL, NULL, 0, ADCx}, /* D44/PC12 */ - {&GPIOC, NULL, NULL, 0, ADCx}, /* D45/PC13 */ - {&GPIOC, NULL, NULL, 0, ADCx}, /* D46/PC14 */ - {&GPIOC, NULL, NULL, 0, ADCx}, /* D47/PC15 */ - - {&GPIOD, NULL, NULL, 0, ADCx}, /* D48/PD0 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D49/PD1 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D50/PD2 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D51/PD3 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D52/PD4 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D53/PD5 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D54/PD6 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D55/PD7 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D56/PD8 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D57/PD9 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D58/PD10 */ - {&GPIOD, NULL, NULL, 0, ADCx}, /* D59/PD11 */ - {&GPIOD, &timer4, NULL, 1, ADCx}, /* D60/PD12 */ // remap in - {&GPIOD, &timer4, NULL, 2, ADCx}, /* D61/PD13 */ // remap in - {&GPIOD, &timer4, NULL, 3, ADCx}, /* D62/PD14 */ // remap in - {&GPIOD, &timer4, NULL, 4, ADCx}, /* D63/PD15 */ // remap in - - {&GPIOE, NULL, NULL, 0, ADCx}, /* D64/PE0 */ - {&GPIOE, NULL, NULL, 0, ADCx}, /* D65/PE1 */ - {&GPIOE, NULL, NULL, 0, ADCx}, /* D66/PE2 */ - {&GPIOE, NULL, NULL, 0, ADCx}, /* D67/PE3 */ - {&GPIOE, NULL, NULL, 0, ADCx}, /* D68/PE4 */ - {&GPIOE, NULL, NULL, 0, ADCx}, /* D69/PE5 */ - {&GPIOE, NULL, NULL, 0, ADCx}, /* D70/PE6 */ - {&GPIOE, NULL, NULL, 0, ADCx}, /* D71/PE7 */ - {&GPIOE, NULL, NULL, 0, ADCx}, /* D72/PE8 */ - {&GPIOE, &timer1, NULL, 1, ADCx}, /* D73/PE9 */ // remap in - {&GPIOE, NULL, NULL, 0, ADCx}, /* D74/PE10 */ - {&GPIOE, &timer1, NULL, 2, ADCx}, /* D75/PE11 */ // remap in - {&GPIOE, NULL, NULL, 0, ADCx}, /* D76/PE12 */ - {&GPIOE, &timer1, NULL, 3, ADCx}, /* D77/PE13 */ // remap in - {&GPIOE, &timer1, NULL, 4, ADCx}, /* D78/PE14 */ // remap in - {&GPIOE, NULL, NULL, 0, ADCx}, /* D79/PE15 */ -#if 0 // not available on LQFP100 package - {&GPIOF, NULL, NULL, 0, ADCx}, /* D80/PF0 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D81/PF1 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D82/PF2 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D83/PF3 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D84/PF4 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D85/PF5 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D86/PF6 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D87/PF7 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D88/PF8 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D89/PF9 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D90/PF10 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D91/PF11 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D92/PF12 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D93/PF13 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D94/PF14 */ - {&GPIOF, NULL, NULL, 0, ADCx}, /* D95/PF15 */ - - {&GPIOG, NULL, NULL, 0, ADCx}, /* D96/PG0 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D97/PG1 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D98/PG2 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D99/PG3 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D100/PG4 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D101/PG5 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D102/PG6 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D103/PG7 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D104/PG8 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D105/PG9 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D106/PG10 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D107/PG11 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D108/PG12 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D109/PG13 */ - {&GPIOG, NULL, NULL, 0, ADCx}, /* D110/PG14 */ - {&GPIOG, NULL, NULL, 0, ADCx} /* D111/PG15 */ -#endif // not available on LQFP100 package -}; - extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 }; @@ -245,4 +103,3 @@ static void initSRAMChip(void) { fsmc_nor_psram_set_datast(regs, 3); } */ -#endif diff --git a/STM32F4/variants/discovery_f407/discovery_f4.h b/STM32F4/variants/discovery_f407/discovery_f4.h index e3fa0466a..b69630e28 100644 --- a/STM32F4/variants/discovery_f407/discovery_f4.h +++ b/STM32F4/variants/discovery_f407/discovery_f4.h @@ -37,74 +37,67 @@ #define Port2Pin(port, bit) ((port-'A')*16+bit) -#define CYCLES_PER_MICROSECOND 168 +#define CLOCK_SPEED_MHZ 168 -#undef STM32_PCLK1 -#undef STM32_PCLK2 -#define STM32_PCLK1 (CYCLES_PER_MICROSECOND*1000000/4) -#define STM32_PCLK2 (CYCLES_PER_MICROSECOND*1000000/2) - -#define SYSTICK_RELOAD_VAL (CYCLES_PER_MICROSECOND*1000-1) - -#define BOARD_LED_PIN Port2Pin('D', 12) -#define BOARD_BUTTON_PIN Port2Pin('A', 0) +#define BOARD_LED_PIN PD12 +#define BOARD_BUTTON_PIN PA0 #define BOARD_USB_DM_PIN PA11 #define BOARD_USB_DP_PIN PA12 #define BOARD_NR_USARTS 5 -#define BOARD_USART1_TX_PIN Port2Pin('A', 9) -#define BOARD_USART1_RX_PIN Port2Pin('A',10) -#define BOARD_USART2_TX_PIN Port2Pin('A', 2) -#define BOARD_USART2_RX_PIN Port2Pin('A', 3) -#define BOARD_USART3_TX_PIN Port2Pin('D', 8) -#define BOARD_USART3_RX_PIN Port2Pin('D', 9) -#define BOARD_UART4_TX_PIN Port2Pin('C',10) -#define BOARD_UART4_RX_PIN Port2Pin('C',11) -#define BOARD_UART5_TX_PIN Port2Pin('C',12) -#define BOARD_UART5_RX_PIN Port2Pin('D', 2) +#define BOARD_USART1_TX_PIN PA9 +#define BOARD_USART1_RX_PIN PA10 +#define BOARD_USART2_TX_PIN PA2 +#define BOARD_USART2_RX_PIN PA3 +#define BOARD_USART3_TX_PIN PD8 +#define BOARD_USART3_RX_PIN PD9 +#define BOARD_UART4_TX_PIN PC10 +#define BOARD_UART4_RX_PIN PC11 +#define BOARD_UART5_TX_PIN PC12 +#define BOARD_UART5_RX_PIN PD2 #define BOARD_NR_SPI 3 -#ifdef ARDUINO_STM32F4_NETDUINO2PLUS -#define BOARD_SPI1_NSS_PIN Port2Pin('C', 8) +#ifdef BOARD_STM32F4_NETDUINO2PLUS +#define BOARD_SPI1_NSS_PIN PC8 #else -#define BOARD_SPI1_NSS_PIN Port2Pin('A', 4) +#define BOARD_SPI1_NSS_PIN PA4 #endif -#define BOARD_SPI1_MOSI_PIN Port2Pin('A', 7) -#ifdef ARDUINO_STM32F4_NETDUINO2PLUS -#define BOARD_SPI1_MISO_PIN Port2Pin('B', 4) +#define BOARD_SPI1_MOSI_PIN PA7 +#ifdef BOARD_STM32F4_NETDUINO2PLUS +#define BOARD_SPI1_MISO_PIN PB4 #else -#define BOARD_SPI1_MISO_PIN Port2Pin('A', 6) +#define BOARD_SPI1_MISO_PIN PA6 #endif -#define BOARD_SPI1_SCK_PIN Port2Pin('A', 5) -#define BOARD_SPI2_NSS_PIN Port2Pin('B',12) -#define BOARD_SPI2_MOSI_PIN Port2Pin('B',15) -#define BOARD_SPI2_MISO_PIN Port2Pin('B',14) -#define BOARD_SPI2_SCK_PIN Port2Pin('B',13) -#define BOARD_SPI3_NSS_PIN Port2Pin('A',15) -#define BOARD_SPI3_MOSI_PIN Port2Pin('B', 5) -#define BOARD_SPI3_MISO_PIN Port2Pin('B', 4) -#define BOARD_SPI3_SCK_PIN Port2Pin('B', 3) - -#ifdef ARDUINO_STM32F4_NETDUINO2PLUS -#define BOARD_SPI3B_NSS_PIN Port2Pin('B', 0) +#define BOARD_SPI1_SCK_PIN PA5 +#define BOARD_SPI2_NSS_PIN PB12 +#define BOARD_SPI2_MOSI_PIN PB15 +#define BOARD_SPI2_MISO_PIN PB14 +#define BOARD_SPI2_SCK_PIN PB13 +#define BOARD_SPI3_NSS_PIN PA15 +#define BOARD_SPI3_MOSI_PIN PB5 +#define BOARD_SPI3_MISO_PIN PB4 +#define BOARD_SPI3_SCK_PIN PB3 + +#ifdef BOARD_STM32F4_NETDUINO2PLUS +#define BOARD_SPI3B_NSS_PIN PB0 #else -#define BOARD_SPI3B_NSS_PIN Port2Pin('B', 8) +#define BOARD_SPI3B_NSS_PIN PB8 #endif -#define BOARD_SPI3B_MOSI_PIN Port2Pin('C',12) -#define BOARD_SPI3B_MISO_PIN Port2Pin('C',11) -#define BOARD_SPI3B_SCK_PIN Port2Pin('C',10) +#define BOARD_SPI3B_MOSI_PIN PC12 +#define BOARD_SPI3B_MISO_PIN PC11 +#define BOARD_SPI3B_SCK_PIN PC10 #define BOARD_NR_GPIO_PINS 112 #define BOARD_NR_PWM_PINS 22 #define BOARD_NR_ADC_PINS 16 #define BOARD_NR_USED_PINS 43 // ala42 not set yet -#define BOARD_JTMS_SWDIO_PIN Port2Pin('A',13) -#define BOARD_JTCK_SWCLK_PIN Port2Pin('A',14) -#define BOARD_JTDI_PIN Port2Pin('A',15) -#define BOARD_JTDO_PIN Port2Pin('B', 3) -#define BOARD_NJTRST_PIN Port2Pin('B', 4) +#define BOARD_JTMS_SWDIO_PIN PA13 +#define BOARD_JTCK_SWCLK_PIN PA14 +#define BOARD_JTDI_PIN PA15 +#define BOARD_JTDO_PIN PB3 +#define BOARD_NJTRST_PIN PB4 enum { diff --git a/STM32F4/variants/discovery_f407/ld/common.inc b/STM32F4/variants/discovery_f407/ld/common.inc index f5a0f5b6e..acaeb3dc6 100644 --- a/STM32F4/variants/discovery_f407/ld/common.inc +++ b/STM32F4/variants/discovery_f407/ld/common.inc @@ -38,9 +38,9 @@ EXTERN(start_c) /* main entry point */ EXTERN(main) -/* Initial stack pointer value. */ +/* Initial stack pointer value. Relocated to CCMRAM */ EXTERN(__msp_init) -PROVIDE(__msp_init = ORIGIN(ram) + LENGTH(ram)); +PROVIDE(__msp_init = ORIGIN(ccmram) + LENGTH(ccmram)); /* Reset vector and chip reset entry point */ EXTERN(__start__) @@ -128,21 +128,6 @@ SECTIONS } > REGION_RODATA __exidx_end = .; - /* - * .data - */ - .data : - { - . = ALIGN(8); - __data_start__ = .; - - *(.got.plt) *(.got) - *(.data .data.* .gnu.linkonce.d.*) - - . = ALIGN(8); - __data_end__ = .; - } > REGION_DATA AT> REGION_RODATA - /* * Read-only data */ @@ -155,6 +140,7 @@ SECTIONS . = ALIGN(4); _lm_rom_img_cfgp = .; LONG(LOADADDR(.data)); + LONG(LOADADDR(.ccmdata)); /* * Heap: Linker scripts may choose a custom heap by overriding * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in @@ -164,10 +150,42 @@ SECTIONS * I'm shoving these here naively; there's probably a cleaner way * to go about this. [mbolivar] */ - _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : _end; + _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : __ccmdata_end__; _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init; } > REGION_RODATA + /* + * .data + */ + .data : + { + . = ALIGN(8); + __data_start__ = .; + + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + + . = ALIGN(8); + __data_end__ = .; + } > REGION_DATA AT> REGION_RODATA + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * The startup code is modified to copy the init-values from flash to ccmram + * at startup + */ + .ccmdata : + { + . = ALIGN(4); + __ccmdata_start__ = .; /* create a global symbol at ccmram start */ + *(.ccmdata) + *(.ccmram*) + + . = ALIGN(4); + __ccmdata_end__ = .; /* create a global symbol at ccmram end */ + } >REGION_CCMRAM AT> REGION_RODATA + /* * .bss */ diff --git a/STM32F4/variants/discovery_f407/ld/jtag.ld b/STM32F4/variants/discovery_f407/ld/jtag.ld index 53413b0f7..a356c3c9a 100644 --- a/STM32F4/variants/discovery_f407/ld/jtag.ld +++ b/STM32F4/variants/discovery_f407/ld/jtag.ld @@ -5,8 +5,9 @@ MEMORY { - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 112K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + ccmram (rw): ORIGIN = 0x10000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 112K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K } /* GROUP(libcs3_stm32_high_density.a) */ @@ -15,6 +16,7 @@ REGION_ALIAS("REGION_TEXT", rom); REGION_ALIAS("REGION_DATA", ram); REGION_ALIAS("REGION_BSS", ram); REGION_ALIAS("REGION_RODATA", rom); +REGION_ALIAS("REGION_CCMRAM", ccmram); _FLASH_BUILD = 1; INCLUDE common.inc diff --git a/STM32F4/variants/discovery_f407/ld/ram.ld b/STM32F4/variants/discovery_f407/ld/ram.ld index 0928b94d4..b57060c92 100644 --- a/STM32F4/variants/discovery_f407/ld/ram.ld +++ b/STM32F4/variants/discovery_f407/ld/ram.ld @@ -6,7 +6,6 @@ MEMORY { ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K - /* rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K ala42 */ rom (rx) : ORIGIN = 0x08010000, LENGTH = 0K /* ala42 */ } diff --git a/STM32F4/variants/discovery_f407/ld/vector_symbols.inc b/STM32F4/variants/discovery_f407/ld/vector_symbols.inc index f8519bba4..853c4f50b 100644 --- a/STM32F4/variants/discovery_f407/ld/vector_symbols.inc +++ b/STM32F4/variants/discovery_f407/ld/vector_symbols.inc @@ -26,18 +26,18 @@ EXTERN(__irq_exti1) EXTERN(__irq_exti2) EXTERN(__irq_exti3) EXTERN(__irq_exti4) -EXTERN(__irq_dma1_channel1) -EXTERN(__irq_dma1_channel2) -EXTERN(__irq_dma1_channel3) -EXTERN(__irq_dma1_channel4) -EXTERN(__irq_dma1_channel5) -EXTERN(__irq_dma1_channel6) -EXTERN(__irq_dma1_channel7) +EXTERN(__irq_dma1_stream0) +EXTERN(__irq_dma1_stream1) +EXTERN(__irq_dma1_stream2) +EXTERN(__irq_dma1_stream3) +EXTERN(__irq_dma1_stream4) +EXTERN(__irq_dma1_stream5) +EXTERN(__irq_dma1_stream6) EXTERN(__irq_adc) -EXTERN(__irq_usb_hp_can_tx) -EXTERN(__irq_usb_lp_can_rx0) -EXTERN(__irq_can_rx1) -EXTERN(__irq_can_sce) +EXTERN(__irq_can1_tx) +EXTERN(__irq_can1_rx0) +EXTERN(__irq_can1_rx1) +EXTERN(__irq_can1_sce) EXTERN(__irq_exti9_5) EXTERN(__irq_tim1_brk) EXTERN(__irq_tim1_up) @@ -58,21 +58,42 @@ EXTERN(__irq_usart3) EXTERN(__irq_exti15_10) EXTERN(__irq_rtcalarm) EXTERN(__irq_usbwakeup) - EXTERN(__irq_tim8_brk) EXTERN(__irq_tim8_up) EXTERN(__irq_tim8_trg_com) EXTERN(__irq_tim8_cc) -EXTERN(__irq_adc3) +EXTERN(__irq_dma1_stream7) EXTERN(__irq_fsmc) EXTERN(__irq_sdio) EXTERN(__irq_tim5) EXTERN(__irq_spi3) EXTERN(__irq_uart4) EXTERN(__irq_uart5) -EXTERN(__irq_tim6) +EXTERN(__irq_tim6_dac) EXTERN(__irq_tim7) -EXTERN(__irq_dma2_channel1) -EXTERN(__irq_dma2_channel2) -EXTERN(__irq_dma2_channel3) -EXTERN(__irq_dma2_channel4_5) +EXTERN(__irq_dma2_stream0) +EXTERN(__irq_dma2_stream1) +EXTERN(__irq_dma2_stream2) +EXTERN(__irq_dma2_stream3) +EXTERN(__irq_dma2_stream4) +EXTERN(__irq_eth) +EXTERN(__irq_eth_wkup) +EXTERN(__irq_can2_tx) +EXTERN(__irq_can2_rx0) +EXTERN(__irq_can2_rx1) +EXTERN(__irq_can2_sce) +EXTERN(__irq_usb_fs) +EXTERN(__irq_dma2_stream5) +EXTERN(__irq_dma2_stream6) +EXTERN(__irq_dma2_stream7) +EXTERN(__irq_usart6) +EXTERN(__irq_i2c3_ev) +EXTERN(__irq_i2c3_er) +EXTERN(__irq_usb_hs_ep1_out) +EXTERN(__irq_usb_hs_ep1_in) +EXTERN(__irq_usb_hs_wkup) +EXTERN(__irq_usb_hs) +EXTERN(__irq_dcmi) +EXTERN(__irq_cryp) +EXTERN(__irq_hash_rng) +EXTERN(__irq_fpu) diff --git a/STM32F4/variants/discovery_f407/stm32_isrs.S b/STM32F4/variants/discovery_f407/stm32_isrs.S deleted file mode 100644 index 34e515c08..000000000 --- a/STM32F4/variants/discovery_f407/stm32_isrs.S +++ /dev/null @@ -1,323 +0,0 @@ -/* STM32 ISR weak declarations */ - - .thumb - -/* Default handler for all non-overridden interrupts and exceptions */ - .globl __default_handler - .type __default_handler, %function - -__default_handler: - b . - - .weak __exc_nmi - .globl __exc_nmi - .set __exc_nmi, __default_handler - .weak __exc_hardfault - .globl __exc_hardfault - .set __exc_hardfault, __default_handler - .weak __exc_memmanage - .globl __exc_memmanage - .set __exc_memmanage, __default_handler - .weak __exc_busfault - .globl __exc_busfault - .set __exc_busfault, __default_handler - .weak __exc_usagefault - .globl __exc_usagefault - .set __exc_usagefault, __default_handler - .weak __stm32reservedexception7 - .globl __stm32reservedexception7 - .set __stm32reservedexception7, __default_handler - .weak __stm32reservedexception8 - .globl __stm32reservedexception8 - .set __stm32reservedexception8, __default_handler - .weak __stm32reservedexception9 - .globl __stm32reservedexception9 - .set __stm32reservedexception9, __default_handler - .weak __stm32reservedexception10 - .globl __stm32reservedexception10 - .set __stm32reservedexception10, __default_handler - .weak __exc_svc - .globl __exc_svc - .set __exc_svc, __default_handler - .weak __exc_debug_monitor - .globl __exc_debug_monitor - .set __exc_debug_monitor, __default_handler - .weak __stm32reservedexception13 - .globl __stm32reservedexception13 - .set __stm32reservedexception13, __default_handler - .weak __exc_pendsv - .globl __exc_pendsv - .set __exc_pendsv, __default_handler - .weak __exc_systick - .globl __exc_systick - .set __exc_systick, __default_handler - .weak __irq_wwdg - .globl __irq_wwdg - .set __irq_wwdg, __default_handler - .weak __irq_pvd - .globl __irq_pvd - .set __irq_pvd, __default_handler - .weak __irq_tamper - .globl __irq_tamper - .set __irq_tamper, __default_handler - .weak __irq_rtc - .globl __irq_rtc - .set __irq_rtc, __default_handler - .weak __irq_flash - .globl __irq_flash - .set __irq_flash, __default_handler - .weak __irq_rcc - .globl __irq_rcc - .set __irq_rcc, __default_handler - .weak __irq_exti0 - .globl __irq_exti0 - .set __irq_exti0, __default_handler - .weak __irq_exti1 - .globl __irq_exti1 - .set __irq_exti1, __default_handler - .weak __irq_exti2 - .globl __irq_exti2 - .set __irq_exti2, __default_handler - .weak __irq_exti3 - .globl __irq_exti3 - .set __irq_exti3, __default_handler - .weak __irq_exti4 - .globl __irq_exti4 - .set __irq_exti4, __default_handler - .weak __irq_dma1_channel1 - .globl __irq_dma1_channel1 - .set __irq_dma1_channel1, __default_handler - .weak __irq_dma1_channel2 - .globl __irq_dma1_channel2 - .set __irq_dma1_channel2, __default_handler - .weak __irq_dma1_channel3 - .globl __irq_dma1_channel3 - .set __irq_dma1_channel3, __default_handler - .weak __irq_dma1_channel4 - .globl __irq_dma1_channel4 - .set __irq_dma1_channel4, __default_handler - .weak __irq_dma1_channel5 - .globl __irq_dma1_channel5 - .set __irq_dma1_channel5, __default_handler - .weak __irq_dma1_channel6 - .globl __irq_dma1_channel6 - .set __irq_dma1_channel6, __default_handler - .weak __irq_dma1_channel7 - .globl __irq_dma1_channel7 - .set __irq_dma1_channel7, __default_handler - .weak __irq_adc - .globl __irq_adc - .set __irq_adc, __default_handler - .weak __irq_usb_hp_can_tx - .globl __irq_usb_hp_can_tx - .set __irq_usb_hp_can_tx, __default_handler - .weak __irq_usb_lp_can_rx0 - .globl __irq_usb_lp_can_rx0 - .set __irq_usb_lp_can_rx0, __default_handler - .weak __irq_can_rx1 - .globl __irq_can_rx1 - .set __irq_can_rx1, __default_handler - .weak __irq_can_sce - .globl __irq_can_sce - .set __irq_can_sce, __default_handler - .weak __irq_exti9_5 - .globl __irq_exti9_5 - .set __irq_exti9_5, __default_handler - .weak __irq_tim1_brk - .globl __irq_tim1_brk - .set __irq_tim1_brk, __default_handler - .weak __irq_tim1_up - .globl __irq_tim1_up - .set __irq_tim1_up, __default_handler - .weak __irq_tim1_trg_com - .globl __irq_tim1_trg_com - .set __irq_tim1_trg_com, __default_handler - .weak __irq_tim1_cc - .globl __irq_tim1_cc - .set __irq_tim1_cc, __default_handler - .weak __irq_tim2 - .globl __irq_tim2 - .set __irq_tim2, __default_handler - .weak __irq_tim3 - .globl __irq_tim3 - .set __irq_tim3, __default_handler - .weak __irq_tim4 - .globl __irq_tim4 - .set __irq_tim4, __default_handler - .weak __irq_i2c1_ev - .globl __irq_i2c1_ev - .set __irq_i2c1_ev, __default_handler - .weak __irq_i2c1_er - .globl __irq_i2c1_er - .set __irq_i2c1_er, __default_handler - .weak __irq_i2c2_ev - .globl __irq_i2c2_ev - .set __irq_i2c2_ev, __default_handler - .weak __irq_i2c2_er - .globl __irq_i2c2_er - .set __irq_i2c2_er, __default_handler - .weak __irq_spi1 - .globl __irq_spi1 - .set __irq_spi1, __default_handler - .weak __irq_spi2 - .globl __irq_spi2 - .set __irq_spi2, __default_handler - .weak __irq_usart1 - .globl __irq_usart1 - .set __irq_usart1, __default_handler - .weak __irq_usart2 - .globl __irq_usart2 - .set __irq_usart2, __default_handler - .weak __irq_usart3 - .globl __irq_usart3 - .set __irq_usart3, __default_handler - .weak __irq_exti15_10 - .globl __irq_exti15_10 - .set __irq_exti15_10, __default_handler - .weak __irq_rtcalarm - .globl __irq_rtcalarm - .set __irq_rtcalarm, __default_handler - .weak __irq_usbwakeup - .globl __irq_usbwakeup - .set __irq_usbwakeup, __default_handler -#if defined (STM32_HIGH_DENSITY) - .weak __irq_tim8_brk - .globl __irq_tim8_brk - .set __irq_tim8_brk, __default_handler - .weak __irq_tim8_up - .globl __irq_tim8_up - .set __irq_tim8_up, __default_handler - .weak __irq_tim8_trg_com - .globl __irq_tim8_trg_com - .set __irq_tim8_trg_com, __default_handler - .weak __irq_tim8_cc - .globl __irq_tim8_cc - .set __irq_tim8_cc, __default_handler - .weak __irq_adc3 - .globl __irq_adc3 - .set __irq_adc3, __default_handler - .weak __irq_fsmc - .globl __irq_fsmc - .set __irq_fsmc, __default_handler - .weak __irq_sdio - .globl __irq_sdio - .set __irq_sdio, __default_handler - .weak __irq_tim5 - .globl __irq_tim5 - .set __irq_tim5, __default_handler - .weak __irq_spi3 - .globl __irq_spi3 - .set __irq_spi3, __default_handler - .weak __irq_uart4 - .globl __irq_uart4 - .set __irq_uart4, __default_handler - .weak __irq_uart5 - .globl __irq_uart5 - .set __irq_uart5, __default_handler - .weak __irq_tim6 - .globl __irq_tim6 - .set __irq_tim6, __default_handler - .weak __irq_tim7 - .globl __irq_tim7 - .set __irq_tim7, __default_handler - .weak __irq_dma2_channel1 - .globl __irq_dma2_channel1 - .set __irq_dma2_channel1, __default_handler - .weak __irq_dma2_channel2 - .globl __irq_dma2_channel2 - .set __irq_dma2_channel2, __default_handler - .weak __irq_dma2_channel3 - .globl __irq_dma2_channel3 - .set __irq_dma2_channel3, __default_handler - .weak __irq_dma2_channel4_5 - .globl __irq_dma2_channel4_5 - .set __irq_dma2_channel4_5, __default_handler -#endif /* STM32_HIGH_DENSITY */ - - .weak __irq_DMA2_Stream4_IRQHandler - .globl __irq_DMA2_Stream4_IRQHandler - .set __irq_DMA2_Stream4_IRQHandler, __default_handler - - .weak __irq_ETH_IRQHandler - .globl __irq_ETH_IRQHandler - .set __irq_ETH_IRQHandler, __default_handler - - .weak __irq_ETH_WKUP_IRQHandler - .globl __irq_ETH_WKUP_IRQHandler - .set __irq_ETH_WKUP_IRQHandler, __default_handler - - .weak __irq_CAN2_TX_IRQHandler - .globl __irq_CAN2_TX_IRQHandler - .set __irq_CAN2_TX_IRQHandler, __default_handler - - .weak __irq_CAN2_RX0_IRQHandler - .globl __irq_CAN2_RX0_IRQHandler - .set __irq_CAN2_RX0_IRQHandler, __default_handler - - .weak __irq_CAN2_RX1_IRQHandler - .globl __irq_CAN2_RX1_IRQHandler - .set __irq_CAN2_RX1_IRQHandler, __default_handler - - .weak __irq_CAN2_SCE_IRQHandler - .globl __irq_CAN2_SCE_IRQHandler - .set __irq_CAN2_SCE_IRQHandler, __default_handler - - .weak __irq_OTG_FS_IRQHandler - .globl __irq_OTG_FS_IRQHandler - .set __irq_OTG_FS_IRQHandler, __default_handler - - .weak __irq_DMA2_Stream5_IRQHandler - .globl __irq_DMA2_Stream5_IRQHandler - .set __irq_DMA2_Stream5_IRQHandler, __default_handler - - .weak __irq_DMA2_Stream6_IRQHandler - .globl __irq_DMA2_Stream6_IRQHandler - .set __irq_DMA2_Stream6_IRQHandler, __default_handler - - .weak __irq_DMA2_Stream7_IRQHandler - .globl __irq_DMA2_Stream7_IRQHandler - .set __irq_DMA2_Stream7_IRQHandler, __default_handler - - .weak __irq_USART6_IRQHandler - .globl __irq_USART6_IRQHandler - .set __irq_USART6_IRQHandler, __default_handler - - .weak __irq_I2C3_EV_IRQHandler - .globl __irq_I2C3_EV_IRQHandler - .set __irq_I2C3_EV_IRQHandler, __default_handler - - .weak __irq_I2C3_ER_IRQHandler - .globl __irq_I2C3_ER_IRQHandler - .set __irq_I2C3_ER_IRQHandler, __default_handler - - .weak __irq_OTG_HS_EP1_OUT_IRQHandler - .globl __irq_OTG_HS_EP1_OUT_IRQHandler - .set __irq_OTG_HS_EP1_OUT_IRQHandler, __default_handler - - .weak __irq_OTG_HS_EP1_IN_IRQHandler - .globl __irq_OTG_HS_EP1_IN_IRQHandler - .set __irq_OTG_HS_EP1_IN_IRQHandler, __default_handler - - .weak __irq_OTG_HS_WKUP_IRQHandler - .globl __irq_OTG_HS_WKUP_IRQHandler - .set __irq_OTG_HS_WKUP_IRQHandler, __default_handler - - .weak __irq_OTG_HS_IRQHandler - .globl __irq_OTG_HS_IRQHandler - .set __irq_OTG_HS_IRQHandler, __default_handler - - .weak __irq_DCMI_IRQHandler - .globl __irq_DCMI_IRQHandler - .set __irq_DCMI_IRQHandler, __default_handler - - .weak __irq_CRYP_IRQHandler - .globl __irq_CRYP_IRQHandler - .set __irq_CRYP_IRQHandler, __default_handler - - .weak __irq_HASH_RNG_IRQHandler - .globl __irq_HASH_RNG_IRQHandler - .set __irq_HASH_RNG_IRQHandler, __default_handler - - .weak __irq_FPU_IRQHandler - .globl __irq_FPU_IRQHandler - .set __irq_FPU_IRQHandler, __default_handler diff --git a/STM32F4/variants/discovery_f407/stm32_vector_table.S b/STM32F4/variants/discovery_f407/stm32_vector_table.S deleted file mode 100644 index 9f08d6669..000000000 --- a/STM32F4/variants/discovery_f407/stm32_vector_table.S +++ /dev/null @@ -1,113 +0,0 @@ -/* STM32 vector table */ - - .section ".stm32.interrupt_vector" - - .globl __stm32_vector_table - .type __stm32_vector_table, %object - -__stm32_vector_table: -/* CM3 core interrupts */ - .long __msp_init - .long __exc_reset - .long __exc_nmi - .long __exc_hardfault - .long __exc_memmanage - .long __exc_busfault - .long __exc_usagefault - .long __stm32reservedexception7 - .long __stm32reservedexception8 - .long __stm32reservedexception9 - .long __stm32reservedexception10 - .long __exc_svc - .long __exc_debug_monitor - .long __stm32reservedexception13 - .long __exc_pendsv - .long __exc_systick -/* Peripheral interrupts */ - .long __irq_wwdg - .long __irq_pvd - .long __irq_tamper - .long __irq_rtc - .long __irq_flash - .long __irq_rcc - .long __irq_exti0 - .long __irq_exti1 - .long __irq_exti2 - .long __irq_exti3 - .long __irq_exti4 - .long __irq_dma1_channel1 - .long __irq_dma1_channel2 - .long __irq_dma1_channel3 - .long __irq_dma1_channel4 - .long __irq_dma1_channel5 - .long __irq_dma1_channel6 - .long __irq_dma1_channel7 - .long __irq_adc - .long __irq_usb_hp_can_tx - .long __irq_usb_lp_can_rx0 - .long __irq_can_rx1 - .long __irq_can_sce - .long __irq_exti9_5 - .long __irq_tim1_brk - .long __irq_tim1_up - .long __irq_tim1_trg_com - .long __irq_tim1_cc - .long __irq_tim2 - .long __irq_tim3 - .long __irq_tim4 - .long __irq_i2c1_ev - .long __irq_i2c1_er - .long __irq_i2c2_ev - .long __irq_i2c2_er - .long __irq_spi1 - .long __irq_spi2 - .long __irq_usart1 - .long __irq_usart2 - .long __irq_usart3 - .long __irq_exti15_10 - .long __irq_rtcalarm - .long __irq_usbwakeup -#if defined (STM32_HIGH_DENSITY) - .long __irq_tim8_brk - .long __irq_tim8_up - .long __irq_tim8_trg_com - .long __irq_tim8_cc - .long __irq_adc3 - .long __irq_fsmc - .long __irq_sdio - .long __irq_tim5 - .long __irq_spi3 - .long __irq_uart4 - .long __irq_uart5 - .long __irq_tim6 - .long __irq_tim7 - .long __irq_dma2_channel1 - .long __irq_dma2_channel2 - .long __irq_dma2_channel3 - .long __irq_dma2_channel4_5 -#endif /* STM32_HIGH_DENSITY */ - - .long __irq_DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ - .long __irq_ETH_IRQHandler /* Ethernet */ - .long __irq_ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */ - .long __irq_CAN2_TX_IRQHandler /* CAN2 TX */ - .long __irq_CAN2_RX0_IRQHandler /* CAN2 RX0 */ - .long __irq_CAN2_RX1_IRQHandler /* CAN2 RX1 */ - .long __irq_CAN2_SCE_IRQHandler /* CAN2 SCE */ - .long __irq_OTG_FS_IRQHandler /* USB OTG FS */ - .long __irq_DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ - .long __irq_DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ - .long __irq_DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ - .long __irq_USART6_IRQHandler /* USART6 */ - .long __irq_I2C3_EV_IRQHandler /* I2C3 event */ - .long __irq_I2C3_ER_IRQHandler /* I2C3 error */ - .long __irq_OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ - .long __irq_OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ - .long __irq_OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ - .long __irq_OTG_HS_IRQHandler /* USB OTG HS */ - .long __irq_DCMI_IRQHandler /* DCMI */ - .long __irq_CRYP_IRQHandler /* CRYP crypto */ - .long __irq_HASH_RNG_IRQHandler /* Hash and Rng */ - .long __irq_FPU_IRQHandler /* FPU */ - - .size __stm32_vector_table, . - __stm32_vector_table diff --git a/STM32F4/variants/discovery_f407/variant.h b/STM32F4/variants/discovery_f407/variant.h index 8782ccc71..74719a979 100644 --- a/STM32F4/variants/discovery_f407/variant.h +++ b/STM32F4/variants/discovery_f407/variant.h @@ -1,16 +1,6 @@ #ifndef _VARIANT_ARDUINO_STM32_ #define _VARIANT_ARDUINO_STM32_ -#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device ) -#define digitalPinToBitMask(P) ( BIT(P&0x0F) ) -#define portOutputRegister(port) ( &(port->regs->ODR) ) -#define portInputRegister(port) ( &(port->regs->IDR) ) - -#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) ) -#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) ) - -#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) ) - static const uint8_t SS = BOARD_SPI1_NSS_PIN; static const uint8_t SS1 = BOARD_SPI2_NSS_PIN; static const uint8_t MOSI = BOARD_SPI1_MOSI_PIN; diff --git a/STM32F4/variants/discovery_f407/wirish/start_c.c b/STM32F4/variants/discovery_f407/wirish/start_c.c deleted file mode 100644 index 655fefb88..000000000 --- a/STM32F4/variants/discovery_f407/wirish/start_c.c +++ /dev/null @@ -1,95 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* - * This file is a modified version of a file obtained from - * CodeSourcery Inc. (now part of Mentor Graphics Corp.), in which the - * following text appeared: - * - * Copyright (c) 2006, 2007 CodeSourcery Inc - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ - -#include - -extern void __libc_init_array(void); - -extern int main(int, char**, char**); - -extern void exit(int) __attribute__((noreturn, weak)); - -/* The linker must ensure that these are at least 4-byte aligned. */ -extern char __data_start__, __data_end__; -extern char __bss_start__, __bss_end__; - -struct rom_img_cfg { - int *img_start; -}; - -extern char _lm_rom_img_cfgp; - -void __attribute__((noreturn)) start_c(void) { - struct rom_img_cfg *img_cfg = (struct rom_img_cfg*)&_lm_rom_img_cfgp; - int *src = img_cfg->img_start; - int *dst = (int*)&__data_start__; - int exit_code; - - /* Initialize .data, if necessary. */ - if (src != dst) { - int *end = (int*)&__data_end__; - while (dst < end) { - *dst++ = *src++; - } - } - - /* Zero .bss. */ - dst = (int*)&__bss_start__; - while (dst < (int*)&__bss_end__) { - *dst++ = 0; - } - - /* Run initializers. */ - __libc_init_array(); - - /* Jump to main. */ - exit_code = main(0, 0, 0); - if (exit) { - exit(exit_code); - } - - /* If exit is NULL, make sure we don't return. */ - for (;;) - continue; -} diff --git a/STM32F4/variants/generic_f407v/generic_f407v.cpp b/STM32F4/variants/generic_f407v/generic_f407v.cpp index c51ff9b55..3e4395a40 100644 --- a/STM32F4/variants/generic_f407v/generic_f407v.cpp +++ b/STM32F4/variants/generic_f407v/generic_f407v.cpp @@ -30,41 +30,38 @@ * @brief generic_f407v board file. */ -#ifdef BOARD_generic_f407v - #include "generic_f407v.h" -#include "wirish_types.h" +#include //static void initSRAMChip(void); /*****************************************************************************/ // Alternate functions, see DocID022152 Rev 8, Table 9. /*****************************************************************************/ void boardInit(void) { -/* // remap TIMER8 to PC6-9 - gpio_set_af_mode(GPIOC, 6, 3); - gpio_set_af_mode(GPIOC, 7, 3); - gpio_set_af_mode(GPIOC, 8, 3); - gpio_set_af_mode(GPIOC, 9, 3); - - // remap TIMER1 to PE9,11,13,14 - gpio_set_af_mode(GPIOE, 9, 1); - gpio_set_af_mode(GPIOE, 11, 1); - gpio_set_af_mode(GPIOE, 13, 1); - gpio_set_af_mode(GPIOE, 14, 1); - // remap TIMER3 to PB4,5,0,1 - gpio_set_af_mode(GPIOB, 4, 2); - gpio_set_af_mode(GPIOB, 5, 2); - gpio_set_af_mode(GPIOB, 0, 2); - gpio_set_af_mode(GPIOB, 1, 2); - - //gpio_set_af_mode(GPIOA, 2, 7); - //gpio_set_af_mode(GPIOA, 3, 7); -*/ return; } +/* to be defined +const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 +}; +*/ +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] = { + PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PB0, PB1, PC0, PC1, PC2, PC3, PC4, PC5 +}; + +const uint8 boardUsedPins[BOARD_NR_USED_PINS] = { + BOARD_LED_PIN, BOARD_LED2_PIN, BOARD_BUTTON1_PIN, BOARD_BUTTON2_PIN, BOARD_BUTTON2_PIN, + BOARD_JTMS_SWDIO_PIN, BOARD_JTCK_SWCLK_PIN, + FLASH_CS_PIN, FLASH_CLK_PIN, FLASH_DO_PIN, FLASH_DI_PIN, + NRF24_CE_PIN, NRF24_CS_PIN, NRF24_IRQ_PIN, + BOARD_SDIO_D0, BOARD_SDIO_D1, BOARD_SDIO_D2, BOARD_SDIO_D3, BOARD_SDIO_CLK, BOARD_SDIO_CMD, + USB_DM_PIN, USB_DP_PIN +}; + + /* static void initSRAMChip(void) { fsmc_nor_psram_reg_map *regs = FSMC_NOR_PSRAM1_BASE; @@ -78,4 +75,3 @@ static void initSRAMChip(void) { fsmc_nor_psram_set_datast(regs, 3); } */ -#endif diff --git a/STM32F4/variants/generic_f407v/generic_f407v.h b/STM32F4/variants/generic_f407v/generic_f407v.h index bc3b77b69..108695927 100644 --- a/STM32F4/variants/generic_f407v/generic_f407v.h +++ b/STM32F4/variants/generic_f407v/generic_f407v.h @@ -35,76 +35,88 @@ #ifndef _BOARD_GENERIC_F407V_H_ #define _BOARD_GENERIC_F407V_H_ -#define Port2Pin(port, bit) ((port-'A')*16+bit) -#define CYCLES_PER_MICROSECOND 168 +#define CLOCK_SPEED_MHZ 168 -#undef STM32_PCLK1 -#undef STM32_PCLK2 -#define STM32_PCLK1 (CYCLES_PER_MICROSECOND*1000000/4) -#define STM32_PCLK2 (CYCLES_PER_MICROSECOND*1000000/2) - -#define SYSTICK_RELOAD_VAL (CYCLES_PER_MICROSECOND*1000-1) - /*****************************************************************************/ // Board pin definitions #define BOARD_USB_DM_PIN PA11 #define BOARD_USB_DP_PIN PA12 -#define BOARD_LED_PIN PA6 //Port2Pin('A', 6) -#define BOARD_LED2_PIN PA7 //Port2Pin('A', 7) -#define BOARD_BUTTON1_PIN PA0 //Port2Pin('A', 0) -#define BOARD_BUTTON2_PIN PE4 //Port2Pin('E', 4) -#define BOARD_BUTTON3_PIN PE3 //Port2Pin('E', 3) - -#define BOARD_NR_USARTS 5 -#define BOARD_USART1_TX_PIN PA9 //Port2Pin('A', 9) -#define BOARD_USART1_RX_PIN PA10 //Port2Pin('A',10) -#define BOARD_USART2_TX_PIN PA2 //Port2Pin('A', 2) -#define BOARD_USART2_RX_PIN PA3 //Port2Pin('A', 3) -#define BOARD_USART3_TX_PIN PB10 //Port2Pin('B',10) -#define BOARD_USART3_RX_PIN PB11 //Port2Pin('B',11) -#define BOARD_UART4_TX_PIN PA0 //Port2Pin('A', 0) -#define BOARD_UART4_RX_PIN PA1 //Port2Pin('A', 1) -#define BOARD_UART5_TX_PIN PC12 //Port2Pin('C',12) -#define BOARD_UART5_RX_PIN PD2 //Port2Pin('D', 2) +#define BOARD_LED_PIN PA6 +#define BOARD_LED2_PIN PA7 +#define BOARD_BUTTON1_PIN PA0 +#define BOARD_BUTTON2_PIN PE4 +#define BOARD_BUTTON3_PIN PE3 + +#define BOARD_NR_USARTS 6 +#define BOARD_USART1_TX_PIN PA9 +#define BOARD_USART1_RX_PIN PA10 +#define BOARD_USART2_TX_PIN PA2 +#define BOARD_USART2_RX_PIN PA3 +#define BOARD_USART3_TX_PIN PB10 +#define BOARD_USART3_RX_PIN PB11 +#define BOARD_UART4_TX_PIN PA0 +#define BOARD_UART4_RX_PIN PA1 +#define BOARD_UART5_TX_PIN PC12 // SDIO_CLK !! +#define BOARD_UART5_RX_PIN PD2 // SDIO_CMD +#define BOARD_USART6_TX_PIN PC6 // DCMI_D0 !! +#define BOARD_USART6_RX_PIN PC7 // DCMI_D1 !! + +#define BOARD_NR_I2C 3 +#define BOARD_I2C1_SCL_PIN PB6 +#define BOARD_I2C1_SDA_PIN PB7 +#define BOARD_I2C1A_SCL_PIN PB8 +#define BOARD_I2C1A_SDA_PIN PB9 +#define BOARD_I2C2_SCL_PIN PB10 +#define BOARD_I2C2_SDA_PIN PB11 +#ifdef PACKAGE_LQFP144 +#define BOARD_I2C2A_SCL_PIN PF1 +#define BOARD_I2C2A_SDA_PIN PF0 +#endif +#define BOARD_I2C3_SCL_PIN PA8 +#define BOARD_I2C3_SDA_PIN PC9 +#ifdef PACKAGE_LQFP144 +#define BOARD_I2C3A_SCL_PIN PH7 +#define BOARD_I2C3A_SDA_PIN PH8 +#endif #define BOARD_NR_SPI 3 -#define BOARD_SPI1_NSS_PIN PA4 //Port2Pin('A', 4) -#define BOARD_SPI1_SCK_PIN PA5 //Port2Pin('A', 5) -#define BOARD_SPI1_MISO_PIN PA6 //Port2Pin('A', 6) -#define BOARD_SPI1_MOSI_PIN PA7 //Port2Pin('A', 7) -#define BOARD_SPI1A_NSS_PIN PA15 //Port2Pin('A',15) -#define BOARD_SPI1A_SCK_PIN PB3 //Port2Pin('B', 3) -#define BOARD_SPI1A_MISO_PIN PB4 //Port2Pin('B', 4) -#define BOARD_SPI1A_MOSI_PIN PB5 //Port2Pin('B', 5) - -#define BOARD_SPI2_NSS_PIN PB12 //Port2Pin('B',12) -#define BOARD_SPI2_SCK_PIN PB13 //Port2Pin('B',13) -#define BOARD_SPI2_MISO_PIN PB14 //Port2Pin('B',14) -#define BOARD_SPI2_MOSI_PIN PB15 //Port2Pin('B',15) -#define BOARD_SPI2A_NSS_PIN PB9 //Port2Pin('B', 9) -#define BOARD_SPI2A_SCK_PIN PB10 //Port2Pin('B',10) -#define BOARD_SPI2A_MISO_PIN PC2 //Port2Pin('C', 2) -#define BOARD_SPI2A_MOSI_PIN PC3 //Port2Pin('C', 3) - -#define BOARD_SPI3_NSS_PIN PA15 //Port2Pin('A',15) -#define BOARD_SPI3_SCK_PIN PB3 //Port2Pin('B', 3) -#define BOARD_SPI3_MISO_PIN PB4 //Port2Pin('B', 4) -#define BOARD_SPI3_MOSI_PIN PB5 //Port2Pin('B', 5) +#define BOARD_SPI1_NSS_PIN PA4 +#define BOARD_SPI1_SCK_PIN PA5 +#define BOARD_SPI1_MISO_PIN PA6 +#define BOARD_SPI1_MOSI_PIN PA7 +#define BOARD_SPI1A_NSS_PIN PA15 +#define BOARD_SPI1A_SCK_PIN PB3 +#define BOARD_SPI1A_MISO_PIN PB4 +#define BOARD_SPI1A_MOSI_PIN PB5 + +#define BOARD_SPI2_NSS_PIN PB12 +#define BOARD_SPI2_SCK_PIN PB13 +#define BOARD_SPI2_MISO_PIN PB14 +#define BOARD_SPI2_MOSI_PIN PB15 +#define BOARD_SPI2A_NSS_PIN PB9 +#define BOARD_SPI2A_SCK_PIN PB10 +#define BOARD_SPI2A_MISO_PIN PC2 +#define BOARD_SPI2A_MOSI_PIN PC3 + +#define BOARD_SPI3_NSS_PIN PA15 +#define BOARD_SPI3_SCK_PIN PB3 +#define BOARD_SPI3_MISO_PIN PB4 +#define BOARD_SPI3_MOSI_PIN PB5 /* overlap with the SDIO interface for SD card -#define BOARD_SPI3A_NSS_PIN PA4 //Port2Pin('A', 4) -#define BOARD_SPI3A_SCK_PIN PC10 //Port2Pin('C',10) -#define BOARD_SPI3A_MISO_PIN PC11 //Port2Pin('C',11) -#define BOARD_SPI3A_MOSI_PIN PC12 //Port2Pin('C',12) +#define BOARD_SPI3A_NSS_PIN PA4 +#define BOARD_SPI3A_SCK_PIN PC10 +#define BOARD_SPI3A_MISO_PIN PC11 +#define BOARD_SPI3A_MOSI_PIN PC12 */ -#define BOARD_SDIO_D0 PC8 //Port2Pin('C', 8) -#define BOARD_SDIO_D1 PC9 //Port2Pin('C', 9) -#define BOARD_SDIO_D2 PC10 //Port2Pin('C',10) -#define BOARD_SDIO_D3 PC11 //Port2Pin('C',11) -#define BOARD_SDIO_CLK PC12 //Port2Pin('C',12) -#define BOARD_SDIO_CMD PD2 //Port2Pin('D', 2) +#define BOARD_SDIO_D0 PC8 +#define BOARD_SDIO_D1 PC9 +#define BOARD_SDIO_D2 PC10 +#define BOARD_SDIO_D3 PC11 +#define BOARD_SDIO_CLK PC12 +#define BOARD_SDIO_CMD PD2 #define FSMC_NOE PD4 #define FSMC_NWE PD5 @@ -129,13 +141,32 @@ #define FSMC_D14 PD9 #define FSMC_D15 PD10 +#define DCMI_PCLK PA6 +#define DCMI_HSYNC PA4 // PA4/PH8 +#define DCMI_VSYNC PB7 // PB7/PI5 +#define DCMI_D0 PC6 // PA9/PC6/PH9 +#define DCMI_D1 PC7 // PA10/PC7/PH10 +#define DCMI_D2 PC8 // PC8/PE0/PH11 +#define DCMI_D3 PC9 // PC9/PE1/PH12 +#define DCMI_D4 PE4 // PC11/PE4/PH14 +#define DCMI_D5 PB6 // PB6/PI4 +#define DCMI_D6 PE5 // PB8/PE5/PI6 +#define DCMI_D7 PE6 // PB9/PE6/PI7 +#define DCMI_D8 PC10 // PC10/PI1 +#define DCMI_D9 PC12 // PC12/PI2 +#define DCMI_D10 PB5 // PB5/PI3 +#define DCMI_D11 PD2 // PD2/PH15 +#ifdef PACKAGE_LQFP144 +#define DCMI_D12 PF11 +#define DCMI_D13 PG15 // PG15/PI0 +#endif + #define BOARD_T_CS BOARD_SPI2_NSS_PIN #define BOARD_T_SCK BOARD_SPI2_SCK_PIN #define BOARD_T_MISO BOARD_SPI2_MISO_PIN #define BOARD_T_MOSI BOARD_SPI2_MOSI_PIN #define BOARD_T_PEN PC5 -#define BOARD_NR_GPIO_PINS 80 #define BOARD_NR_PWM_PINS 22 #define BOARD_NR_ADC_PINS 16 #define BOARD_NR_USED_PINS 22 @@ -183,10 +214,11 @@ PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15, PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PC8,PC9,PC10,PC11,PC12,PC13,PC14,PC15, PD0,PD1,PD2,PD3,PD4,PD5,PD6,PD7,PD8,PD9,PD10,PD11,PD12,PD13,PD14,PD15, PE0,PE1,PE2,PE3,PE4,PE5,PE6,PE7,PE8,PE9,PE10,PE11,PE12,PE13,PE14,PE15, -#if 0 // not available on LQFP100 package +#ifdef PACKAGE_LQFP144 PF0,PF1,PF2,PF3,PF4,PF5,PF6,PF7,PF8,PF9,PF10,PF11,PF12,PF13,PF14,PF15, -PG0,PG1,PG2,PG3,PG4,PG5,PG6,PG7,PG8,PG9,PG10,PG11,PG12,PG13,PG14,PG15 -#endif // not available on LQFP100 package +PG0,PG1,PG2,PG3,PG4,PG5,PG6,PG7,PG8,PG9,PG10,PG11,PG12,PG13,PG14,PG15, +#endif +BOARD_NR_GPIO_PINS }; #endif diff --git a/STM32F4/variants/generic_f407v/ld/bootloader_8004000.ld b/STM32F4/variants/generic_f407v/ld/bootloader_8004000.ld index 677683e24..40386248f 100644 --- a/STM32F4/variants/generic_f407v/ld/bootloader_8004000.ld +++ b/STM32F4/variants/generic_f407v/ld/bootloader_8004000.ld @@ -16,6 +16,7 @@ REGION_ALIAS("REGION_TEXT", rom); REGION_ALIAS("REGION_DATA", ram); REGION_ALIAS("REGION_BSS", ram); REGION_ALIAS("REGION_RODATA", rom); +REGION_ALIAS("REGION_CCMRAM", ccmram); _FLASH_BUILD = 1; INCLUDE common.inc diff --git a/STM32F4/variants/generic_f407v/ld/common.inc b/STM32F4/variants/generic_f407v/ld/common.inc index 30c49c2d0..0cbaeaa44 100644 --- a/STM32F4/variants/generic_f407v/ld/common.inc +++ b/STM32F4/variants/generic_f407v/ld/common.inc @@ -128,21 +128,6 @@ SECTIONS } > REGION_RODATA __exidx_end = .; - /* - * .data - */ - .data : - { - . = ALIGN(8); - __data_start__ = .; - - *(.got.plt) *(.got) - *(.data .data.* .gnu.linkonce.d.*) - - . = ALIGN(8); - __data_end__ = .; - } > REGION_DATA AT> REGION_RODATA - /* * Read-only data */ @@ -155,6 +140,7 @@ SECTIONS . = ALIGN(4); _lm_rom_img_cfgp = .; LONG(LOADADDR(.data)); + LONG(LOADADDR(.ccmdata)); /* * Heap: Linker scripts may choose a custom heap by overriding * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in @@ -164,10 +150,42 @@ SECTIONS * I'm shoving these here naively; there's probably a cleaner way * to go about this. [mbolivar] */ - _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : _end; + _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : __bss_end__; _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init; } > REGION_RODATA + /* + * .data + */ + .data : + { + . = ALIGN(8); + __data_start__ = .; + + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + + . = ALIGN(8); + __data_end__ = .; + } > REGION_DATA AT> REGION_RODATA + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * The startup code is modified to copy the init-values from flash to ccmram + * at startup + */ + .ccmdata : + { + . = ALIGN(4); + __ccmdata_start__ = .; /* create a global symbol at ccmram start */ + *(.ccmdata) + *(.ccmram*) + + . = ALIGN(4); + __ccmdata_end__ = .; /* create a global symbol at ccmram end */ + } >REGION_CCMRAM AT> REGION_RODATA + /* * .bss */ @@ -183,15 +201,6 @@ SECTIONS } > REGION_BSS /* - * .ccmram - */ - .ccmram (NOLOAD): - { - . = ALIGN(8); - *(.ccmram .ccmram.*) - } > ccmram - - /* * Debugging sections */ .stab 0 (NOLOAD) : { *(.stab) } diff --git a/STM32F4/variants/generic_f407v/ld/jtag.ld b/STM32F4/variants/generic_f407v/ld/jtag.ld index 2156f15c1..891e06069 100644 --- a/STM32F4/variants/generic_f407v/ld/jtag.ld +++ b/STM32F4/variants/generic_f407v/ld/jtag.ld @@ -16,6 +16,7 @@ REGION_ALIAS("REGION_TEXT", rom); REGION_ALIAS("REGION_DATA", ram); REGION_ALIAS("REGION_BSS", ram); REGION_ALIAS("REGION_RODATA", rom); +REGION_ALIAS("REGION_CCMRAM", ccmram); _FLASH_BUILD = 1; INCLUDE common.inc diff --git a/STM32F4/variants/generic_f407v/ld/vector_symbols.inc b/STM32F4/variants/generic_f407v/ld/vector_symbols.inc index f8519bba4..853c4f50b 100644 --- a/STM32F4/variants/generic_f407v/ld/vector_symbols.inc +++ b/STM32F4/variants/generic_f407v/ld/vector_symbols.inc @@ -26,18 +26,18 @@ EXTERN(__irq_exti1) EXTERN(__irq_exti2) EXTERN(__irq_exti3) EXTERN(__irq_exti4) -EXTERN(__irq_dma1_channel1) -EXTERN(__irq_dma1_channel2) -EXTERN(__irq_dma1_channel3) -EXTERN(__irq_dma1_channel4) -EXTERN(__irq_dma1_channel5) -EXTERN(__irq_dma1_channel6) -EXTERN(__irq_dma1_channel7) +EXTERN(__irq_dma1_stream0) +EXTERN(__irq_dma1_stream1) +EXTERN(__irq_dma1_stream2) +EXTERN(__irq_dma1_stream3) +EXTERN(__irq_dma1_stream4) +EXTERN(__irq_dma1_stream5) +EXTERN(__irq_dma1_stream6) EXTERN(__irq_adc) -EXTERN(__irq_usb_hp_can_tx) -EXTERN(__irq_usb_lp_can_rx0) -EXTERN(__irq_can_rx1) -EXTERN(__irq_can_sce) +EXTERN(__irq_can1_tx) +EXTERN(__irq_can1_rx0) +EXTERN(__irq_can1_rx1) +EXTERN(__irq_can1_sce) EXTERN(__irq_exti9_5) EXTERN(__irq_tim1_brk) EXTERN(__irq_tim1_up) @@ -58,21 +58,42 @@ EXTERN(__irq_usart3) EXTERN(__irq_exti15_10) EXTERN(__irq_rtcalarm) EXTERN(__irq_usbwakeup) - EXTERN(__irq_tim8_brk) EXTERN(__irq_tim8_up) EXTERN(__irq_tim8_trg_com) EXTERN(__irq_tim8_cc) -EXTERN(__irq_adc3) +EXTERN(__irq_dma1_stream7) EXTERN(__irq_fsmc) EXTERN(__irq_sdio) EXTERN(__irq_tim5) EXTERN(__irq_spi3) EXTERN(__irq_uart4) EXTERN(__irq_uart5) -EXTERN(__irq_tim6) +EXTERN(__irq_tim6_dac) EXTERN(__irq_tim7) -EXTERN(__irq_dma2_channel1) -EXTERN(__irq_dma2_channel2) -EXTERN(__irq_dma2_channel3) -EXTERN(__irq_dma2_channel4_5) +EXTERN(__irq_dma2_stream0) +EXTERN(__irq_dma2_stream1) +EXTERN(__irq_dma2_stream2) +EXTERN(__irq_dma2_stream3) +EXTERN(__irq_dma2_stream4) +EXTERN(__irq_eth) +EXTERN(__irq_eth_wkup) +EXTERN(__irq_can2_tx) +EXTERN(__irq_can2_rx0) +EXTERN(__irq_can2_rx1) +EXTERN(__irq_can2_sce) +EXTERN(__irq_usb_fs) +EXTERN(__irq_dma2_stream5) +EXTERN(__irq_dma2_stream6) +EXTERN(__irq_dma2_stream7) +EXTERN(__irq_usart6) +EXTERN(__irq_i2c3_ev) +EXTERN(__irq_i2c3_er) +EXTERN(__irq_usb_hs_ep1_out) +EXTERN(__irq_usb_hs_ep1_in) +EXTERN(__irq_usb_hs_wkup) +EXTERN(__irq_usb_hs) +EXTERN(__irq_dcmi) +EXTERN(__irq_cryp) +EXTERN(__irq_hash_rng) +EXTERN(__irq_fpu) diff --git a/STM32F4/variants/generic_f407v/pin_map.c b/STM32F4/variants/generic_f407v/pin_map.c deleted file mode 100644 index db5247b02..000000000 --- a/STM32F4/variants/generic_f407v/pin_map.c +++ /dev/null @@ -1,210 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file generic_f407v.cpp - * @author ala42 - * @brief generic_f407v board file. - */ - -#ifdef BOARD_generic_f407v - -#ifdef __cplusplus -extern "C"{ -#endif - -//#include "generic_f407v.h" - -//#include "fsmc.h" -#include -#include -#include - -#include - -extern timer_dev timer1; -extern timer_dev timer2; -extern timer_dev timer3; -extern timer_dev timer4; -extern timer_dev timer5; -extern timer_dev timer6; -extern timer_dev timer7; -extern timer_dev timer8; - -/* -typedef struct stm32_pin_info { - gpio_dev *gpio_device; // Maple pin's GPIO device - timer_dev *timer_device; // Pin's timer device, if any. - uint8 timer_channel; // Timer channel, or 0 if none. - uint8 adc_channel; // Pin ADC channel, or ADCx if none. - const adc_dev *adc_device; // ADC device, if any. -} stm32_pin_info; -*/ -const stm32_pin_info PIN_MAP[] = { // LQFP100 package pin - {&GPIOA, &timer5, 1, 0, &ADC1}, // D00/PA0 | 23 | USART2_CTS | UART4_TX | ETH_MII_CRS | TIM2_CH1_ETR | TIM5_CH1 | TIM8_ETR | ADC123_IN0/WKUP - {&GPIOA, &timer5, 2, 1, &ADC1}, // D01/PA1 | 24 | USART2_RTS | UART4_RX | ETH_RMII_REF_CLK | ETH_MII_RX_CLK | TIM5_CH2 | TIM2_CH2 | ADC123_IN1 - {&GPIOA, &timer5, 3, 2, &ADC1}, // D02/PA2 | 25 | USART2_TX | TIM5_CH3 | TIM9_CH1 | TIM2_CH3 | ETH_MDIO | ADC123_IN2 - {&GPIOA, &timer5, 4, 3, &ADC1}, // D03/PA3 | 26 | USART2_RX | TIM5_CH4 | TIM9_CH2 | TIM2_CH4 | OTG_HS_ULPI_D0 | ETH_MII_COL | ADC123_IN3 - {&GPIOA, NULL, 0, 4, &ADC1}, // D04/PA4 | 29 | SPI1_NSS | SPI3_NSS | USART2_CK | DCMI_HSYNC | OTG_HS_SOF | I2S3_WS | ADC12_IN4 / DAC_OUT1 - {&GPIOA, NULL, 0, 5, &ADC1}, // D05/PA5 | 30 | SPI1_SCK | OTG_HS_ULPI_CK | TIM2_CH1_ETR | TIM8_CH1N | ADC12_IN5 / DAC_OUT2 - {&GPIOA, NULL, 1, 6, &ADC1}, // D06/PA6 | 31 | SPI1_MISO | TIM8_BKIN | TIM13_CH1 | DCMI_PIXCLK | TIM3_CH1 | TIM1_BKIN | ADC12_IN6 - {&GPIOA, NULL, 0, 7, &ADC1}, // D07/PA7 | 32 | SPI1_MOSI | TIM8_CH1N | TIM14_CH1 | TIM3_CH2 | ETH_MII_RX_DV | TIM1_CH1N / ETH_RMII_CRS_DV | ADC12_IN7 - {&GPIOA, NULL, 0, ADCx, NULL}, // D08/PA8 | 67 | MCO1 | USART1_CK | TIM1_CH1 | I2C3_SCL | OTG_FS_SOF - {&GPIOA, NULL, 0, ADCx, NULL}, // D09/PA9 | 68 | USART1_TX | TIM1_CH2 | I2C3_SMBA | DCMI_D0 - {&GPIOA, NULL, 0, ADCx, NULL}, // D10/PA10 | 69 | USART1_RX | TIM1_CH3 | OTG_FS_ID | DCMI_D1 - {&GPIOA, NULL, 0, ADCx, NULL}, // D11/PA11 | 70 | USART1_CTS | CAN1_RX | TIM1_CH4 | OTG_FS_DM - {&GPIOA, NULL, 0, ADCx, NULL}, // D12/PA12 | 71 | USART1_RTS | CAN1_TX | TIM1_ETR | OTG_FS_DP - {&GPIOA, NULL, 0, ADCx, NULL}, // D13/PA13 | 72 | JTMS-SWDIO - {&GPIOA, NULL, 0, ADCx, NULL}, // D14/PA14 | 76 | JTCK-SWCLK - {&GPIOA, &timer2, 1, ADCx, NULL}, // D15/PA15 | 77 | JTDI | SPI3_NSS | I2S3_WS | TIM2_CH1_ETR | SPI1_NSS - - {&GPIOB, &timer3, 3, 8, &ADC1}, // D16/PB0 | 35 | TIM3_CH3 | TIM8_CH2N | OTG_HS_ULPI_D1 | ETH_MII_RXD2 | TIM1_CH2N | ADC12_IN8 - {&GPIOB, &timer3, 4, 9, &ADC1}, // D17/PB1 | 36 | TIM3_CH4 | TIM8_CH3N | OTG_HS_ULPI_D2 | ETH_MII_RXD3 | TIM1_CH3N | ADC12_IN9 - {&GPIOB, NULL, 0, ADCx, NULL}, // D18/PB2 | 37 | BOOT1 - {&GPIOB, &timer2, 2, ADCx, NULL}, // D19/PB3 | 89 | JTDO | TRACESWO | SPI3_SCK | I2S3_CK | TIM2_CH2 | SPI1_SCK - {&GPIOB, &timer3, 1, ADCx, NULL}, // D20/PB4 | 90 | NJTRST | SPI3_MISO | TIM3_CH1 | SPI1_MISO | I2S3ext_SD - {&GPIOB, &timer3, 2, ADCx, NULL}, // D21/PB5 | 91 | I2C1_SMBA | CAN2_RX | OTG_HS_ULPI_D7 | ETH_PPS_OUT | TIM3_CH2 | SPI1_MOSI | SPI3_MOSI | DCMI_D10 | I2S3_SD - {&GPIOB, NULL, 0, ADCx, NULL}, // D22/PB6 | 92 | I2C1_SCL | TIM4_CH1 | CAN2_TX | DCMI_D5 | USART1_TX - {&GPIOB, NULL, 0, ADCx, NULL}, // D23/PB7 | 93 | I2C1_SDA | FSMC_NL | DCMI_VSYNC | USART1_RX | TIM4_CH2 - {&GPIOB, NULL, 0, ADCx, NULL}, // D24/PB8 | 95 | TIM4_CH3 | SDIO_D4 | TIM10_CH1 | DCMI_D6 | ETH_MII_TXD3 | I2C1_SCL | CAN1_RX - {&GPIOB, NULL, 0, ADCx, NULL}, // D25/PB9 | 96 | SPI2_NSS | I2S2_WS | TIM4_CH4 | TIM11_CH1 | SDIO_D5 | DCMI_D7 | I2C1_SDA | CAN1_TX - {&GPIOB, NULL, 0, ADCx, NULL}, // D26/PB10 | 47 | SPI2_SCK | I2S2_CK | I2C2_SCL | USART3_TX | OTG_HS_ULPI_D3 | ETH_MII_RX_ER | TIM2_CH3 - {&GPIOB, NULL, 0, ADCx, NULL}, // D27/PB11 | 48 | I2C2_SDA | USART3_RX | OTG_HS_ULPI_D4 | ETH_RMII_TX_EN | ETH_MII_TX_EN | TIM2_CH4 - {&GPIOB, NULL, 0, ADCx, NULL}, // D28/PB12 | 51 | SPI2_NSS | I2S2_WS | I2C2_SMBA | USART3_CK | TIM1_BKIN | CAN2_RX | OTG_HS_ULPI_D5 | ETH_RMII_TXD0 | ETH_MII_TXD0 | OTG_HS_ID - {&GPIOB, NULL, 0, ADCx, NULL}, // D29/PB13 | 52 | SPI2_SCK | I2S2_CK | USART3_CTS | TIM1_CH1N | CAN2_TX | OTG_HS_ULPI_D6 | ETH_RMII_TXD1 | ETH_MII_TXD1 - {&GPIOB, NULL, 0, ADCx, NULL}, // D30/PB14 | 53 | SPI2_MISO | TIM1_CH2N | TIM12_CH1 | OTG_HS_DM | USART3_RTS | TIM8_CH2N | I2S2ext_SD - {&GPIOB, NULL, 0, ADCx, NULL}, // D31/PB15 | 54 | SPI2_MOSI | I2S2_SD | TIM1_CH3N | TIM8_CH3N | TIM12_CH2 | OTG_HS_DP - - {&GPIOC, NULL, 0, 10, &ADC1}, // D32/PC0 | 15 | OTG_HS_ULPI_STP | ADC123_IN10 - {&GPIOC, NULL, 0, 11, &ADC1}, // D33/PC1 | 16 | ETH_MDC | ADC123_IN11 - {&GPIOC, NULL, 0, 12, &ADC1}, // D34/PC2 | 17 | SPI2_MISO | OTG_HS_ULPI_DIR | ETH_MII_TXD2 | I2S2ext_SD | ADC123_IN12 - {&GPIOC, NULL, 0, 13, &ADC1}, // D35/PC3 | 18 | SPI2_MOSI | I2S2_SD | OTG_HS_ULPI_NXT | ETH_MII_TX_CLK | ADC123_IN13 - {&GPIOC, NULL, 0, 14, &ADC1}, // D36/PC4 | 33 | ETH_RMII_RX_D0 | ETH_MII_RX_D0 | ADC12_IN14 - {&GPIOC, NULL, 0, 15, &ADC1}, // D37/PC5 | 34 | ETH_RMII_RX_D1 | ETH_MII_RX_D1 | ADC12_IN15 - {&GPIOC, &timer8, 1, ADCx, NULL}, // D38/PC6 | 63 | I2S2_MCK | TIM8_CH1/SDIO_D6 | USART6_TX | DCMI_D0/TIM3_CH1 - {&GPIOC, &timer8, 2, ADCx, NULL}, // D39/PC7 | 64 | I2S3_MCK | TIM8_CH2/SDIO_D7 | USART6_RX | DCMI_D1/TIM3_CH2 - {&GPIOC, &timer8, 3, ADCx, NULL}, // D40/PC8 | 65 | TIM8_CH3 | SDIO_D0 | TIM3_CH3 | USART6_CK | DCMI_D2 - {&GPIOC, &timer8, 4, ADCx, NULL}, // D41/PC9 | 66 | I2S_CKIN | MCO2 | TIM8_CH4 | SDIO_D1 | I2C3_SDA | DCMI_D3 | TIM3_CH4 - {&GPIOC, NULL, 0, ADCx, NULL}, // D42/PC10 | 78 | SPI3_SCK | I2S3_CK | UART4_TX | SDIO_D2 | DCMI_D8 | USART3_TX - {&GPIOC, NULL, 0, ADCx, NULL}, // D43/PC11 | 79 | UART4_RX | SPI3_MISO | SDIO_D3 | DCMI_D4 | USART3_RX | I2S3ext_SD - {&GPIOC, NULL, 0, ADCx, NULL}, // D44/PC12 | 80 | UART5_TX | SDIO_CK | DCMI_D9 | SPI3_MOSI | I2S3_SD | USART3_CK - {&GPIOC, NULL, 0, ADCx, NULL}, // D45/PC13 | 7 | RTC_OUT, RTC_TAMP1, RTC_TS - {&GPIOC, NULL, 0, ADCx, NULL}, // D46/PC14 | 8 | OSC32_IN - {&GPIOC, NULL, 0, ADCx, NULL}, // D47/PC15 | 9 | OSC32_OUT - - {&GPIOD, NULL, 0, ADCx, NULL}, // D48/PD0 | 81 | FSMC_D2 | CAN1_RX - {&GPIOD, NULL, 0, ADCx, NULL}, // D49/PD1 | 82 | FSMC_D3 | CAN1_TX - {&GPIOD, NULL, 0, ADCx, NULL}, // D50/PD2 | 83 | TIM3_ETR | UART5_RX | SDIO_CMD | DCMI_D11 - {&GPIOD, NULL, 0, ADCx, NULL}, // D51/PD3 | 84 | FSMC_CLK | USART2_CTS - {&GPIOD, NULL, 0, ADCx, NULL}, // D52/PD4 | 85 | FSMC_NOE | USART2_RTS - {&GPIOD, NULL, 0, ADCx, NULL}, // D53/PD5 | 86 | FSMC_NWE | USART2_TX - {&GPIOD, NULL, 0, ADCx, NULL}, // D54/PD6 | 87 | FSMC_NWAIT | USART2_RX - {&GPIOD, NULL, 0, ADCx, NULL}, // D55/PD7 | 88 | USART2_CK | FSMC_NE1 | FSMC_NCE2 - {&GPIOD, NULL, 0, ADCx, NULL}, // D56/PD8 | 55 | FSMC_D13 | USART3_TX - {&GPIOD, NULL, 0, ADCx, NULL}, // D57/PD9 | 56 | FSMC_D14 | USART3_RX - {&GPIOD, NULL, 0, ADCx, NULL}, // D58/PD10 | 57 | FSMC_D15 | USART3_CK - {&GPIOD, NULL, 0, ADCx, NULL}, // D59/PD11 | 58 | FSMC_CLE | FSMC_A16 | USART3_CTS - {&GPIOD, &timer4, 1, ADCx, NULL}, // D60/PD12 | 59 | FSMC_ALE | FSMC_A17 | TIM4_CH1 | USART3_RTS // remap in - {&GPIOD, &timer4, 2, ADCx, NULL}, // D61/PD13 | 60 | FSMC_A18 | TIM4_CH2 // remap in - {&GPIOD, &timer4, 3, ADCx, NULL}, // D62/PD14 | 61 | FSMC_D0 | TIM4_CH3 // remap in - {&GPIOD, &timer4, 4, ADCx, NULL}, // D63/PD15 | 62 | FSMC_D1 | TIM4_CH4 // remap in - - {&GPIOE, NULL, 0, ADCx, NULL}, // D64/PE0 | 97 | TIM4_ETR | FSMC_NBL0 | DCMI_D2 - {&GPIOE, NULL, 0, ADCx, NULL}, // D65/PE1 | 98 | FSMC_NBL1 | DCMI_D3 - {&GPIOE, NULL, 0, ADCx, NULL}, // D66/PE2 | 1 | TRACECLK | FSMC_A23 | ETH_MII_TXD3 - {&GPIOE, NULL, 0, ADCx, NULL}, // D67/PE3 | 2 | TRACED0 | FSMC_A19 - {&GPIOE, NULL, 0, ADCx, NULL}, // D68/PE4 | 3 | TRACED1 | FSMC_A20 | DCMI_D4 - {&GPIOE, NULL, 0, ADCx, NULL}, // D69/PE5 | 4 | TRACED2 | FSMC_A21 | TIM9_CH1 / DCMI_D6 - {&GPIOE, NULL, 0, ADCx, NULL}, // D70/PE6 | 5 | TRACED3 | FSMC_A22 | TIM9_CH2 / DCMI_D7 - {&GPIOE, NULL, 0, ADCx, NULL}, // D71/PE7 | 38 | FSMC_D4 | TIM1_ETR - {&GPIOE, NULL, 0, ADCx, NULL}, // D72/PE8 | 39 | FSMC_D5 | TIM1_CH1N - {&GPIOE, &timer1, 1, ADCx, NULL}, // D73/PE9 | 40 | FSMC_D6 | TIM1_CH1 // remap in - {&GPIOE, NULL, 0, ADCx, NULL}, // D74/PE10 | 41 | FSMC_D7 | TIM1_CH2N - {&GPIOE, &timer1, 2, ADCx, NULL}, // D75/PE11 | 42 | FSMC_D8 | TIM1_CH2 // remap in - {&GPIOE, NULL, 0, ADCx, NULL}, // D76/PE12 | 43 | FSMC_D9 | TIM1_CH3N - {&GPIOE, &timer1, 3, ADCx, NULL}, // D77/PE13 | 44 | FSMC_D10 | TIM1_CH3 // remap in - {&GPIOE, &timer1, 4, ADCx, NULL}, // D78/PE14 | 45 | FSMC_D11 | TIM1_CH4 // remap in - {&GPIOE, NULL, 0, ADCx, NULL}, // D79/PE15 | 46 | FSMC_D12 | TIM1_BKIN -#if 0 - {GPIOF, 0, NULL, 0, NULL, ADCx}, // D80/PF0 - {GPIOF, 1, NULL, 0, NULL, ADCx}, // D81/PF1 - {GPIOF, 2, NULL, 0, NULL, ADCx}, // D82/PF2 - {GPIOF, 3, NULL, 0, NULL, ADCx}, // D83/PF3 - {GPIOF, 4, NULL, 0, NULL, ADCx}, // D84/PF4 - {GPIOF, 5, NULL, 0, NULL, ADCx}, // D85/PF5 - {GPIOF, 6, NULL, 0, NULL, ADCx}, // D86/PF6 - {GPIOF, 7, NULL, 0, NULL, ADCx}, // D87/PF7 - {GPIOF, 8, NULL, 0, NULL, ADCx}, // D88/PF8 - {GPIOF, 9, NULL, 0, NULL, ADCx}, // D89/PF9 - {GPIOF, 10, NULL, 0, NULL, ADCx}, // D90/PF10 - {GPIOF, 11, NULL, 0, NULL, ADCx}, // D91/PF11 - {GPIOF, 12, NULL, 0, NULL, ADCx}, // D92/PF12 - {GPIOF, 13, NULL, 0, NULL, ADCx}, // D93/PF13 - {GPIOF, 14, NULL, 0, NULL, ADCx}, // D94/PF14 - {GPIOF, 15, NULL, 0, NULL, ADCx}, // D95/PF15 - - {GPIOG, 0, NULL, 0, NULL, ADCx}, // D96/PG0 - {GPIOG, 1, NULL, 0, NULL, ADCx}, // D97/PG1 - {GPIOG, 2, NULL, 0, NULL, ADCx}, // D98/PG2 - {GPIOG, 3, NULL, 0, NULL, ADCx}, // D99/PG3 - {GPIOG, 4, NULL, 0, NULL, ADCx}, // D100/PG4 - {GPIOG, 5, NULL, 0, NULL, ADCx}, // D101/PG5 - {GPIOG, 6, NULL, 0, NULL, ADCx}, // D102/PG6 - {GPIOG, 7, NULL, 0, NULL, ADCx}, // D103/PG7 - {GPIOG, 8, NULL, 0, NULL, ADCx}, // D104/PG8 - {GPIOG, 9, NULL, 0, NULL, ADCx}, // D105/PG9 - {GPIOG, 10, NULL, 0, NULL, ADCx}, // D106/PG10 - {GPIOG, 11, NULL, 0, NULL, ADCx}, // D107/PG11 - {GPIOG, 12, NULL, 0, NULL, ADCx}, // D108/PG12 - {GPIOG, 13, NULL, 0, NULL, ADCx}, // D109/PG13 - {GPIOG, 14, NULL, 0, NULL, ADCx}, // D110/PG14 - {GPIOG, 15, NULL, 0, NULL, ADCx} // D111/PG15 -#endif -}; -/* to be defined -extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { - 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 -}; -*/ -const uint8 boardADCPins[BOARD_NR_ADC_PINS] = { - PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PB0, PB1, PC0, PC1, PC2, PC3, PC4, PC5 -}; - -const uint8 boardUsedPins[BOARD_NR_USED_PINS] = { - BOARD_LED_PIN, BOARD_LED2_PIN, BOARD_BUTTON1_PIN, BOARD_BUTTON2_PIN, BOARD_BUTTON2_PIN, - BOARD_JTMS_SWDIO_PIN, BOARD_JTCK_SWCLK_PIN, - FLASH_CS_PIN, FLASH_CLK_PIN, FLASH_DO_PIN, FLASH_DI_PIN, - NRF24_CE_PIN, NRF24_CS_PIN, NRF24_IRQ_PIN, - BOARD_SDIO_D0, BOARD_SDIO_D1, BOARD_SDIO_D2, BOARD_SDIO_D3, BOARD_SDIO_CLK, BOARD_SDIO_CMD, - USB_DM_PIN, USB_DP_PIN -}; - -#ifdef __cplusplus -} -#endif - - -#endif // BOARD_generic_f407v diff --git a/STM32F4/variants/generic_f407v/stm32_isrs.S b/STM32F4/variants/generic_f407v/stm32_isrs.S deleted file mode 100644 index 34e515c08..000000000 --- a/STM32F4/variants/generic_f407v/stm32_isrs.S +++ /dev/null @@ -1,323 +0,0 @@ -/* STM32 ISR weak declarations */ - - .thumb - -/* Default handler for all non-overridden interrupts and exceptions */ - .globl __default_handler - .type __default_handler, %function - -__default_handler: - b . - - .weak __exc_nmi - .globl __exc_nmi - .set __exc_nmi, __default_handler - .weak __exc_hardfault - .globl __exc_hardfault - .set __exc_hardfault, __default_handler - .weak __exc_memmanage - .globl __exc_memmanage - .set __exc_memmanage, __default_handler - .weak __exc_busfault - .globl __exc_busfault - .set __exc_busfault, __default_handler - .weak __exc_usagefault - .globl __exc_usagefault - .set __exc_usagefault, __default_handler - .weak __stm32reservedexception7 - .globl __stm32reservedexception7 - .set __stm32reservedexception7, __default_handler - .weak __stm32reservedexception8 - .globl __stm32reservedexception8 - .set __stm32reservedexception8, __default_handler - .weak __stm32reservedexception9 - .globl __stm32reservedexception9 - .set __stm32reservedexception9, __default_handler - .weak __stm32reservedexception10 - .globl __stm32reservedexception10 - .set __stm32reservedexception10, __default_handler - .weak __exc_svc - .globl __exc_svc - .set __exc_svc, __default_handler - .weak __exc_debug_monitor - .globl __exc_debug_monitor - .set __exc_debug_monitor, __default_handler - .weak __stm32reservedexception13 - .globl __stm32reservedexception13 - .set __stm32reservedexception13, __default_handler - .weak __exc_pendsv - .globl __exc_pendsv - .set __exc_pendsv, __default_handler - .weak __exc_systick - .globl __exc_systick - .set __exc_systick, __default_handler - .weak __irq_wwdg - .globl __irq_wwdg - .set __irq_wwdg, __default_handler - .weak __irq_pvd - .globl __irq_pvd - .set __irq_pvd, __default_handler - .weak __irq_tamper - .globl __irq_tamper - .set __irq_tamper, __default_handler - .weak __irq_rtc - .globl __irq_rtc - .set __irq_rtc, __default_handler - .weak __irq_flash - .globl __irq_flash - .set __irq_flash, __default_handler - .weak __irq_rcc - .globl __irq_rcc - .set __irq_rcc, __default_handler - .weak __irq_exti0 - .globl __irq_exti0 - .set __irq_exti0, __default_handler - .weak __irq_exti1 - .globl __irq_exti1 - .set __irq_exti1, __default_handler - .weak __irq_exti2 - .globl __irq_exti2 - .set __irq_exti2, __default_handler - .weak __irq_exti3 - .globl __irq_exti3 - .set __irq_exti3, __default_handler - .weak __irq_exti4 - .globl __irq_exti4 - .set __irq_exti4, __default_handler - .weak __irq_dma1_channel1 - .globl __irq_dma1_channel1 - .set __irq_dma1_channel1, __default_handler - .weak __irq_dma1_channel2 - .globl __irq_dma1_channel2 - .set __irq_dma1_channel2, __default_handler - .weak __irq_dma1_channel3 - .globl __irq_dma1_channel3 - .set __irq_dma1_channel3, __default_handler - .weak __irq_dma1_channel4 - .globl __irq_dma1_channel4 - .set __irq_dma1_channel4, __default_handler - .weak __irq_dma1_channel5 - .globl __irq_dma1_channel5 - .set __irq_dma1_channel5, __default_handler - .weak __irq_dma1_channel6 - .globl __irq_dma1_channel6 - .set __irq_dma1_channel6, __default_handler - .weak __irq_dma1_channel7 - .globl __irq_dma1_channel7 - .set __irq_dma1_channel7, __default_handler - .weak __irq_adc - .globl __irq_adc - .set __irq_adc, __default_handler - .weak __irq_usb_hp_can_tx - .globl __irq_usb_hp_can_tx - .set __irq_usb_hp_can_tx, __default_handler - .weak __irq_usb_lp_can_rx0 - .globl __irq_usb_lp_can_rx0 - .set __irq_usb_lp_can_rx0, __default_handler - .weak __irq_can_rx1 - .globl __irq_can_rx1 - .set __irq_can_rx1, __default_handler - .weak __irq_can_sce - .globl __irq_can_sce - .set __irq_can_sce, __default_handler - .weak __irq_exti9_5 - .globl __irq_exti9_5 - .set __irq_exti9_5, __default_handler - .weak __irq_tim1_brk - .globl __irq_tim1_brk - .set __irq_tim1_brk, __default_handler - .weak __irq_tim1_up - .globl __irq_tim1_up - .set __irq_tim1_up, __default_handler - .weak __irq_tim1_trg_com - .globl __irq_tim1_trg_com - .set __irq_tim1_trg_com, __default_handler - .weak __irq_tim1_cc - .globl __irq_tim1_cc - .set __irq_tim1_cc, __default_handler - .weak __irq_tim2 - .globl __irq_tim2 - .set __irq_tim2, __default_handler - .weak __irq_tim3 - .globl __irq_tim3 - .set __irq_tim3, __default_handler - .weak __irq_tim4 - .globl __irq_tim4 - .set __irq_tim4, __default_handler - .weak __irq_i2c1_ev - .globl __irq_i2c1_ev - .set __irq_i2c1_ev, __default_handler - .weak __irq_i2c1_er - .globl __irq_i2c1_er - .set __irq_i2c1_er, __default_handler - .weak __irq_i2c2_ev - .globl __irq_i2c2_ev - .set __irq_i2c2_ev, __default_handler - .weak __irq_i2c2_er - .globl __irq_i2c2_er - .set __irq_i2c2_er, __default_handler - .weak __irq_spi1 - .globl __irq_spi1 - .set __irq_spi1, __default_handler - .weak __irq_spi2 - .globl __irq_spi2 - .set __irq_spi2, __default_handler - .weak __irq_usart1 - .globl __irq_usart1 - .set __irq_usart1, __default_handler - .weak __irq_usart2 - .globl __irq_usart2 - .set __irq_usart2, __default_handler - .weak __irq_usart3 - .globl __irq_usart3 - .set __irq_usart3, __default_handler - .weak __irq_exti15_10 - .globl __irq_exti15_10 - .set __irq_exti15_10, __default_handler - .weak __irq_rtcalarm - .globl __irq_rtcalarm - .set __irq_rtcalarm, __default_handler - .weak __irq_usbwakeup - .globl __irq_usbwakeup - .set __irq_usbwakeup, __default_handler -#if defined (STM32_HIGH_DENSITY) - .weak __irq_tim8_brk - .globl __irq_tim8_brk - .set __irq_tim8_brk, __default_handler - .weak __irq_tim8_up - .globl __irq_tim8_up - .set __irq_tim8_up, __default_handler - .weak __irq_tim8_trg_com - .globl __irq_tim8_trg_com - .set __irq_tim8_trg_com, __default_handler - .weak __irq_tim8_cc - .globl __irq_tim8_cc - .set __irq_tim8_cc, __default_handler - .weak __irq_adc3 - .globl __irq_adc3 - .set __irq_adc3, __default_handler - .weak __irq_fsmc - .globl __irq_fsmc - .set __irq_fsmc, __default_handler - .weak __irq_sdio - .globl __irq_sdio - .set __irq_sdio, __default_handler - .weak __irq_tim5 - .globl __irq_tim5 - .set __irq_tim5, __default_handler - .weak __irq_spi3 - .globl __irq_spi3 - .set __irq_spi3, __default_handler - .weak __irq_uart4 - .globl __irq_uart4 - .set __irq_uart4, __default_handler - .weak __irq_uart5 - .globl __irq_uart5 - .set __irq_uart5, __default_handler - .weak __irq_tim6 - .globl __irq_tim6 - .set __irq_tim6, __default_handler - .weak __irq_tim7 - .globl __irq_tim7 - .set __irq_tim7, __default_handler - .weak __irq_dma2_channel1 - .globl __irq_dma2_channel1 - .set __irq_dma2_channel1, __default_handler - .weak __irq_dma2_channel2 - .globl __irq_dma2_channel2 - .set __irq_dma2_channel2, __default_handler - .weak __irq_dma2_channel3 - .globl __irq_dma2_channel3 - .set __irq_dma2_channel3, __default_handler - .weak __irq_dma2_channel4_5 - .globl __irq_dma2_channel4_5 - .set __irq_dma2_channel4_5, __default_handler -#endif /* STM32_HIGH_DENSITY */ - - .weak __irq_DMA2_Stream4_IRQHandler - .globl __irq_DMA2_Stream4_IRQHandler - .set __irq_DMA2_Stream4_IRQHandler, __default_handler - - .weak __irq_ETH_IRQHandler - .globl __irq_ETH_IRQHandler - .set __irq_ETH_IRQHandler, __default_handler - - .weak __irq_ETH_WKUP_IRQHandler - .globl __irq_ETH_WKUP_IRQHandler - .set __irq_ETH_WKUP_IRQHandler, __default_handler - - .weak __irq_CAN2_TX_IRQHandler - .globl __irq_CAN2_TX_IRQHandler - .set __irq_CAN2_TX_IRQHandler, __default_handler - - .weak __irq_CAN2_RX0_IRQHandler - .globl __irq_CAN2_RX0_IRQHandler - .set __irq_CAN2_RX0_IRQHandler, __default_handler - - .weak __irq_CAN2_RX1_IRQHandler - .globl __irq_CAN2_RX1_IRQHandler - .set __irq_CAN2_RX1_IRQHandler, __default_handler - - .weak __irq_CAN2_SCE_IRQHandler - .globl __irq_CAN2_SCE_IRQHandler - .set __irq_CAN2_SCE_IRQHandler, __default_handler - - .weak __irq_OTG_FS_IRQHandler - .globl __irq_OTG_FS_IRQHandler - .set __irq_OTG_FS_IRQHandler, __default_handler - - .weak __irq_DMA2_Stream5_IRQHandler - .globl __irq_DMA2_Stream5_IRQHandler - .set __irq_DMA2_Stream5_IRQHandler, __default_handler - - .weak __irq_DMA2_Stream6_IRQHandler - .globl __irq_DMA2_Stream6_IRQHandler - .set __irq_DMA2_Stream6_IRQHandler, __default_handler - - .weak __irq_DMA2_Stream7_IRQHandler - .globl __irq_DMA2_Stream7_IRQHandler - .set __irq_DMA2_Stream7_IRQHandler, __default_handler - - .weak __irq_USART6_IRQHandler - .globl __irq_USART6_IRQHandler - .set __irq_USART6_IRQHandler, __default_handler - - .weak __irq_I2C3_EV_IRQHandler - .globl __irq_I2C3_EV_IRQHandler - .set __irq_I2C3_EV_IRQHandler, __default_handler - - .weak __irq_I2C3_ER_IRQHandler - .globl __irq_I2C3_ER_IRQHandler - .set __irq_I2C3_ER_IRQHandler, __default_handler - - .weak __irq_OTG_HS_EP1_OUT_IRQHandler - .globl __irq_OTG_HS_EP1_OUT_IRQHandler - .set __irq_OTG_HS_EP1_OUT_IRQHandler, __default_handler - - .weak __irq_OTG_HS_EP1_IN_IRQHandler - .globl __irq_OTG_HS_EP1_IN_IRQHandler - .set __irq_OTG_HS_EP1_IN_IRQHandler, __default_handler - - .weak __irq_OTG_HS_WKUP_IRQHandler - .globl __irq_OTG_HS_WKUP_IRQHandler - .set __irq_OTG_HS_WKUP_IRQHandler, __default_handler - - .weak __irq_OTG_HS_IRQHandler - .globl __irq_OTG_HS_IRQHandler - .set __irq_OTG_HS_IRQHandler, __default_handler - - .weak __irq_DCMI_IRQHandler - .globl __irq_DCMI_IRQHandler - .set __irq_DCMI_IRQHandler, __default_handler - - .weak __irq_CRYP_IRQHandler - .globl __irq_CRYP_IRQHandler - .set __irq_CRYP_IRQHandler, __default_handler - - .weak __irq_HASH_RNG_IRQHandler - .globl __irq_HASH_RNG_IRQHandler - .set __irq_HASH_RNG_IRQHandler, __default_handler - - .weak __irq_FPU_IRQHandler - .globl __irq_FPU_IRQHandler - .set __irq_FPU_IRQHandler, __default_handler diff --git a/STM32F4/variants/generic_f407v/stm32_vector_table.S b/STM32F4/variants/generic_f407v/stm32_vector_table.S deleted file mode 100644 index 9f08d6669..000000000 --- a/STM32F4/variants/generic_f407v/stm32_vector_table.S +++ /dev/null @@ -1,113 +0,0 @@ -/* STM32 vector table */ - - .section ".stm32.interrupt_vector" - - .globl __stm32_vector_table - .type __stm32_vector_table, %object - -__stm32_vector_table: -/* CM3 core interrupts */ - .long __msp_init - .long __exc_reset - .long __exc_nmi - .long __exc_hardfault - .long __exc_memmanage - .long __exc_busfault - .long __exc_usagefault - .long __stm32reservedexception7 - .long __stm32reservedexception8 - .long __stm32reservedexception9 - .long __stm32reservedexception10 - .long __exc_svc - .long __exc_debug_monitor - .long __stm32reservedexception13 - .long __exc_pendsv - .long __exc_systick -/* Peripheral interrupts */ - .long __irq_wwdg - .long __irq_pvd - .long __irq_tamper - .long __irq_rtc - .long __irq_flash - .long __irq_rcc - .long __irq_exti0 - .long __irq_exti1 - .long __irq_exti2 - .long __irq_exti3 - .long __irq_exti4 - .long __irq_dma1_channel1 - .long __irq_dma1_channel2 - .long __irq_dma1_channel3 - .long __irq_dma1_channel4 - .long __irq_dma1_channel5 - .long __irq_dma1_channel6 - .long __irq_dma1_channel7 - .long __irq_adc - .long __irq_usb_hp_can_tx - .long __irq_usb_lp_can_rx0 - .long __irq_can_rx1 - .long __irq_can_sce - .long __irq_exti9_5 - .long __irq_tim1_brk - .long __irq_tim1_up - .long __irq_tim1_trg_com - .long __irq_tim1_cc - .long __irq_tim2 - .long __irq_tim3 - .long __irq_tim4 - .long __irq_i2c1_ev - .long __irq_i2c1_er - .long __irq_i2c2_ev - .long __irq_i2c2_er - .long __irq_spi1 - .long __irq_spi2 - .long __irq_usart1 - .long __irq_usart2 - .long __irq_usart3 - .long __irq_exti15_10 - .long __irq_rtcalarm - .long __irq_usbwakeup -#if defined (STM32_HIGH_DENSITY) - .long __irq_tim8_brk - .long __irq_tim8_up - .long __irq_tim8_trg_com - .long __irq_tim8_cc - .long __irq_adc3 - .long __irq_fsmc - .long __irq_sdio - .long __irq_tim5 - .long __irq_spi3 - .long __irq_uart4 - .long __irq_uart5 - .long __irq_tim6 - .long __irq_tim7 - .long __irq_dma2_channel1 - .long __irq_dma2_channel2 - .long __irq_dma2_channel3 - .long __irq_dma2_channel4_5 -#endif /* STM32_HIGH_DENSITY */ - - .long __irq_DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ - .long __irq_ETH_IRQHandler /* Ethernet */ - .long __irq_ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */ - .long __irq_CAN2_TX_IRQHandler /* CAN2 TX */ - .long __irq_CAN2_RX0_IRQHandler /* CAN2 RX0 */ - .long __irq_CAN2_RX1_IRQHandler /* CAN2 RX1 */ - .long __irq_CAN2_SCE_IRQHandler /* CAN2 SCE */ - .long __irq_OTG_FS_IRQHandler /* USB OTG FS */ - .long __irq_DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ - .long __irq_DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ - .long __irq_DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ - .long __irq_USART6_IRQHandler /* USART6 */ - .long __irq_I2C3_EV_IRQHandler /* I2C3 event */ - .long __irq_I2C3_ER_IRQHandler /* I2C3 error */ - .long __irq_OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ - .long __irq_OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ - .long __irq_OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ - .long __irq_OTG_HS_IRQHandler /* USB OTG HS */ - .long __irq_DCMI_IRQHandler /* DCMI */ - .long __irq_CRYP_IRQHandler /* CRYP crypto */ - .long __irq_HASH_RNG_IRQHandler /* Hash and Rng */ - .long __irq_FPU_IRQHandler /* FPU */ - - .size __stm32_vector_table, . - __stm32_vector_table diff --git a/STM32F4/variants/generic_f407v/variant.h b/STM32F4/variants/generic_f407v/variant.h index 95a7f3928..74719a979 100644 --- a/STM32F4/variants/generic_f407v/variant.h +++ b/STM32F4/variants/generic_f407v/variant.h @@ -1,17 +1,6 @@ #ifndef _VARIANT_ARDUINO_STM32_ #define _VARIANT_ARDUINO_STM32_ - -#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device ) -#define digitalPinToBitMask(P) ( BIT(P&0x0F) ) -#define portOutputRegister(port) ( &(port->regs->ODR) ) -#define portInputRegister(port) ( &(port->regs->IDR) ) - -#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) ) -#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) ) - -#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) ) - static const uint8_t SS = BOARD_SPI1_NSS_PIN; static const uint8_t SS1 = BOARD_SPI2_NSS_PIN; static const uint8_t MOSI = BOARD_SPI1_MOSI_PIN; diff --git a/STM32F4/variants/generic_f407v/wirish/start.S b/STM32F4/variants/generic_f407v/wirish/start.S deleted file mode 100644 index 8b181aa99..000000000 --- a/STM32F4/variants/generic_f407v/wirish/start.S +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* - * This file is a modified version of a file obtained from - * CodeSourcery Inc. (now part of Mentor Graphics Corp.), in which the - * following text appeared: - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ - - .text - .code 16 - .thumb_func - - .globl __start__ - .type __start__, %function -__start__: - .fnstart - ldr r1,=__msp_init - mov sp,r1 - ldr r1,=start_c - bx r1 - .pool - .cantunwind - .fnend diff --git a/tools/linux/hid_flash/hid-flash b/tools/linux/hid_flash/hid-flash new file mode 100755 index 000000000..e0a41c07e Binary files /dev/null and b/tools/linux/hid_flash/hid-flash differ diff --git a/tools/linux/hid_upload b/tools/linux/hid_upload new file mode 100755 index 000000000..12de4449a --- /dev/null +++ b/tools/linux/hid_upload @@ -0,0 +1,9 @@ +#!/bin/bash + +# Get the directory where the script is running. +DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) + +binfile="$1" +com_port="$2" + +"$DIR/hid_flash/hid-flash" ${binfile} ${com_port} diff --git a/tools/linux/maple_upload b/tools/linux/maple_upload index 50d2ae557..ffbcc7a82 100755 --- a/tools/linux/maple_upload +++ b/tools/linux/maple_upload @@ -5,12 +5,12 @@ if [ $# -lt 4 ]; then - echo "Usage: $0 $# " >&2 + echo "Usage: $0 $# " >&2 exit 1 fi dummy_port="$1"; altID="$2"; usbID="$3"; binfile="$4"; dummy_port_fullpath="/dev/$1" -if [ $# -eq 5 ]; then - dfuse_addr="--dfuse-address $5" +if [ $# -eq 6 ]; then + dfuse_addr="--dfuse-address $6" else dfuse_addr="" fi @@ -19,6 +19,14 @@ fi # Get the directory where the script is running. DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +#DFU_UTIL=$(dirname $0)/dfu-util/dfu-util +#DFU_UTIL=/usr/bin/dfu-util +DFU_UTIL=${DIR}/dfu-util/dfu-util +if [ ! -x "${DFU_UTIL}" ]; then + echo "$0: error: cannot find ${DFU_UTIL}" >&2 + exit 2 +fi + # ----------------- IMPORTANT ----------------- # The 2nd parameter to upload-reset is the delay after resetting before it exits # This value is in milliseonds @@ -26,18 +34,15 @@ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) # 750ms to 1500ms seems to work on my Mac -"${DIR}/upload-reset" ${dummy_port_fullpath} 750 +"${DIR}/upload-reset" ${dummy_port_fullpath} 750 || { + # ignore the error but give a useful hint + echo -e "\n*** autoreset failed; you need to use RESET button" 1>&2 +} - -#DFU_UTIL=$(dirname $0)/dfu-util/dfu-util -DFU_UTIL=/usr/bin/dfu-util -DFU_UTIL=${DIR}/dfu-util/dfu-util -if [ ! -x "${DFU_UTIL}" ]; then - echo "$0: error: cannot find ${DFU_UTIL}" >&2 - exit 2 -fi - -"${DFU_UTIL}" -d ${usbID} -a ${altID} -D ${binfile} ${dfuse_addr} -R +"${DFU_UTIL}" -d ${usbID} -a ${altID} -D ${binfile} ${dfuse_addr} -R || { + echo -e "\nUpload failed :(" 1>&2 + exit 1 +} echo -n Waiting for ${dummy_port_fullpath} serial... @@ -46,4 +51,8 @@ while [ ! -r ${dummy_port_fullpath} ] && ((COUNTER++ < 40)); do sleep 0.1 done -echo Done +if [ ! -r ${dummy_port_fullpath} ]; then + echo " TIMEOUT :(" +else + echo " DONE :)" +fi diff --git a/tools/linux/src/upload-reset/upload-reset.c b/tools/linux/src/upload-reset/upload-reset.c index 1d03bff51..bab193af0 100644 --- a/tools/linux/src/upload-reset/upload-reset.c +++ b/tools/linux/src/upload-reset/upload-reset.c @@ -11,17 +11,7 @@ * * * - * Terminal control code by Heiko Noordhof (see copyright below) - */ - - - -/* Copyright (C) 2003 Heiko Noordhof - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Terminal control code by Kir Kolyshkin */ #include @@ -32,130 +22,73 @@ #include #include #include -#include - -/* Function prototypes (belong in a seperate header file) */ -int openserial(char *devicename); -void closeserial(void); -int setDTR(unsigned short level); -int setRTS(unsigned short level); - - -/* Two globals for use by this module only */ -static int fd; -static struct termios oldterminfo; - - -void closeserial(void) -{ - tcsetattr(fd, TCSANOW, &oldterminfo); - close(fd); -} +static int fd = -1; int openserial(char *devicename) { - struct termios attr; - - if ((fd = open(devicename, O_RDWR)) == -1) return 0; /* Error */ - atexit(closeserial); - - if (tcgetattr(fd, &oldterminfo) == -1) return 0; /* Error */ - attr = oldterminfo; - attr.c_cflag |= CRTSCTS | CLOCAL; - attr.c_oflag = 0; - if (tcflush(fd, TCIOFLUSH) == -1) return 0; /* Error */ - if (tcsetattr(fd, TCSANOW, &attr) == -1) return 0; /* Error */ + if ((fd = open(devicename, O_RDWR | O_NOCTTY)) == -1) { + fprintf(stderr, "Can't open %s: %m\n\r", devicename); + return -1; + } - /* Set the lines to a known state, and */ - /* finally return non-zero is successful. */ - return setRTS(0) && setDTR(0); + return 0; // all good } -/* For the two functions below: - * level=0 to set line to LOW - * level=1 to set line to HIGH +/* flag can be TIOCM_RTS or TIOCM_DTR + * level can be 1 (set) or 0 (clear) */ - -int setRTS(unsigned short level) +int setFlag(int flag, short level) { - int status; - - if (ioctl(fd, TIOCMGET, &status) == -1) { - perror("setRTS(): TIOCMGET"); - return 0; - } - if (level) status |= TIOCM_RTS; - else status &= ~TIOCM_RTS; - if (ioctl(fd, TIOCMSET, &status) == -1) { - perror("setRTS(): TIOCMSET"); - return 0; - } - return 1; -} + int op = TIOCMBIC; + if (level) + op = TIOCMBIS; + if (ioctl(fd, op, &flag) == -1) { + perror("setFlag(): ioctl failed"); + return -1; + } -int setDTR(unsigned short level) -{ - int status; - - if (ioctl(fd, TIOCMGET, &status) == -1) { - perror("setDTR(): TIOCMGET"); - return 0; - } - if (level) status |= TIOCM_DTR; - else status &= ~TIOCM_DTR; - if (ioctl(fd, TIOCMSET, &status) == -1) { - perror("setDTR: TIOCMSET"); - return 0; - } - return 1; + return 0; // all good } -/* This portion of code was written by Roger Clark - * It was informed by various other pieces of code written by Leaflabs to reset their - * Maple and Maple mini boards +/* This portion of code was written by Roger Clark. + * It was informed by various other pieces of code written + * by Leaflabs to reset their Maple and Maple mini boards. + * For example, see https://goo.gl/qJi16x */ - -main(int argc, char *argv[]) +int main(int argc, char *argv[]) { - - if (argc<2 || argc >3) - { - printf("Usage upload-reset \n\r"); - return; + if (argc < 2 || argc > 3) { + printf("Usage: upload-reset []\n\r"); + return 1; } - if (openserial(argv[1])) - { - // Send magic sequence of DTR and RTS followed by the magic word "1EAF" - setRTS(false); - setDTR(false); - setDTR(true); - - usleep(50000L); - - setDTR(false); - setRTS(true); - setDTR(true); - - usleep(50000L); - - setDTR(false); - - usleep(50000L); + if (openserial(argv[1]) < 0) { + fprintf(stderr, "Can't open serial %s\n\r", argv[1]); + return 1; + } - write(fd,"1EAF",4); - - closeserial(); - if (argc==3) - { - usleep(atol(argv[2])*1000L); - } + // Old style magic sequence + setFlag(TIOCM_RTS, 0); + setFlag(TIOCM_DTR, 0); + setFlag(TIOCM_DTR, 1); + usleep(50000L); + setFlag(TIOCM_DTR, 0); + + // New style + setFlag(TIOCM_RTS, 1); + setFlag(TIOCM_DTR, 1); + usleep(50000L); + setFlag(TIOCM_DTR, 0); + if (write(fd, "1EAF", 4) != 4) { + perror("write()"); } - else - { - printf("Failed to open serial device.\n\r"); + + if (argc == 3) { + usleep(atol(argv[2])*1000L); } + + return 0; } diff --git a/tools/linux/stlink_upload b/tools/linux/stlink_upload index f0dd789b6..07adccfc0 100755 --- a/tools/linux/stlink_upload +++ b/tools/linux/stlink_upload @@ -1,5 +1,5 @@ #!/bin/bash -$(dirname $0)/stlink/st-flash write "$4" 0x8000000 +$(dirname $0)/stlink/st-flash write "$1" 0x8000000 exit 0 ## Remove the lines 2 and 3 (above) if you want this script to wait until the Serial device has been enumerated and loaded before the script exits diff --git a/tools/linux/upload-reset b/tools/linux/upload-reset index 26985b857..4449c3ba3 100755 Binary files a/tools/linux/upload-reset and b/tools/linux/upload-reset differ diff --git a/tools/linux64/hid-flash b/tools/linux64/hid-flash new file mode 100755 index 000000000..324cc3027 Binary files /dev/null and b/tools/linux64/hid-flash differ diff --git a/tools/linux64/install.sh b/tools/linux64/install.sh index 29ddb2f22..9d4caad23 100755 --- a/tools/linux64/install.sh +++ b/tools/linux64/install.sh @@ -17,7 +17,8 @@ if sudo [ -w /etc/udev/rules.d ]; then echo "Reloading udev rules" sudo udevadm control --reload-rules echo "Adding current user to dialout group" - sudo adduser $USER dialout + #sudo adduser $USER dialout + sudo usermod -aG dialout $USER else echo "Couldn't copy to /etc/udev/rules.d/; you probably have to run this script as root? Or your distribution of Linux doesn't include udev; try running the IDE itself as root." fi diff --git a/tools/linux64/maple_upload b/tools/linux64/maple_upload index 27e006c22..299a13480 100755 --- a/tools/linux64/maple_upload +++ b/tools/linux64/maple_upload @@ -5,12 +5,12 @@ if [ $# -lt 4 ]; then - echo "Usage: $0 $# " >&2 + echo "Usage: $0 $# " >&2 exit 1 fi dummy_port="$1"; altID="$2"; usbID="$3"; binfile="$4"; dummy_port_fullpath="/dev/$1" -if [ $# -eq 5 ]; then - dfuse_addr="--dfuse-address $5" +if [ $# -eq 6 ]; then + dfuse_addr="--dfuse-address $6" else dfuse_addr="" fi @@ -46,4 +46,4 @@ while [ ! -c ${dummy_port_fullpath} ] && ((COUNTER++ < 40)); do sleep 0.1 done -echo Done \ No newline at end of file +echo Done diff --git a/tools/linux64/stlink_upload b/tools/linux64/stlink_upload index 24e528d5b..c973ea24c 100755 --- a/tools/linux64/stlink_upload +++ b/tools/linux64/stlink_upload @@ -28,7 +28,7 @@ USBRESET=$(which usb-reset) || USBRESET="./usb-reset" LEAF_STATUS=$(leaf_status) echo "USB Status [$LEAF_STATUS]" -$(dirname $0)/stlink/st-flash write "$4" 0x8000000 +$(dirname $0)/stlink/st-flash write "$1" 0x8000000 sleep 4 # Reset the usb device to bring up the tty rather than DFU diff --git a/tools/linux64/upload-reset b/tools/linux64/upload-reset index 26985b857..f2f6c65bd 100755 Binary files a/tools/linux64/upload-reset and b/tools/linux64/upload-reset differ diff --git a/tools/macosx/hid_flash b/tools/macosx/hid_flash new file mode 100755 index 000000000..11915c014 Binary files /dev/null and b/tools/macosx/hid_flash differ diff --git a/tools/macosx/stlink_upload b/tools/macosx/stlink_upload index 7c107c79f..486bb3927 100755 --- a/tools/macosx/stlink_upload +++ b/tools/macosx/stlink_upload @@ -1,2 +1,2 @@ #!/bin/bash -$(dirname $0)/stlink/st-flash write "$4" 0x8000000 +$(dirname $0)/stlink/st-flash write "$1" 0x8000000 diff --git a/tools/win/hid-flash.exe b/tools/win/hid-flash.exe new file mode 100644 index 000000000..c6a18eb3d Binary files /dev/null and b/tools/win/hid-flash.exe differ diff --git a/tools/win/maple_upload.bat b/tools/win/maple_upload.bat index 7d59bf53b..3b76154d3 100644 --- a/tools/win/maple_upload.bat +++ b/tools/win/maple_upload.bat @@ -5,7 +5,8 @@ set driverLetter=%~dp0 set driverLetter=%driverLetter:~0,2% %driverLetter% cd %~dp0 -java -jar maple_loader.jar %1 %2 %3 %4 %5 %6 %7 %8 %9 +set PATH=%5\java\bin;%PATH% +java -jar maple_loader.jar %1 %2 %3 %4 for /l %%x in (1, 1, 40) do ( ping -w 50 -n 1 192.0.2.1 > nul diff --git a/tools/win/stlink/Docs/ST-LINK Utility UM.pdf b/tools/win/stlink/Docs/ST-LINK Utility UM.pdf new file mode 100644 index 000000000..55b7fcba3 Binary files /dev/null and b/tools/win/stlink/Docs/ST-LINK Utility UM.pdf differ diff --git a/tools/win/stlink/Docs/STLINK Utility.pdf b/tools/win/stlink/Docs/STLINK Utility.pdf deleted file mode 100644 index c9cf4c3d9..000000000 Binary files a/tools/win/stlink/Docs/STLINK Utility.pdf and /dev/null differ diff --git a/tools/win/stlink/Docs/Software license agreement.pdf b/tools/win/stlink/Docs/Software license agreement.pdf new file mode 100644 index 000000000..6f26ebf69 Binary files /dev/null and b/tools/win/stlink/Docs/Software license agreement.pdf differ diff --git a/tools/win/stlink/Docs/license.txt b/tools/win/stlink/Docs/license.txt deleted file mode 100644 index e18b63ff5..000000000 --- a/tools/win/stlink/Docs/license.txt +++ /dev/null @@ -1,58 +0,0 @@ -SOFTWARE LICENSE AGREEMENT - - -By using this Licensed Software, You are agreeing to be bound by the terms and conditions of this License Agreement. Do not use the Licensed Software until You have read and agreed to the following terms and conditions. The use of the Licensed Software implies automatically the acceptance of the following terms and conditions. Please indicate your acceptance or NON-acceptance by selecting 'I ACCEPT' or 'I DO NOT ACCEPT' as indicated below in the media. - -DEFINITIONS. - -Licensed Software: means the enclosed SOFTWARE LIBRARY, EXAMPLES, PROJECT TEMPLATE and all the related documentation and design tools licensed in the form of object and/or source code as the case maybe. - -Product: means a product or a system that includes or incorporates solely and exclusively an executable version of the Licensed Software and provided further that such Licensed Software executes solely and exclusively on STM32 microcontrollers devices manufactured by or for ST. - -LICENSE. -STMicroelectronics (ST) grants You a non-exclusive, worldwide, non-transferable (whether by assignment or otherwise) non sub-licensable, revocable, royalty-free limited license of the Licensed Software to: -(i) make copies, prepare derivatives works, of the source code version of the Licensed Software for the sole and exclusive purpose of developing executable versions (in object and source code) of such Licensed Software only for use with the Product; -(ii) make copies, prepare derivatives works of the object code versions of the Licensed Software for the sole purpose of designing, developing and manufacturing the Products; -(iii) make, use, sell, offer to sell, lease, hire out, import and export or otherwise distribute Products. - - -OWNERSHIP AND COPYRIGHT. Title to the Licensed Software, related documentation and all copies thereof remain with ST and/or its licensors. You may not remove the copyrights notices from the Licensed Software and to any copies of the Licensed Software. You agree to prevent any unauthorized copying of the Licensed Software and related documentation. - - -RESTRICTIONS. Unless otherwise explicitly stated in this Agreement, You may not sell, assign, sublicense, lease, rent or otherwise distribute the Licensed Software for commercial purposes, in whole or in part. - -You acknowledge and agree that any use, adaptation translation or transcription of the Licensed Software or any portion or derivative thereof, for use with processors manufactured by or for an entity other than ST is a material breach of this Agreement and requires a separate license from ST. - -No source code and/or object code relating to and/or based upon Licensed Software is to be made available by You unless expressly permitted under the section 'License'. - -You acknowledge and agree that the protection of the source code of the Licensed Software warrants the imposition of reasonable security precautions -In the event ST demonstrates to You a reasonable belief that the source code of the Licensed Software has been used or distributed in violation of this Agreement, ST may by written notification request certification as to whether such unauthorized use or distribution has occurred. You shall cooperate and assist ST in its determination of whether there has been unauthorized use or distribution of the source code of the Licensed Software and will take appropriate steps to remedy any unauthorized use or distribution. - -NO WARRANTY. The Licensed Software is provided 'as is' and 'with all faults' without warranty of any kind expressed or implied. ST and its licensors expressly disclaim all warranties, expressed, implied or otherwise, including without limitation, warranties of merchantability, fitness for a particular purpose and non-infringement of intellectual property rights. ST does not warrant that the use in whole or in part of the Licensed Software will be interrupted or error free, will meet your requirements, or will operate with the combination of hardware and software selected by You. - -You are responsible for determining whether the Licensed Software will be suitable for your intended use or application or will achieve your intended results. - -ST has not authorized anyone to make any representation or warranty for the Licensed Software, and any technical, applications or design information or advice, quality characterization, reliability data or other services provided by ST shall not constitute any representation or warranty by ST or alter this disclaimer or warranty, and in no additional obligations or liabilities shall arise from ST�s providing such information or services. ST does not assume or authorize any other person to assume for it any other liability in connection with its Licensed Software. - -Nothing contained in this Agreement will be construed as -(i) a warranty or representation by ST to maintain production of any ST device or other hardware or software with which the Licensed Software may be used or to otherwise maintain or support the Licensed Software in any manner; and -(ii) a commitment from ST and/or its licensors to bring or prosecute actions or suits against third parties for infringement of any of the rights licensed hereby, or conferring any rights to bring or prosecute actions or suits against third parties for infringement. However, ST has the right to terminate this Agreement immediately upon receiving notice of any claim, suit or proceeding that alleges that the Licensed Software or your use or distribution of the Licensed Software infringes any third party intellectual property rights. - -All other warranties, conditions or other terms implied by law are excluded to the fullest extent permitted by law. - -LIMITATION OF LIABILITIES. In no event ST or its licensors shall be liable to You or any third party for any indirect, special, consequential, incidental, punitive damages or other damages (including but not limited to, the cost of labour, re-qualification, delay, loss of profits, loss of revenues, loss of data, costs of procurement of substitute goods or services or the like) whether based on contract, tort, or any other legal theory, relating to or in connection with the Licensed Software, the documentation or this Agreement, even if ST has been advised of the possibility of such damages. - -In no event shall ST�s liability to You or any third party under this Agreement, including any claim with respect of any third party intellectual property rights, for any cause of action exceed 100 US$. This section does not apply to the extent prohibited by law. For the purposes of this section, any liability of ST shall be treated in the aggregate. - -TERMINATION. ST may terminate this License Agreement license at any time if You are in material breach of any of its terms and conditions. Upon termination, You will immediately destroy or return all copies of the Licensed Software and documentation to ST. - - -APPLICABLE LAW AND JURISDICTION. In case of dispute and in the absence of an amicable settlement, the only competent jurisdiction shall be the Courts of Geneva, Switzerland. The applicable law shall be the law of Switzerland. - - -SEVERABILITY. If any provision of this agreement is or becomes, at any time or for any reason, unenforceable or invalid, no other provision of this agreement shall be affected thereby, and the remaining provisions of this agreement shall continue with the same force and effect as if such unenforceable or invalid provisions had not been inserted in this Agreement. - - -WAIVER. The waiver by either party of any breach of any provisions of this Agreement shall not operate or be construed as a waiver of any other or a subsequent breach of the same or a different provision. - -RELATIONSHIP OF THE PARTIES. Nothing in this Agreement shall create, or be deemed to create, a partnership or the relationship of principal and agent or employer and employee between the Parties. Neither Party has the authority or power to bind, to contract in the name of or to create a liability for the other in any way or for any purpose. diff --git a/tools/win/stlink/FlashLoader/0x410.stldr b/tools/win/stlink/FlashLoader/0x410.stldr index cf034faf9..db6e6f590 100644 Binary files a/tools/win/stlink/FlashLoader/0x410.stldr and b/tools/win/stlink/FlashLoader/0x410.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x411.stldr b/tools/win/stlink/FlashLoader/0x411.stldr index 3967e6a2f..af4671358 100644 Binary files a/tools/win/stlink/FlashLoader/0x411.stldr and b/tools/win/stlink/FlashLoader/0x411.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x412.stldr b/tools/win/stlink/FlashLoader/0x412.stldr index 83f6adbb4..58728d875 100644 Binary files a/tools/win/stlink/FlashLoader/0x412.stldr and b/tools/win/stlink/FlashLoader/0x412.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x413.stldr b/tools/win/stlink/FlashLoader/0x413.stldr index 54cd56591..997277b68 100644 Binary files a/tools/win/stlink/FlashLoader/0x413.stldr and b/tools/win/stlink/FlashLoader/0x413.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x414.stldr b/tools/win/stlink/FlashLoader/0x414.stldr index ac9e117e3..4b6729aa5 100644 Binary files a/tools/win/stlink/FlashLoader/0x414.stldr and b/tools/win/stlink/FlashLoader/0x414.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x415.stldr b/tools/win/stlink/FlashLoader/0x415.stldr index 12a05f02f..17429f030 100644 Binary files a/tools/win/stlink/FlashLoader/0x415.stldr and b/tools/win/stlink/FlashLoader/0x415.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x416.stldr b/tools/win/stlink/FlashLoader/0x416.stldr index fab670e41..c72af2650 100644 Binary files a/tools/win/stlink/FlashLoader/0x416.stldr and b/tools/win/stlink/FlashLoader/0x416.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x417.stldr b/tools/win/stlink/FlashLoader/0x417.stldr index f9fafc0fa..0ef285bb6 100644 Binary files a/tools/win/stlink/FlashLoader/0x417.stldr and b/tools/win/stlink/FlashLoader/0x417.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x418.stldr b/tools/win/stlink/FlashLoader/0x418.stldr index 94b420499..d047b48d3 100644 Binary files a/tools/win/stlink/FlashLoader/0x418.stldr and b/tools/win/stlink/FlashLoader/0x418.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x419.stldr b/tools/win/stlink/FlashLoader/0x419.stldr index 6e22d66b5..3c0be227a 100644 Binary files a/tools/win/stlink/FlashLoader/0x419.stldr and b/tools/win/stlink/FlashLoader/0x419.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x419_DB1M_On.stldr b/tools/win/stlink/FlashLoader/0x419_DB1M_On.stldr index 9d9e0c351..2c276bb5a 100644 Binary files a/tools/win/stlink/FlashLoader/0x419_DB1M_On.stldr and b/tools/win/stlink/FlashLoader/0x419_DB1M_On.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x420.stldr b/tools/win/stlink/FlashLoader/0x420.stldr index 3d361c306..27df693cc 100644 Binary files a/tools/win/stlink/FlashLoader/0x420.stldr and b/tools/win/stlink/FlashLoader/0x420.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x421.stldr b/tools/win/stlink/FlashLoader/0x421.stldr index ccdeafd80..a942da972 100644 Binary files a/tools/win/stlink/FlashLoader/0x421.stldr and b/tools/win/stlink/FlashLoader/0x421.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x422.stldr b/tools/win/stlink/FlashLoader/0x422.stldr index 49f2dbb3a..87fb729c9 100644 Binary files a/tools/win/stlink/FlashLoader/0x422.stldr and b/tools/win/stlink/FlashLoader/0x422.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x423.stldr b/tools/win/stlink/FlashLoader/0x423.stldr index ef0f67de9..f20655cdd 100644 Binary files a/tools/win/stlink/FlashLoader/0x423.stldr and b/tools/win/stlink/FlashLoader/0x423.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x425.stldr b/tools/win/stlink/FlashLoader/0x425.stldr index 7e8f10d21..937b3d8b4 100644 Binary files a/tools/win/stlink/FlashLoader/0x425.stldr and b/tools/win/stlink/FlashLoader/0x425.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x427.stldr b/tools/win/stlink/FlashLoader/0x427.stldr index ea4bbb635..3b1ddd21e 100644 Binary files a/tools/win/stlink/FlashLoader/0x427.stldr and b/tools/win/stlink/FlashLoader/0x427.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x428.stldr b/tools/win/stlink/FlashLoader/0x428.stldr index 75c46067c..003ee6177 100644 Binary files a/tools/win/stlink/FlashLoader/0x428.stldr and b/tools/win/stlink/FlashLoader/0x428.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x429.stldr b/tools/win/stlink/FlashLoader/0x429.stldr index 38b0199d1..8658549c6 100644 Binary files a/tools/win/stlink/FlashLoader/0x429.stldr and b/tools/win/stlink/FlashLoader/0x429.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x430.stldr b/tools/win/stlink/FlashLoader/0x430.stldr index 8372b59ed..7ce7a5fe9 100644 Binary files a/tools/win/stlink/FlashLoader/0x430.stldr and b/tools/win/stlink/FlashLoader/0x430.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x431.stldr b/tools/win/stlink/FlashLoader/0x431.stldr index 5a901dcda..cc0afb1b2 100644 Binary files a/tools/win/stlink/FlashLoader/0x431.stldr and b/tools/win/stlink/FlashLoader/0x431.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x432.stldr b/tools/win/stlink/FlashLoader/0x432.stldr index a3de2a6d2..8b93983e7 100644 Binary files a/tools/win/stlink/FlashLoader/0x432.stldr and b/tools/win/stlink/FlashLoader/0x432.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x433.stldr b/tools/win/stlink/FlashLoader/0x433.stldr index c88598adf..02f50d2bb 100644 Binary files a/tools/win/stlink/FlashLoader/0x433.stldr and b/tools/win/stlink/FlashLoader/0x433.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x434.stldr b/tools/win/stlink/FlashLoader/0x434.stldr index 9f956ec0e..4db0da711 100644 Binary files a/tools/win/stlink/FlashLoader/0x434.stldr and b/tools/win/stlink/FlashLoader/0x434.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x434_DB1M_On.stldr b/tools/win/stlink/FlashLoader/0x434_DB1M_On.stldr index 1cf4ac4d5..5dafc1316 100644 Binary files a/tools/win/stlink/FlashLoader/0x434_DB1M_On.stldr and b/tools/win/stlink/FlashLoader/0x434_DB1M_On.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x435.stldr b/tools/win/stlink/FlashLoader/0x435.stldr new file mode 100644 index 000000000..c865f57a8 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x435.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x436.stldr b/tools/win/stlink/FlashLoader/0x436.stldr index 27d26c82b..e9c88deaa 100644 Binary files a/tools/win/stlink/FlashLoader/0x436.stldr and b/tools/win/stlink/FlashLoader/0x436.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x437.stldr b/tools/win/stlink/FlashLoader/0x437.stldr index 3183baf5f..1892bedd1 100644 Binary files a/tools/win/stlink/FlashLoader/0x437.stldr and b/tools/win/stlink/FlashLoader/0x437.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x438.stldr b/tools/win/stlink/FlashLoader/0x438.stldr index 8dd027a08..ea7ed37ef 100644 Binary files a/tools/win/stlink/FlashLoader/0x438.stldr and b/tools/win/stlink/FlashLoader/0x438.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x439.stldr b/tools/win/stlink/FlashLoader/0x439.stldr index f64c4b1ff..61372ae5b 100644 Binary files a/tools/win/stlink/FlashLoader/0x439.stldr and b/tools/win/stlink/FlashLoader/0x439.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x440.stldr b/tools/win/stlink/FlashLoader/0x440.stldr index eb4b92ec5..b1fa618c4 100644 Binary files a/tools/win/stlink/FlashLoader/0x440.stldr and b/tools/win/stlink/FlashLoader/0x440.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x441.stldr b/tools/win/stlink/FlashLoader/0x441.stldr new file mode 100644 index 000000000..8895a1775 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x441.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x442.stldr b/tools/win/stlink/FlashLoader/0x442.stldr index 14f068ff3..8deb980d0 100644 Binary files a/tools/win/stlink/FlashLoader/0x442.stldr and b/tools/win/stlink/FlashLoader/0x442.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x444.stldr b/tools/win/stlink/FlashLoader/0x444.stldr index 9f8fcf577..276176e02 100644 Binary files a/tools/win/stlink/FlashLoader/0x444.stldr and b/tools/win/stlink/FlashLoader/0x444.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x445.stldr b/tools/win/stlink/FlashLoader/0x445.stldr index 4047c3fbe..62cfb84b2 100644 Binary files a/tools/win/stlink/FlashLoader/0x445.stldr and b/tools/win/stlink/FlashLoader/0x445.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x446.stldr b/tools/win/stlink/FlashLoader/0x446.stldr index 0e8ce6b14..72185da42 100644 Binary files a/tools/win/stlink/FlashLoader/0x446.stldr and b/tools/win/stlink/FlashLoader/0x446.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x447.stldr b/tools/win/stlink/FlashLoader/0x447.stldr index c4ce5ac21..972174e1a 100644 Binary files a/tools/win/stlink/FlashLoader/0x447.stldr and b/tools/win/stlink/FlashLoader/0x447.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x448.stldr b/tools/win/stlink/FlashLoader/0x448.stldr index 8f2a32626..15728bd42 100644 Binary files a/tools/win/stlink/FlashLoader/0x448.stldr and b/tools/win/stlink/FlashLoader/0x448.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x449.stldr b/tools/win/stlink/FlashLoader/0x449.stldr index 78efc83c4..1810dabad 100644 Binary files a/tools/win/stlink/FlashLoader/0x449.stldr and b/tools/win/stlink/FlashLoader/0x449.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x450.stldr b/tools/win/stlink/FlashLoader/0x450.stldr new file mode 100644 index 000000000..147da0ac8 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x450.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x451.stldr b/tools/win/stlink/FlashLoader/0x451.stldr new file mode 100644 index 000000000..89691f5dc Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x451.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x451_DB_On.stldr b/tools/win/stlink/FlashLoader/0x451_DB_On.stldr new file mode 100644 index 000000000..f39502236 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x451_DB_On.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x452.stldr b/tools/win/stlink/FlashLoader/0x452.stldr new file mode 100644 index 000000000..5d46da249 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x452.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x457.stldr b/tools/win/stlink/FlashLoader/0x457.stldr new file mode 100644 index 000000000..879ab385d Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x457.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x458.stldr b/tools/win/stlink/FlashLoader/0x458.stldr new file mode 100644 index 000000000..63a3fb974 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x458.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x460.stldr b/tools/win/stlink/FlashLoader/0x460.stldr new file mode 100644 index 000000000..6610e2264 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x460.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x461.stldr b/tools/win/stlink/FlashLoader/0x461.stldr new file mode 100644 index 000000000..50baccd92 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x461.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x462.stldr b/tools/win/stlink/FlashLoader/0x462.stldr new file mode 100644 index 000000000..eaf222753 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x462.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x463.stldr b/tools/win/stlink/FlashLoader/0x463.stldr new file mode 100644 index 000000000..2f57b6353 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x463.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x470.stldr b/tools/win/stlink/FlashLoader/0x470.stldr new file mode 100644 index 000000000..c909b1142 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x470.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x495.stldr b/tools/win/stlink/FlashLoader/0x495.stldr new file mode 100644 index 000000000..96f4fd0e4 Binary files /dev/null and b/tools/win/stlink/FlashLoader/0x495.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x9A8.stldr b/tools/win/stlink/FlashLoader/0x9A8.stldr index c673d821c..099d79300 100644 Binary files a/tools/win/stlink/FlashLoader/0x9A8.stldr and b/tools/win/stlink/FlashLoader/0x9A8.stldr differ diff --git a/tools/win/stlink/FlashLoader/0x9B0.stldr b/tools/win/stlink/FlashLoader/0x9B0.stldr index f917e5b55..a2ee9d850 100644 Binary files a/tools/win/stlink/FlashLoader/0x9B0.stldr and b/tools/win/stlink/FlashLoader/0x9B0.stldr differ diff --git a/tools/win/stlink/ST-LINK_CLI.exe b/tools/win/stlink/ST-LINK_CLI.exe index a9452e81a..c8b2e6eee 100644 Binary files a/tools/win/stlink/ST-LINK_CLI.exe and b/tools/win/stlink/ST-LINK_CLI.exe differ diff --git a/tools/win/stlink/ST-LINK_USB_V2_1_Driver/amd64/WdfCoInstaller01009.dll b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/amd64/WdfCoInstaller01009.dll new file mode 100644 index 000000000..1731b962d Binary files /dev/null and b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/amd64/WdfCoInstaller01009.dll differ diff --git a/tools/win/stlink/ST-LINK_USB_V2_1_Driver/amd64/winusbcoinstaller2.dll b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/amd64/winusbcoinstaller2.dll new file mode 100644 index 000000000..30e55025b Binary files /dev/null and b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/amd64/winusbcoinstaller2.dll differ diff --git a/tools/win/stlink/ST-LINK_USB_V2_Driver/dpinst_amd64.exe b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/dpinst_amd64.exe similarity index 100% rename from tools/win/stlink/ST-LINK_USB_V2_Driver/dpinst_amd64.exe rename to tools/win/stlink/ST-LINK_USB_V2_1_Driver/dpinst_amd64.exe diff --git a/tools/win/stlink/ST-LINK_USB_V2_Driver/dpinst_x86.exe b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/dpinst_x86.exe similarity index 100% rename from tools/win/stlink/ST-LINK_USB_V2_Driver/dpinst_x86.exe rename to tools/win/stlink/ST-LINK_USB_V2_1_Driver/dpinst_x86.exe diff --git a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_VCP.inf b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlink_VCP.inf similarity index 100% rename from tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_VCP.inf rename to tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlink_VCP.inf diff --git a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_dbg_winusb.inf b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlink_dbg_winusb.inf similarity index 84% rename from tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_dbg_winusb.inf rename to tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlink_dbg_winusb.inf index 18b3dfd3a..740e0c8f8 100644 --- a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_dbg_winusb.inf +++ b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlink_dbg_winusb.inf @@ -9,7 +9,7 @@ ClassGUID = {88BAE032-5A81-49f0-BC3D-A4FF138216D6} Provider = %ManufacturerName% CatalogFile.NTx86 = STLinkDbgWinUSB_x86.cat CatalogFile.NTAMD64 = STLinkDbgWinUSB_x64.cat -DriverVer=12/10/2013,1.01 +DriverVer=01/21/2013,1.01 ; ========== Manufacturer/Models sections =========== @@ -73,9 +73,6 @@ KmdfService=WINUSB, WinUsb_Install [WinUsb_Install] KmdfLibraryVersion=1.9 -[WinUsb_InstallRW] -KmdfLibraryVersion=1.9 - [USB_Install.HW] AddReg=Dev_AddReg @@ -90,20 +87,37 @@ HKR,,DeviceInterfaceGUIDs,0x10000,%STLink_GUID_RW% [USB_Install.CoInstallers] AddReg=CoInstallers_AddReg -%11%/WinUSBCoInstaller2.dll -%11%/WdfCoInstaller01009.dll +CopyFiles=CoInstallers_CopyFiles [USB_InstallRW.CoInstallers] AddReg=CoInstallers_AddReg -%11%/WinUSBCoInstaller2.dll -%11%/WdfCoInstaller01009.dll +CopyFiles=CoInstallers_CopyFiles + +[CoInstallers_CopyFiles] +WinUSBCoInstaller2.dll +WdfCoInstaller01009.dll [CoInstallers_AddReg] HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01009.dll,WdfCoInstaller","WinUSBCoInstaller2.dll" -; [DestinationDirs] +[DestinationDirs] ; If your INF needs to copy files, you must not use the DefaultDestDir directive here. ; You must explicitly reference all file-list-section names in this section. +CoInstallers_CopyFiles=11 + +; ================= Source Media Section ===================== + +[SourceDisksNames] +1 = %DISK_NAME%,,,\x86 +2 = %DISK_NAME%,,,\amd64 + +[SourceDisksFiles.x86] +WinUSBCoInstaller2.dll=1 +WdfCoInstaller01009.dll=1 + +[SourceDisksFiles.amd64] +WinUSBCoInstaller2.dll=2 +WdfCoInstaller01009.dll=2 ; =================== Strings =================== @@ -114,6 +128,7 @@ DeviceName="STMicroelectronics STLink dongle" DeviceNameRW="STMicroelectronics STLink dongle RW" WinUSB_SvcDesc="WinUSB Driver for STLink" REG_MULTI_SZ = 0x00010000 +DISK_NAME="WinUSB coinstallers sources on disk" ;------------Replace GUID below with custom GUID-------------; STLink_GUID="{DBCE1CD9-A320-4b51-A365-A0C3F3C5FB29}" diff --git a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_winusb_install.bat b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlink_winusb_install.bat similarity index 97% rename from tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_winusb_install.bat rename to tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlink_winusb_install.bat index 59a3090cc..25535d650 100644 --- a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_winusb_install.bat +++ b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlink_winusb_install.bat @@ -5,4 +5,4 @@ start "" dpinst_x86.exe goto END :X64 start "" dpinst_amd64.exe -:END +:END \ No newline at end of file diff --git a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlinkdbgwinusb_x64.cat b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlinkdbgwinusb_x64.cat similarity index 69% rename from tools/win/stlink/ST-LINK_USB_V2_Driver/stlinkdbgwinusb_x64.cat rename to tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlinkdbgwinusb_x64.cat index 2c04b7bfa..b4e906491 100644 Binary files a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlinkdbgwinusb_x64.cat and b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlinkdbgwinusb_x64.cat differ diff --git a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlinkdbgwinusb_x86.cat b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlinkdbgwinusb_x86.cat similarity index 69% rename from tools/win/stlink/ST-LINK_USB_V2_Driver/stlinkdbgwinusb_x86.cat rename to tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlinkdbgwinusb_x86.cat index 2f3e80e2e..3d7e801eb 100644 Binary files a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlinkdbgwinusb_x86.cat and b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlinkdbgwinusb_x86.cat differ diff --git a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlinkvcp_x64.cat b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlinkvcp_x64.cat similarity index 100% rename from tools/win/stlink/ST-LINK_USB_V2_Driver/stlinkvcp_x64.cat rename to tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlinkvcp_x64.cat diff --git a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlinkvcp_x86.cat b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlinkvcp_x86.cat similarity index 100% rename from tools/win/stlink/ST-LINK_USB_V2_Driver/stlinkvcp_x86.cat rename to tools/win/stlink/ST-LINK_USB_V2_1_Driver/stlinkvcp_x86.cat diff --git a/tools/win/stlink/ST-LINK_USB_V2_1_Driver/x86/WdfCoInstaller01009.dll b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/x86/WdfCoInstaller01009.dll new file mode 100644 index 000000000..30e81af62 Binary files /dev/null and b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/x86/WdfCoInstaller01009.dll differ diff --git a/tools/win/stlink/ST-LINK_USB_V2_1_Driver/x86/winusbcoinstaller2.dll b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/x86/winusbcoinstaller2.dll new file mode 100644 index 000000000..fc450d2b2 Binary files /dev/null and b/tools/win/stlink/ST-LINK_USB_V2_1_Driver/x86/winusbcoinstaller2.dll differ diff --git a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_winusb_uninstall.bat b/tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_winusb_uninstall.bat deleted file mode 100644 index 5f91323fc..000000000 --- a/tools/win/stlink/ST-LINK_USB_V2_Driver/stlink_winusb_uninstall.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo off -if "%PROCESSOR_ARCHITECTURE%"=="x86" goto X86 -dpinst_amd64.exe /u stlink_dbg_winusb.inf -dpinst_amd64.exe /u stlink_VCP.inf -goto END -:X86 -dpinst_x86.exe /u stlink_dbg_winusb.inf -dpinst_x86.exe /u stlink_VCP.inf -:END diff --git a/tools/win/stlink/STLinkUSBDriver.dll b/tools/win/stlink/STLinkUSBDriver.dll index afa63bb95..e25fc7e8b 100644 Binary files a/tools/win/stlink/STLinkUSBDriver.dll and b/tools/win/stlink/STLinkUSBDriver.dll differ diff --git a/tools/win/stlink_upload.bat b/tools/win/stlink_upload.bat index 160fcdf81..da44321f9 100644 --- a/tools/win/stlink_upload.bat +++ b/tools/win/stlink_upload.bat @@ -6,12 +6,12 @@ set driverLetter=%driverLetter:~0,2% %driverLetter% cd %~dp0 rem: the two line below are needed to fix path issues with incorrect slashes before the bin file name -set str=%4 +set str=%1 set str=%str:/=\% rem: ------------- use STLINK CLI -stlink\ST-LINK_CLI.exe -c SWD -P %str% 0x8000000 -Rst -Run +stlink\ST-LINK_CLI.exe -c SWD -P %str% 0x8000000 -Rst -Run -NoPrompt rem: Using the open source texane-stlink instead of the proprietary STM stlink exe -rem:texane-stlink\st-flash.exe write %str% 0x8000000 \ No newline at end of file +rem:texane-stlink\st-flash.exe write %str% 0x8000000