├── .gitattributes ├── .gitignore ├── Documentation ├── MPU-9250-Register-Map.pdf └── MPU9250REV1.0.pdf ├── Firmware ├── Bootloader │ ├── Makefile │ ├── README.md │ ├── SparkFun_9DoF_Razor_M0.bin │ ├── SparkFun_9DoF_Razor_M0.hex │ ├── board_definitions.h │ ├── board_definitions_arduino_mkr1000.h │ ├── board_definitions_arduino_zero.h │ ├── board_definitions_genuino_mkr1000.h │ ├── board_definitions_genuino_zero.h │ ├── board_definitions_sparkfun_9dofRazor.h │ ├── board_definitions_sparkfun_samd21dev.h │ ├── board_driver_led.c │ ├── board_driver_led.h │ ├── board_driver_serial.c │ ├── board_driver_serial.h │ ├── board_driver_usb.c │ ├── board_driver_usb.h │ ├── board_init.c │ ├── board_startup.c │ ├── bootloader_samd21x18.ld │ ├── build_all_bootloaders.sh │ ├── main.c │ ├── sam_ba_cdc.c │ ├── sam_ba_cdc.h │ ├── sam_ba_monitor.c │ ├── sam_ba_monitor.h │ ├── sam_ba_serial.c │ ├── sam_ba_serial.h │ ├── sam_ba_usb.c │ └── sam_ba_usb.h └── _9DoF_Razor_M0_Firmware │ ├── _9DoF_Razor_M0_Firmware.ino │ └── config.h ├── Hardware ├── 9dof-devboard-temp.lbr ├── sparkfun-9dof-razor-imu.brd └── sparkfun-9dof-razor-imu.sch ├── LICENSE.md ├── Libraries └── Arduino │ ├── LICENSE.md │ ├── README.md │ ├── examples │ ├── MPU9250_Basic │ │ └── MPU9250_Basic.ino │ ├── MPU9250_Basic_Interrupt │ │ └── MPU9250_Basic_Interrupt.ino │ ├── MPU9250_DMP_Gyro_Cal │ │ └── MPU9250_DMP_Gyro_Cal.ino │ ├── MPU9250_DMP_Orientation │ │ └── MPU9250_DMP_Orientation.ino │ ├── MPU9250_DMP_Pedometer │ │ └── MPU9250_DMP_Pedometer.ino │ ├── MPU9250_DMP_Quaternion │ │ └── MPU9250_DMP_Quaternion.ino │ ├── MPU9250_DMP_Tap │ │ └── MPU9250_DMP_Tap.ino │ └── MPU9250_FIFO_Basic │ │ └── MPU9250_FIFO_Basic.ino │ ├── keywords.txt │ ├── library.properties │ └── src │ ├── MPU9250_RegisterMap.h │ ├── SparkFunMPU9250-DMP.cpp │ ├── SparkFunMPU9250-DMP.h │ └── util │ ├── MPU9250_RegisterMap.h │ ├── arduino_mpu9250_clk.c │ ├── arduino_mpu9250_clk.h │ ├── arduino_mpu9250_i2c.cpp │ ├── arduino_mpu9250_i2c.h │ ├── arduino_mpu9250_log.cpp │ ├── arduino_mpu9250_log.h │ ├── dmpKey.h │ ├── dmpmap.h │ ├── inv_mpu.c │ ├── inv_mpu.h │ ├── inv_mpu_dmp_motion_driver.c │ └── inv_mpu_dmp_motion_driver.h ├── Production Files ├── 9DOF-Razor-Panel-v23.brd └── sparkfun-9dof-razor-imu-Panel-v30.brd └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## SparkFun Useful stuff 3 | ################# 4 | 5 | ## AVR Development 6 | *.eep 7 | *.elf 8 | *.lst 9 | *.lss 10 | *.sym 11 | *.d 12 | *.o 13 | *.srec 14 | *.map 15 | 16 | ## Notepad++ backup files 17 | *.bak 18 | 19 | ## BOM files 20 | *bom* 21 | 22 | ################# 23 | ## Eclipse 24 | ################# 25 | 26 | *.pydevproject 27 | .project 28 | .metadata 29 | bin/ 30 | tmp/ 31 | *.tmp 32 | *.bak 33 | *.swp 34 | *~.nib 35 | local.properties 36 | .classpath 37 | .settings/ 38 | .loadpath 39 | 40 | # External tool builders 41 | .externalToolBuilders/ 42 | 43 | # Locally stored "Eclipse launch configurations" 44 | *.launch 45 | 46 | # CDT-specific 47 | .cproject 48 | 49 | # PDT-specific 50 | .buildpath 51 | 52 | 53 | ############# 54 | ## Eagle 55 | ############# 56 | 57 | # Ignore the board and schematic backup files 58 | *.b#? 59 | *.s#? 60 | 61 | 62 | ################# 63 | ## Visual Studio 64 | ################# 65 | 66 | ## Ignore Visual Studio temporary files, build results, and 67 | ## files generated by popular Visual Studio add-ons. 68 | 69 | # User-specific files 70 | *.suo 71 | *.user 72 | *.sln.docstates 73 | 74 | # Build results 75 | [Dd]ebug/ 76 | [Rr]elease/ 77 | *_i.c 78 | *_p.c 79 | *.ilk 80 | *.meta 81 | *.obj 82 | *.pch 83 | *.pdb 84 | *.pgc 85 | *.pgd 86 | *.rsp 87 | *.sbr 88 | *.tlb 89 | *.tli 90 | *.tlh 91 | *.tmp 92 | *.vspscc 93 | .builds 94 | *.dotCover 95 | 96 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 97 | #packages/ 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opensdf 104 | *.sdf 105 | 106 | # Visual Studio profiler 107 | *.psess 108 | *.vsp 109 | 110 | # ReSharper is a .NET coding add-in 111 | _ReSharper* 112 | 113 | # Installshield output folder 114 | [Ee]xpress 115 | 116 | # DocProject is a documentation generator add-in 117 | DocProject/buildhelp/ 118 | DocProject/Help/*.HxT 119 | DocProject/Help/*.HxC 120 | DocProject/Help/*.hhc 121 | DocProject/Help/*.hhk 122 | DocProject/Help/*.hhp 123 | DocProject/Help/Html2 124 | DocProject/Help/html 125 | 126 | # Click-Once directory 127 | publish 128 | 129 | # Others 130 | [Bb]in 131 | [Oo]bj 132 | sql 133 | TestResults 134 | *.Cache 135 | ClientBin 136 | stylecop.* 137 | ~$* 138 | *.dbmdl 139 | Generated_Code #added for RIA/Silverlight projects 140 | 141 | # Backup & report files from converting an old project file to a newer 142 | # Visual Studio version. Backup files are not needed, because we have git ;-) 143 | _UpgradeReport_Files/ 144 | Backup*/ 145 | UpgradeLog*.XML 146 | 147 | 148 | ############ 149 | ## Windows 150 | ############ 151 | 152 | # Windows image file caches 153 | Thumbs.db 154 | 155 | # Folder config file 156 | Desktop.ini 157 | 158 | 159 | ############# 160 | ## Python 161 | ############# 162 | 163 | *.py[co] 164 | 165 | # Packages 166 | *.egg 167 | *.egg-info 168 | dist 169 | build 170 | eggs 171 | parts 172 | bin 173 | var 174 | sdist 175 | develop-eggs 176 | .installed.cfg 177 | 178 | # Installer logs 179 | pip-log.txt 180 | 181 | # Unit test / coverage reports 182 | .coverage 183 | .tox 184 | 185 | #Translations 186 | *.mo 187 | 188 | #Mr Developer 189 | .mr.developer.cfg 190 | 191 | # Mac crap 192 | .DS_Store 193 | -------------------------------------------------------------------------------- /Documentation/MPU-9250-Register-Map.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/9DOF_Razor_IMU/51dbea98591c547e73c2511f2339e35e4bd7ad48/Documentation/MPU-9250-Register-Map.pdf -------------------------------------------------------------------------------- /Documentation/MPU9250REV1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/9DOF_Razor_IMU/51dbea98591c547e73c2511f2339e35e4bd7ad48/Documentation/MPU9250REV1.0.pdf -------------------------------------------------------------------------------- /Firmware/Bootloader/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 2 | # Copyright (c) 2015 Arduino LLC. All right reserved. 3 | # 4 | # This library is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation; either 7 | # version 2.1 of the License, or (at your option) any later version. 8 | # 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | # See the GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | 18 | # ----------------------------------------------------------------------------- 19 | # Paths 20 | ifeq ($(OS),Windows_NT) 21 | # Are we using mingw/msys/msys2/cygwin? 22 | ifeq ($(TERM),xterm) 23 | T=$(shell cygpath -u $(LOCALAPPDATA)) 24 | MODULE_PATH?=$(T)/Arduino15/packages/arduino 25 | RM=rm 26 | SEP=/ 27 | else 28 | MODULE_PATH?=$(LOCALAPPDATA)/Arduino15/packages/arduino 29 | RM=rm 30 | SEP=\\ 31 | endif 32 | else 33 | UNAME_S := $(shell uname -s) 34 | 35 | ifeq ($(UNAME_S),Linux) 36 | MODULE_PATH?=$(HOME)/.arduino15/packages/arduino 37 | RM=rm 38 | SEP=/ 39 | endif 40 | 41 | ifeq ($(UNAME_S),Darwin) 42 | MODULE_PATH?=$(HOME)/Library/Arduino15/packages/arduino/ 43 | RM=rm 44 | SEP=/ 45 | endif 46 | endif 47 | 48 | ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- 49 | BUILD_PATH=build 50 | 51 | # ----------------------------------------------------------------------------- 52 | # Tools 53 | CC=$(ARM_GCC_PATH)gcc 54 | OBJCOPY=$(ARM_GCC_PATH)objcopy 55 | NM=$(ARM_GCC_PATH)nm 56 | SIZE=$(ARM_GCC_PATH)size 57 | 58 | # ----------------------------------------------------------------------------- 59 | # Boards definitions 60 | BOARD_ID?=sparkfun_9dof 61 | NAME?=SparkFun_9DoF_Razor_M0 62 | #SparkFun_9DoF_Razor 63 | 64 | # ----------------------------------------------------------------------------- 65 | # Compiler options 66 | CFLAGS_EXTRA=-D__SAMD21G18A__ -DBOARD_ID_$(BOARD_ID) 67 | CFLAGS=-mthumb -mcpu=cortex-m0plus -Wall -c -std=gnu99 -ffunction-sections -fdata-sections -nostdlib -nostartfiles --param max-inline-insns-single=500 68 | ifdef DEBUG 69 | CFLAGS+=-g3 -O1 -DDEBUG=1 70 | else 71 | CFLAGS+=-Os -DDEBUG=0 72 | endif 73 | 74 | ELF=$(NAME).elf 75 | BIN=$(NAME).bin 76 | HEX=$(NAME).hex 77 | 78 | INCLUDES=-I"$(MODULE_PATH)/tools/CMSIS/4.0.0-atmel/CMSIS/Include/" -I"$(MODULE_PATH)/tools/CMSIS/4.0.0-atmel/Device/ATMEL/" 79 | 80 | # ----------------------------------------------------------------------------- 81 | # Linker options 82 | LDFLAGS=-mthumb -mcpu=cortex-m0plus -Wall -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all 83 | LDFLAGS+=-Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols --specs=nano.specs --specs=nosys.specs 84 | 85 | # ----------------------------------------------------------------------------- 86 | # Source files and objects 87 | SOURCES= \ 88 | board_driver_led.c \ 89 | board_driver_serial.c \ 90 | board_driver_usb.c \ 91 | board_init.c \ 92 | board_startup.c \ 93 | main.c \ 94 | sam_ba_usb.c \ 95 | sam_ba_cdc.c \ 96 | sam_ba_monitor.c \ 97 | sam_ba_serial.c 98 | 99 | OBJECTS=$(addprefix $(BUILD_PATH)/, $(SOURCES:.c=.o)) 100 | DEPS=$(addprefix $(BUILD_PATH)/, $(SOURCES:.c=.d)) 101 | 102 | ifneq "test$(AVRSTUDIO_EXE_PATH)" "test" 103 | AS_BUILD=copy_for_atmel_studio 104 | AS_CLEAN=clean_for_atmel_studio 105 | else 106 | AS_BUILD= 107 | AS_CLEAN= 108 | endif 109 | 110 | 111 | all: print_info $(SOURCES) $(BIN) $(HEX) $(AS_BUILD) 112 | 113 | $(ELF): Makefile $(BUILD_PATH) $(OBJECTS) 114 | @echo ---------------------------------------------------------- 115 | @echo Creating ELF binary 116 | "$(CC)" -L. -L$(BUILD_PATH) $(LDFLAGS) -Os -Wl,--gc-sections -save-temps -Tbootloader_samd21x18.ld -Wl,-Map,"$(BUILD_PATH)/$(NAME).map" -o "$(BUILD_PATH)/$(ELF)" -Wl,--start-group $(OBJECTS) -lm -Wl,--end-group 117 | "$(NM)" "$(BUILD_PATH)/$(ELF)" >"$(BUILD_PATH)/$(NAME)_symbols.txt" 118 | "$(SIZE)" --format=sysv -t -x $(BUILD_PATH)/$(ELF) 119 | 120 | $(BIN): $(ELF) 121 | @echo ---------------------------------------------------------- 122 | @echo Creating flash binary 123 | "$(OBJCOPY)" -O binary $(BUILD_PATH)/$< $@ 124 | 125 | $(HEX): $(ELF) 126 | @echo ---------------------------------------------------------- 127 | @echo Creating flash binary 128 | "$(OBJCOPY)" -O ihex $(BUILD_PATH)/$< $@ 129 | 130 | $(BUILD_PATH)/%.o: %.c 131 | @echo ---------------------------------------------------------- 132 | @echo Compiling $< to $@ 133 | "$(CC)" $(CFLAGS) $(CFLAGS_EXTRA) $(INCLUDES) $< -o $@ 134 | @echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 135 | 136 | $(BUILD_PATH): 137 | @echo ---------------------------------------------------------- 138 | @echo Creating build folder 139 | -mkdir $(BUILD_PATH) 140 | 141 | print_info: 142 | @echo ---------------------------------------------------------- 143 | @echo Compiling bootloader using 144 | @echo BASE PATH = $(MODULE_PATH) 145 | @echo GCC PATH = $(ARM_GCC_PATH) 146 | # @echo OS = $(OS) 147 | # @echo SHELL = $(SHELL) 148 | # @echo TERM = $(TERM) 149 | # "$(CC)" -v 150 | # env 151 | 152 | copy_for_atmel_studio: $(BIN) $(HEX) 153 | @echo ---------------------------------------------------------- 154 | @echo Atmel Studio detected, copying ELF to project root for debug 155 | cp $(BUILD_PATH)/$(ELF) . 156 | 157 | clean_for_atmel_studio: 158 | @echo ---------------------------------------------------------- 159 | @echo Atmel Studio detected, cleaning ELF from project root 160 | -$(RM) ./$(ELF) 161 | 162 | clean: $(AS_CLEAN) 163 | @echo ---------------------------------------------------------- 164 | @echo Cleaning project 165 | -$(RM) $(BIN) 166 | -$(RM) $(HEX) 167 | -$(RM) $(BUILD_PATH)/*.* 168 | -rmdir $(BUILD_PATH) 169 | 170 | .phony: print_info $(BUILD_PATH) 171 | -------------------------------------------------------------------------------- /Firmware/Bootloader/README.md: -------------------------------------------------------------------------------- 1 | # Arduino Zero Bootloader 2 | 3 | ## 1- Prerequisites 4 | 5 | The project build is based on Makefile system. 6 | Makefile is present at project root and try to handle multi-platform cases. 7 | 8 | Multi-plaform GCC is provided by ARM here: https://launchpad.net/gcc-arm-embedded/+download 9 | 10 | Atmel Studio contains both make and ARM GCC toolchain. You don't need to install them in this specific use case. 11 | 12 | For all builds and platforms you will need to have the Arduino IDE installed and the board support 13 | package for "Arduino SAMD Boards (32-bits ARM Cortex-M0+)". You can install the latter 14 | from the former's "Boards Manager" UI. 15 | 16 | ### Windows 17 | 18 | * Native command line 19 | Make binary can be obtained here: http://gnuwin32.sourceforge.net/packages/make.htm 20 | 21 | * Cygwin/MSys/MSys2/Babun/etc... 22 | It is available natively in all distributions. 23 | 24 | * Atmel Studio 25 | An Atmel Studio **7** Makefile-based project is present at project root, just open samd21_sam_ba.atsln file in AS7. 26 | 27 | ### Linux 28 | 29 | Make is usually available by default. 30 | 31 | ### OS X 32 | 33 | Make is available through XCode package. 34 | 35 | 36 | ## 2- Selecting available SAM-BA interfaces 37 | 38 | By default both USB and UART are made available, but this parameter can be modified in sam_ba_monitor.h, line 31: 39 | 40 | Set the define SAM_BA_INTERFACE to 41 | * SAM_BA_UART_ONLY for only UART interface 42 | * SAM_BA_USBCDC_ONLY for only USB CDC interface 43 | * SAM_BA_BOTH_INTERFACES for enabling both the interfaces 44 | 45 | ## 3- Behaviour 46 | 47 | This bootloader implements the double-tap on Reset button. 48 | By quickly pressing this button two times, the board will reset and stay in bootloader, waiting for communication on either USB or USART. 49 | 50 | The USB port in use is the USB Native port, close to the Reset button. 51 | The USART in use is the one available on pins D0/D1, labelled respectively RX/TX. Communication parameters are a baudrate at 115200, 8bits of data, no parity and 1 stop bit (8N1). 52 | 53 | ## 4- Description 54 | 55 | **Pinmap** 56 | 57 | The following pins are used by the program : 58 | PA25 : input/output (USB DP) 59 | PA24 : input/output (USB DM) 60 | PA11 : input (USART RX) 61 | PA10 : output (USART TX) 62 | 63 | The application board shall avoid driving the PA25, PA24, PB23 and PB22 signals while the boot program is running (after a POR for example). 64 | 65 | **Clock system** 66 | 67 | CPU runs at 48MHz from Generic Clock Generator 0 on DFLL48M. 68 | 69 | Generic Clock Generator 1 is using external 32kHz oscillator and is the source of DFLL48M. 70 | 71 | USB and USART are using Generic Clock Generator 0 also. 72 | 73 | **Memory Mapping** 74 | 75 | Bootloader code will be located at 0x0 and executed before any applicative code. 76 | 77 | Applications compiled to be executed along with the bootloader will start at 0x2000 (see linker script bootloader_samd21x18.ld). 78 | 79 | Before jumping to the application, the bootloader changes the VTOR register to use the interrupt vectors of the application @0x2000.<- not required as application code is taking care of this. 80 | 81 | ## 5- How to build 82 | 83 | If not specified the makefile builds for **Arduino Zero**: 84 | 85 | ``` 86 | make 87 | ``` 88 | 89 | if you want to make a custom bootloader for a derivative board you must supply all the necessary information in a `board_definitions_xxx.h` file, and add the corresponding case in `board_definitions.h`. 90 | For example for the **Arduino MKR1000** we use `board_definitions_arduino_mkr1000.h` and it is build with the following command: 91 | 92 | ``` 93 | BOARD_ID=arduino_mkr1000 NAME=samd21_sam_ba_arduino_mkr1000 make clean all 94 | ``` 95 | 96 | -------------------------------------------------------------------------------- /Firmware/Bootloader/SparkFun_9DoF_Razor_M0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/9DOF_Razor_IMU/51dbea98591c547e73c2511f2339e35e4bd7ad48/Firmware/Bootloader/SparkFun_9DoF_Razor_M0.bin -------------------------------------------------------------------------------- /Firmware/Bootloader/board_definitions.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #if defined(BOARD_ID_arduino_zero) 21 | #include "board_definitions_arduino_zero.h" 22 | #elif defined(BOARD_ID_genuino_zero) 23 | #include "board_definitions_genuino_zero.h" 24 | #elif defined(BOARD_ID_arduino_mkr1000) 25 | #include "board_definitions_arduino_mkr1000.h" 26 | #elif defined(BOARD_ID_genuino_mkr1000) 27 | #include "board_definitions_genuino_mkr1000.h" 28 | #elif defined(BOARD_ID_sparkfun_9dof) 29 | #include "board_definitions_sparkfun_9dofRazor.h" 30 | #elif defined(BOARD_ID_sparkfun_samd21_dev) 31 | #include "board_definitions_sparkfun_samd21dev.h" 32 | #else 33 | #error You must define a BOARD_ID and add the corresponding definitions in board_definitions.h 34 | #endif 35 | 36 | // Common definitions 37 | // ------------------ 38 | 39 | #define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f)) 40 | 41 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_definitions_arduino_mkr1000.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _BOARD_DEFINITIONS_H_ 21 | #define _BOARD_DEFINITIONS_H_ 22 | 23 | /* 24 | * USB device definitions 25 | */ 26 | #define STRING_PRODUCT "Arduino MKR1000" 27 | #define USB_VID_HIGH 0x23 28 | #define USB_VID_LOW 0x41 29 | #define USB_PID_HIGH 0x00 30 | #define USB_PID_LOW 0x4E 31 | 32 | /* 33 | * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by 34 | * quickly tapping two times on the reset button. 35 | * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not 36 | * be touched from the loaded application. 37 | */ 38 | #define BOOT_DOUBLE_TAP_ADDRESS (0x20007FFCul) 39 | #define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS)) 40 | 41 | /* 42 | * If BOOT_LOAD_PIN is defined the bootloader is started if the selected 43 | * pin is tied LOW. 44 | */ 45 | //#define BOOT_LOAD_PIN PIN_PA21 // Pin 7 46 | //#define BOOT_LOAD_PIN PIN_PA15 // Pin 5 47 | 48 | #define BOOT_USART_MODULE SERCOM0 49 | #define BOOT_USART_BUS_CLOCK_INDEX PM_APBCMASK_SERCOM0 50 | #define BOOT_USART_PER_CLOCK_INDEX GCLK_ID_SERCOM0_CORE 51 | #define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2 52 | #define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3 53 | #define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2 54 | #define BOOT_USART_PAD1 PINMUX_UNUSED 55 | #define BOOT_USART_PAD0 PINMUX_UNUSED 56 | 57 | /* Master clock frequency */ 58 | #define CPU_FREQUENCY (48000000ul) 59 | #define VARIANT_MCK CPU_FREQUENCY 60 | 61 | /* Frequency of the board main oscillator */ 62 | #define VARIANT_MAINOSC (32768ul) 63 | 64 | /* Calibration values for DFLL48 pll */ 65 | #define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58) 66 | #define NVM_SW_CALIB_DFLL48M_FINE_VAL (64) 67 | 68 | /* 69 | * LEDs definitions 70 | */ 71 | // PA20 (digital pin 6) 72 | #define BOARD_LED_PORT (0) 73 | #define BOARD_LED_PIN (20) 74 | 75 | // No RX/TX led 76 | //#define BOARD_LEDRX_PORT 77 | //#define BOARD_LEDRX_PIN 78 | 79 | //#define BOARD_LEDTX_PORT 80 | //#define BOARD_LEDTX_PIN 81 | 82 | #endif // _BOARD_DEFINITIONS_H_ 83 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_definitions_arduino_zero.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _BOARD_DEFINITIONS_H_ 21 | #define _BOARD_DEFINITIONS_H_ 22 | 23 | /* 24 | * USB device definitions 25 | */ 26 | #define STRING_PRODUCT "Arduino Zero" 27 | #define USB_VID_HIGH 0x23 28 | #define USB_VID_LOW 0x41 29 | #define USB_PID_HIGH 0x00 30 | #define USB_PID_LOW 0x4D 31 | 32 | /* 33 | * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by 34 | * quickly tapping two times on the reset button. 35 | * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not 36 | * be touched from the loaded application. 37 | */ 38 | #define BOOT_DOUBLE_TAP_ADDRESS (0x20007FFCul) 39 | #define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS)) 40 | 41 | /* 42 | * If BOOT_LOAD_PIN is defined the bootloader is started if the selected 43 | * pin is tied LOW. 44 | */ 45 | //#define BOOT_LOAD_PIN PIN_PA21 // Pin 7 46 | //#define BOOT_LOAD_PIN PIN_PA15 // Pin 5 47 | 48 | #define BOOT_USART_MODULE SERCOM0 49 | #define BOOT_USART_BUS_CLOCK_INDEX PM_APBCMASK_SERCOM0 50 | #define BOOT_USART_PER_CLOCK_INDEX GCLK_ID_SERCOM0_CORE 51 | #define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2 52 | #define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3 53 | #define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2 54 | #define BOOT_USART_PAD1 PINMUX_UNUSED 55 | #define BOOT_USART_PAD0 PINMUX_UNUSED 56 | 57 | 58 | /* Master clock frequency */ 59 | #define CPU_FREQUENCY (48000000ul) 60 | #define VARIANT_MCK CPU_FREQUENCY 61 | 62 | /* Frequency of the board main oscillator */ 63 | #define VARIANT_MAINOSC (32768ul) 64 | 65 | /* Calibration values for DFLL48 pll */ 66 | #define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58) 67 | #define NVM_SW_CALIB_DFLL48M_FINE_VAL (64) 68 | 69 | /* 70 | * LEDs definitions 71 | */ 72 | #define BOARD_LED_PORT (0) 73 | #define BOARD_LED_PIN (17) 74 | 75 | #define BOARD_LEDRX_PORT (1) 76 | #define BOARD_LEDRX_PIN (3) 77 | 78 | #define BOARD_LEDTX_PORT (0) 79 | #define BOARD_LEDTX_PIN (27) 80 | 81 | #endif // _BOARD_DEFINITIONS_H_ 82 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_definitions_genuino_mkr1000.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _BOARD_DEFINITIONS_H_ 21 | #define _BOARD_DEFINITIONS_H_ 22 | 23 | /* 24 | * USB device definitions 25 | */ 26 | #define STRING_PRODUCT "Genuino MKR1000" 27 | #define USB_VID_HIGH 0x23 28 | #define USB_VID_LOW 0x41 29 | #define USB_PID_HIGH 0x02 30 | #define USB_PID_LOW 0x4E 31 | 32 | /* 33 | * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by 34 | * quickly tapping two times on the reset button. 35 | * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not 36 | * be touched from the loaded application. 37 | */ 38 | #define BOOT_DOUBLE_TAP_ADDRESS (0x20007FFCul) 39 | #define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS)) 40 | 41 | /* 42 | * If BOOT_LOAD_PIN is defined the bootloader is started if the selected 43 | * pin is tied LOW. 44 | */ 45 | //#define BOOT_LOAD_PIN PIN_PA21 // Pin 7 46 | //#define BOOT_LOAD_PIN PIN_PA15 // Pin 5 47 | 48 | #define BOOT_USART_MODULE SERCOM0 49 | #define BOOT_USART_BUS_CLOCK_INDEX PM_APBCMASK_SERCOM0 50 | #define BOOT_USART_PER_CLOCK_INDEX GCLK_ID_SERCOM0_CORE 51 | #define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2 52 | #define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3 53 | #define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2 54 | #define BOOT_USART_PAD1 PINMUX_UNUSED 55 | #define BOOT_USART_PAD0 PINMUX_UNUSED 56 | 57 | 58 | /* Master clock frequency */ 59 | #define CPU_FREQUENCY (48000000ul) 60 | #define VARIANT_MCK CPU_FREQUENCY 61 | 62 | /* Frequency of the board main oscillator */ 63 | #define VARIANT_MAINOSC (32768ul) 64 | 65 | /* Calibration values for DFLL48 pll */ 66 | #define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58) 67 | #define NVM_SW_CALIB_DFLL48M_FINE_VAL (64) 68 | 69 | /* 70 | * LEDs definitions 71 | */ 72 | // PA20 (digital pin 6) 73 | #define BOARD_LED_PORT (0) 74 | #define BOARD_LED_PIN (20) 75 | 76 | // No RX/TX led 77 | //#define BOARD_LEDRX_PORT 78 | //#define BOARD_LEDRX_PIN 79 | 80 | //#define BOARD_LEDTX_PORT 81 | //#define BOARD_LEDTX_PIN 82 | 83 | #endif // _BOARD_DEFINITIONS_H_ 84 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_definitions_genuino_zero.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _BOARD_DEFINITIONS_H_ 21 | #define _BOARD_DEFINITIONS_H_ 22 | 23 | /* 24 | * USB device definitions 25 | */ 26 | #define STRING_PRODUCT "Genuino Zero" 27 | #define USB_VID_HIGH 0x23 28 | #define USB_VID_LOW 0x41 29 | #define USB_PID_HIGH 0x02 30 | #define USB_PID_LOW 0x4D 31 | 32 | /* 33 | * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by 34 | * quickly tapping two times on the reset button. 35 | * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not 36 | * be touched from the loaded application. 37 | */ 38 | #define BOOT_DOUBLE_TAP_ADDRESS (0x20007FFCul) 39 | #define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS)) 40 | 41 | /* 42 | * If BOOT_LOAD_PIN is defined the bootloader is started if the selected 43 | * pin is tied LOW. 44 | */ 45 | //#define BOOT_LOAD_PIN PIN_PA21 // Pin 7 46 | //#define BOOT_LOAD_PIN PIN_PA15 // Pin 5 47 | 48 | #define BOOT_USART_MODULE SERCOM0 49 | #define BOOT_USART_BUS_CLOCK_INDEX PM_APBCMASK_SERCOM0 50 | #define BOOT_USART_PER_CLOCK_INDEX GCLK_ID_SERCOM0_CORE 51 | #define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2 52 | #define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3 53 | #define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2 54 | #define BOOT_USART_PAD1 PINMUX_UNUSED 55 | #define BOOT_USART_PAD0 PINMUX_UNUSED 56 | 57 | 58 | /* Master clock frequency */ 59 | #define CPU_FREQUENCY (48000000ul) 60 | #define VARIANT_MCK CPU_FREQUENCY 61 | 62 | /* Frequency of the board main oscillator */ 63 | #define VARIANT_MAINOSC (32768ul) 64 | 65 | /* Calibration values for DFLL48 pll */ 66 | #define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58) 67 | #define NVM_SW_CALIB_DFLL48M_FINE_VAL (64) 68 | 69 | /* 70 | * LEDs definitions 71 | */ 72 | #define BOARD_LED_PORT (0) 73 | #define BOARD_LED_PIN (17) 74 | 75 | #define BOARD_LEDRX_PORT (1) 76 | #define BOARD_LEDRX_PIN (3) 77 | 78 | #define BOARD_LEDTX_PORT (0) 79 | #define BOARD_LEDTX_PIN (27) 80 | 81 | #endif // _BOARD_DEFINITIONS_H_ 82 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_definitions_sparkfun_9dofRazor.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _BOARD_DEFINITIONS_H_ 21 | #define _BOARD_DEFINITIONS_H_ 22 | 23 | /* 24 | * USB device definitions 25 | */ 26 | #define STRING_PRODUCT "SparkFun 9DoF" 27 | #define USB_VID_HIGH 0x1B 28 | #define USB_VID_LOW 0x4F 29 | #define USB_PID_HIGH 0x9D 30 | #define USB_PID_LOW 0x0E 31 | 32 | /* 33 | * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by 34 | * quickly tapping two times on the reset button. 35 | * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not 36 | * be touched from the loaded application. 37 | */ 38 | #define BOOT_DOUBLE_TAP_ADDRESS (0x20007FFCul) 39 | #define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS)) 40 | 41 | /* 42 | * If BOOT_LOAD_PIN is defined the bootloader is started if the selected 43 | * pin is tied LOW. 44 | */ 45 | #define BOOT_LOAD_PIN PIN_PA23 // PA23 is SCL on the 9DoF Razor 46 | 47 | #define BOOT_USART_MODULE SERCOM0 48 | #define BOOT_USART_BUS_CLOCK_INDEX PM_APBCMASK_SERCOM0 49 | #define BOOT_USART_PER_CLOCK_INDEX GCLK_ID_SERCOM0_CORE 50 | #define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2 51 | #define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3 52 | #define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2 53 | #define BOOT_USART_PAD1 PINMUX_UNUSED 54 | #define BOOT_USART_PAD0 PINMUX_UNUSED 55 | 56 | /* Master clock frequency */ 57 | #define CPU_FREQUENCY (48000000ul) 58 | #define VARIANT_MCK CPU_FREQUENCY 59 | 60 | /* Frequency of the board main oscillator */ 61 | #define VARIANT_MAINOSC (32768ul) 62 | 63 | /* Calibration values for DFLL48 pll */ 64 | #define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58) 65 | #define NVM_SW_CALIB_DFLL48M_FINE_VAL (64) 66 | 67 | /* 68 | * LEDs definitions 69 | */ 70 | #define BOARD_LED_PORT (0) 71 | #define BOARD_LED_PIN (17) 72 | 73 | #define BOARD_LEDRX_PORT (1) 74 | #define BOARD_LEDRX_PIN (3) 75 | 76 | #define BOARD_LEDTX_PORT (0) 77 | #define BOARD_LEDTX_PIN (27) 78 | 79 | #endif // _BOARD_DEFINITIONS_H_ 80 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_definitions_sparkfun_samd21dev.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _BOARD_DEFINITIONS_H_ 21 | #define _BOARD_DEFINITIONS_H_ 22 | 23 | /* 24 | * USB device definitions 25 | */ 26 | #define STRING_PRODUCT "SparkFun SAMD21" 27 | #define USB_VID_HIGH 0x1B 28 | #define USB_VID_LOW 0x4F 29 | #define USB_PID_HIGH 0x8D 30 | #define USB_PID_LOW 0x21 31 | 32 | /* 33 | * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by 34 | * quickly tapping two times on the reset button. 35 | * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not 36 | * be touched from the loaded application. 37 | */ 38 | #define BOOT_DOUBLE_TAP_ADDRESS (0x20007FFCul) 39 | #define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS)) 40 | 41 | /* 42 | * If BOOT_LOAD_PIN is defined the bootloader is started if the selected 43 | * pin is tied LOW. 44 | */ 45 | //#define BOOT_LOAD_PIN PIN_PA21 // Pin 7 46 | //#define BOOT_LOAD_PIN PIN_PA15 // Pin 5 47 | 48 | #define BOOT_USART_MODULE SERCOM0 49 | #define BOOT_USART_BUS_CLOCK_INDEX PM_APBCMASK_SERCOM0 50 | #define BOOT_USART_PER_CLOCK_INDEX GCLK_ID_SERCOM0_CORE 51 | #define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2 52 | #define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3 53 | #define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2 54 | #define BOOT_USART_PAD1 PINMUX_UNUSED 55 | #define BOOT_USART_PAD0 PINMUX_UNUSED 56 | 57 | 58 | /* Master clock frequency */ 59 | #define CPU_FREQUENCY (48000000ul) 60 | #define VARIANT_MCK CPU_FREQUENCY 61 | 62 | /* Frequency of the board main oscillator */ 63 | #define VARIANT_MAINOSC (32768ul) 64 | 65 | /* Calibration values for DFLL48 pll */ 66 | #define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58) 67 | #define NVM_SW_CALIB_DFLL48M_FINE_VAL (64) 68 | 69 | /* 70 | * LEDs definitions 71 | */ 72 | #define BOARD_LED_PORT (0) 73 | #define BOARD_LED_PIN (17) 74 | 75 | #define BOARD_LEDRX_PORT (1) 76 | #define BOARD_LEDRX_PIN (3) 77 | 78 | #define BOARD_LEDTX_PORT (0) 79 | #define BOARD_LEDTX_PIN (27) 80 | 81 | #endif // _BOARD_DEFINITIONS_H_ 82 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_driver_led.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include "board_driver_led.h" 21 | 22 | volatile uint8_t ledKeepValue = 0; 23 | volatile uint8_t ledTargetValue = 20; 24 | volatile int8_t ledDirection = 1; 25 | 26 | inline void LED_pulse() 27 | { 28 | if (ledKeepValue == 0) { 29 | ledTargetValue += ledDirection; 30 | LED_toggle(); 31 | } 32 | ledKeepValue ++; 33 | 34 | if (ledTargetValue > 240 || ledTargetValue < 10) { 35 | ledDirection = -ledDirection; 36 | ledTargetValue += ledDirection; 37 | } 38 | 39 | if (ledKeepValue == ledTargetValue) { 40 | LED_toggle(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_driver_led.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _BOARD_DRIVER_LED_ 21 | #define _BOARD_DRIVER_LED_ 22 | 23 | #include 24 | #include "board_definitions.h" 25 | 26 | #if defined(BOARD_LED_PORT) 27 | inline void LED_init(void) { PORT->Group[BOARD_LED_PORT].DIRSET.reg = (1<Group[BOARD_LED_PORT].OUTSET.reg = (1<Group[BOARD_LED_PORT].OUTCLR.reg = (1<Group[BOARD_LED_PORT].OUTTGL.reg = (1<Group[BOARD_LEDRX_PORT].DIRSET.reg = (1<Group[BOARD_LEDRX_PORT].OUTCLR.reg = (1<Group[BOARD_LEDRX_PORT].OUTSET.reg = (1<Group[BOARD_LEDRX_PORT].OUTTGL.reg = (1<Group[BOARD_LEDTX_PORT].DIRSET.reg = (1<Group[BOARD_LEDTX_PORT].OUTCLR.reg = (1<Group[BOARD_LEDTX_PORT].OUTSET.reg = (1<Group[BOARD_LEDTX_PORT].OUTTGL.reg = (1<USART.SYNCBUSY.bit.ENABLE); 28 | /* Disable the SERCOM UART module */ 29 | sercom->USART.CTRLA.bit.ENABLE = 0; 30 | /* Wait for synchronization */ 31 | while(sercom->USART.SYNCBUSY.bit.SWRST); 32 | /* Perform a software reset */ 33 | sercom->USART.CTRLA.bit.SWRST = 1; 34 | /* Wait for synchronization */ 35 | while(sercom->USART.CTRLA.bit.SWRST); 36 | /* Wait for synchronization */ 37 | while(sercom->USART.SYNCBUSY.bit.SWRST || sercom->USART.SYNCBUSY.bit.ENABLE); 38 | /* Update the UART pad settings, mode and data order settings */ 39 | sercom->USART.CTRLA.reg = pad_conf | SERCOM_USART_CTRLA_MODE(1) | SERCOM_USART_CTRLA_DORD; 40 | /* Wait for synchronization */ 41 | while(sercom->USART.SYNCBUSY.bit.CTRLB); 42 | /* Enable transmit and receive and set data size to 8 bits */ 43 | sercom->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0); 44 | /* Load the baud value */ 45 | sercom->USART.BAUD.reg = baud_val; 46 | /* Wait for synchronization */ 47 | while(sercom->USART.SYNCBUSY.bit.ENABLE); 48 | /* Enable SERCOM UART */ 49 | sercom->USART.CTRLA.bit.ENABLE = 1; 50 | } 51 | 52 | void uart_disable(Sercom *sercom) 53 | { 54 | /* Wait for synchronization */ 55 | while(sercom->USART.SYNCBUSY.bit.ENABLE); 56 | /* Disable SERCOM UART */ 57 | sercom->USART.CTRLA.bit.ENABLE = 0; 58 | } 59 | 60 | void uart_write_byte(Sercom *sercom, uint8_t data) 61 | { 62 | /* Wait for Data Register Empty flag */ 63 | while(!sercom->USART.INTFLAG.bit.DRE); 64 | /* Write the data to DATA register */ 65 | sercom->USART.DATA.reg = (uint16_t)data; 66 | } 67 | 68 | uint8_t uart_read_byte(Sercom *sercom) 69 | { 70 | /* Wait for Receive Complete flag */ 71 | while(!sercom->USART.INTFLAG.bit.RXC); 72 | /* Check for errors */ 73 | if (sercom->USART.STATUS.bit.PERR || sercom->USART.STATUS.bit.FERR || sercom->USART.STATUS.bit.BUFOVF) 74 | /* Set the error flag */ 75 | uart_drv_error_flag = true; 76 | /* Return the read data */ 77 | return((uint8_t)sercom->USART.DATA.reg); 78 | } 79 | 80 | void uart_write_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length) 81 | { 82 | /* Do the following for specified length */ 83 | do { 84 | /* Wait for Data Register Empty flag */ 85 | while(!sercom->USART.INTFLAG.bit.DRE); 86 | /* Send data from the buffer */ 87 | sercom->USART.DATA.reg = (uint16_t)*ptr++; 88 | } while (length--); 89 | } 90 | 91 | void uart_read_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length) 92 | { 93 | /* Do the following for specified length */ 94 | do { 95 | /* Wait for Receive Complete flag */ 96 | while(!sercom->USART.INTFLAG.bit.RXC); 97 | /* Check for errors */ 98 | if (sercom->USART.STATUS.bit.PERR || sercom->USART.STATUS.bit.FERR || sercom->USART.STATUS.bit.BUFOVF) 99 | /* Set the error flag */ 100 | uart_drv_error_flag = true; 101 | /* Store the read data to the buffer */ 102 | *ptr++ = (uint8_t)sercom->USART.DATA.reg; 103 | } while (length--); 104 | } 105 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_driver_serial.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef UART_DRIVER_H 21 | #define UART_DRIVER_H 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #define PINMUX_UNUSED 0xFFFFFFFF 28 | #define GCLK_ID_SERCOM0_CORE 0x14 29 | 30 | /* SERCOM UART available pad settings */ 31 | enum uart_pad_settings { 32 | UART_RX_PAD0_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(1), 33 | UART_RX_PAD1_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(1), 34 | UART_RX_PAD2_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(2), 35 | UART_RX_PAD3_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(3), 36 | UART_RX_PAD1_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(1), 37 | UART_RX_PAD3_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(1), 38 | }; 39 | 40 | /** 41 | * \brief Initializes the UART 42 | * 43 | * \param Pointer to SERCOM instance 44 | * \param Baud value corresponding to the desired baudrate 45 | * \param SERCOM pad settings 46 | */ 47 | void uart_basic_init(Sercom *sercom, uint16_t baud_val, enum uart_pad_settings pad_conf); 48 | 49 | /** 50 | * \brief Disables UART interface 51 | * 52 | * \param Pointer to SERCOM instance 53 | */ 54 | void uart_disable(Sercom *sercom); 55 | 56 | /** 57 | * \brief Sends a single byte through UART interface 58 | * 59 | * \param Pointer to SERCOM instance 60 | * \param Data to send 61 | */ 62 | void uart_write_byte(Sercom *sercom, uint8_t data); 63 | 64 | /** 65 | * \brief Reads a single character from UART interface 66 | * 67 | * \param Pointer to SERCOM instance 68 | * \return Data byte read 69 | */ 70 | uint8_t uart_read_byte(Sercom *sercom); 71 | 72 | /** 73 | * \brief Sends buffer on UART interface 74 | * 75 | * \param Pointer to SERCOM instance 76 | * \param Pointer to data to send 77 | * \param Number of bytes to send 78 | */ 79 | void uart_write_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length); 80 | 81 | /** 82 | * \brief Reads data on UART interface 83 | * 84 | * \param Pointer to SERCOM instance 85 | * \param Pointer to store read data 86 | * \param Number of bytes to read 87 | */ 88 | void uart_read_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length); 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_driver_usb.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include "board_driver_usb.h" 22 | #include "sam_ba_usb.h" 23 | #include "sam_ba_cdc.h" 24 | 25 | #define NVM_USB_PAD_TRANSN_POS (45) 26 | #define NVM_USB_PAD_TRANSN_SIZE (5) 27 | #define NVM_USB_PAD_TRANSP_POS (50) 28 | #define NVM_USB_PAD_TRANSP_SIZE (5) 29 | #define NVM_USB_PAD_TRIM_POS (55) 30 | #define NVM_USB_PAD_TRIM_SIZE (3) 31 | 32 | __attribute__((__aligned__(4))) UsbDeviceDescriptor usb_endpoint_table[MAX_EP]; // Initialized to zero in USB_Init 33 | __attribute__((__aligned__(4))) uint8_t udd_ep_out_cache_buffer[2][64]; //1 for CTRL, 1 for BULK 34 | __attribute__((__aligned__(4))) uint8_t udd_ep_in_cache_buffer[2][64]; //1 for CTRL, 1 for BULK 35 | 36 | static volatile bool read_job = false; 37 | 38 | /*---------------------------------------------------------------------------- 39 | * \brief 40 | */ 41 | P_USB_CDC USB_Open(P_USB_CDC pCdc, Usb *pUsb) 42 | { 43 | pCdc->pUsb = pUsb; 44 | pCdc->currentConfiguration = 0; 45 | pCdc->currentConnection = 0; 46 | pCdc->IsConfigured = USB_IsConfigured; 47 | // pCdc->Write = USB_Write; 48 | // pCdc->Read = USB_Read; 49 | 50 | pCdc->pUsb->HOST.CTRLA.bit.ENABLE = true; 51 | 52 | return pCdc; 53 | } 54 | 55 | /*---------------------------------------------------------------------------- 56 | * \brief Initializes USB 57 | */ 58 | void USB_Init(void) 59 | { 60 | uint32_t pad_transn, pad_transp, pad_trim; 61 | 62 | /* Enable USB clock */ 63 | PM->APBBMASK.reg |= PM_APBBMASK_USB; 64 | 65 | /* Set up the USB DP/DN pins */ 66 | PORT->Group[0].PINCFG[PIN_PA24G_USB_DM].bit.PMUXEN = 1; 67 | PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24G_USB_DM & 0x01u))); 68 | PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg |= MUX_PA24G_USB_DM << (4 * (PIN_PA24G_USB_DM & 0x01u)); 69 | PORT->Group[0].PINCFG[PIN_PA25G_USB_DP].bit.PMUXEN = 1; 70 | PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25G_USB_DP & 0x01u))); 71 | PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg |= MUX_PA25G_USB_DP << (4 * (PIN_PA25G_USB_DP & 0x01u)); 72 | 73 | /* ---------------------------------------------------------------------------------------------- 74 | * Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference) 75 | */ 76 | GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( 6 ) | // Generic Clock Multiplexer 6 77 | GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source 78 | GCLK_CLKCTRL_CLKEN ; 79 | 80 | while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) 81 | { 82 | /* Wait for synchronization */ 83 | } 84 | 85 | /* Reset */ 86 | USB->DEVICE.CTRLA.bit.SWRST = 1; 87 | while (USB->DEVICE.SYNCBUSY.bit.SWRST) 88 | { 89 | /* Sync wait */ 90 | } 91 | 92 | /* Load Pad Calibration */ 93 | pad_transn =( *((uint32_t *)(NVMCTRL_OTP4) 94 | + (NVM_USB_PAD_TRANSN_POS / 32)) 95 | >> (NVM_USB_PAD_TRANSN_POS % 32)) 96 | & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1); 97 | 98 | if (pad_transn == 0x1F) 99 | { 100 | pad_transn = 5; 101 | } 102 | 103 | USB->HOST.PADCAL.bit.TRANSN = pad_transn; 104 | 105 | pad_transp =( *((uint32_t *)(NVMCTRL_OTP4) 106 | + (NVM_USB_PAD_TRANSP_POS / 32)) 107 | >> (NVM_USB_PAD_TRANSP_POS % 32)) 108 | & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1); 109 | 110 | if (pad_transp == 0x1F) 111 | { 112 | pad_transp = 29; 113 | } 114 | 115 | USB->HOST.PADCAL.bit.TRANSP = pad_transp; 116 | pad_trim =( *((uint32_t *)(NVMCTRL_OTP4) 117 | + (NVM_USB_PAD_TRIM_POS / 32)) 118 | >> (NVM_USB_PAD_TRIM_POS % 32)) 119 | & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1); 120 | 121 | if (pad_trim == 0x7) 122 | { 123 | pad_trim = 3; 124 | } 125 | 126 | USB->HOST.PADCAL.bit.TRIM = pad_trim; 127 | 128 | /* Set the configuration */ 129 | /* Set mode to Device mode */ 130 | USB->HOST.CTRLA.bit.MODE = 0; 131 | /* Enable Run in Standby */ 132 | USB->HOST.CTRLA.bit.RUNSTDBY = true; 133 | /* Set the descriptor address */ 134 | USB->HOST.DESCADD.reg = (uint32_t)(&usb_endpoint_table[0]); 135 | /* Set speed configuration to Full speed */ 136 | USB->DEVICE.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val; 137 | /* Attach to the USB host */ 138 | USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH; 139 | 140 | /* Initialize endpoint table RAM location to a known value 0 */ 141 | memset((uint8_t *)(&usb_endpoint_table[0]), 0, sizeof(usb_endpoint_table)); 142 | } 143 | 144 | uint32_t USB_Write(Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num) 145 | { 146 | uint32_t data_address; 147 | uint8_t buf_index; 148 | 149 | /* Set buffer index */ 150 | buf_index = (ep_num == 0) ? 0 : 1; 151 | 152 | /* Check for requirement for multi-packet or auto zlp */ 153 | if (length >= (1 << (usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.SIZE + 3))) 154 | { 155 | /* Update the EP data address */ 156 | data_address = (uint32_t) pData; 157 | /* Enable auto zlp */ 158 | usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = true; 159 | } 160 | else 161 | { 162 | /* Copy to local buffer */ 163 | memcpy(udd_ep_in_cache_buffer[buf_index], pData, length); 164 | /* Update the EP data address */ 165 | data_address = (uint32_t) &udd_ep_in_cache_buffer[buf_index]; 166 | } 167 | 168 | /* Set the buffer address for ep data */ 169 | usb_endpoint_table[ep_num].DeviceDescBank[1].ADDR.reg = data_address; 170 | /* Set the byte count as zero */ 171 | usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = length; 172 | /* Set the multi packet size as zero for multi-packet transfers where length > ep size */ 173 | usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; 174 | /* Clear the transfer complete flag */ 175 | //pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT1 = true; 176 | pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT |= (1<<1); 177 | /* Set the bank as ready */ 178 | pUsb->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.bit.BK1RDY = true; 179 | 180 | /* Wait for transfer to complete */ 181 | while ( (pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT & (1<<1)) == 0 ); 182 | 183 | return length; 184 | } 185 | 186 | /*---------------------------------------------------------------------------- 187 | * \brief Read available data from Endpoint OUT 188 | */ 189 | uint32_t USB_Read(Usb *pUsb, char *pData, uint32_t length) 190 | { 191 | uint32_t packetSize = 0; 192 | 193 | if (!read_job) 194 | { 195 | /* Set the buffer address for ep data */ 196 | usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[USB_EP_OUT-1]; 197 | /* Set the byte count as zero */ 198 | usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; 199 | /* Set the byte count as zero */ 200 | usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; 201 | /* Start the reception by clearing the bank 0 ready bit */ 202 | pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSCLR.bit.BK0RDY = true; 203 | /* set the user flag */ 204 | read_job = true; 205 | } 206 | 207 | /* Check for Transfer Complete 0 flag */ 208 | if ( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT & (1<<0) ) 209 | { 210 | /* Set packet size */ 211 | packetSize = SAM_BA_MIN(usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT, length); 212 | /* Copy read data to user buffer */ 213 | memcpy(pData, udd_ep_out_cache_buffer[USB_EP_OUT-1], packetSize); 214 | /* Clear the Transfer Complete 0 flag */ 215 | //pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 = true; 216 | pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT |= (1 << 0); 217 | /* Clear the user flag */ 218 | read_job = false; 219 | } 220 | 221 | return packetSize; 222 | } 223 | 224 | uint32_t USB_Read_blocking(Usb *pUsb, char *pData, uint32_t length) 225 | { 226 | if (read_job) 227 | { 228 | /* Stop the reception by setting the bank 0 ready bit */ 229 | pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSSET.bit.BK0RDY = true; 230 | /* Clear the user flag */ 231 | read_job = false; 232 | } 233 | 234 | /* Set the buffer address for ep data */ 235 | usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = ((uint32_t)pData); 236 | /* Set the byte count as zero */ 237 | usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; 238 | /* Set the multi packet size as zero for multi-packet transfers where length > ep size */ 239 | usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = length; 240 | /* Clear the bank 0 ready flag */ 241 | pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSCLR.bit.BK0RDY = true; 242 | /* Wait for transfer to complete */ 243 | while (!( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT & (1<<0) )); 244 | /* Clear Transfer complete 0 flag */ 245 | //pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 = true; 246 | pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT |= (1 << 0); 247 | 248 | return length; 249 | } 250 | 251 | /*---------------------------------------------------------------------------- 252 | * \brief Test if the device is configured and handle enumeration 253 | */ 254 | uint8_t USB_IsConfigured(P_USB_CDC pCdc) 255 | { 256 | Usb *pUsb = pCdc->pUsb; 257 | 258 | /* Check for End of Reset flag */ 259 | if (pUsb->DEVICE.INTFLAG.reg & USB_DEVICE_INTFLAG_EORST) 260 | { 261 | /* Clear the flag */ 262 | pUsb->DEVICE.INTFLAG.bit.EORST = true; 263 | /* Set Device address as 0 */ 264 | pUsb->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | 0; 265 | /* Configure endpoint 0 */ 266 | /* Configure Endpoint 0 for Control IN and Control OUT */ 267 | pUsb->DEVICE.DeviceEndpoint[0].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1); 268 | pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; 269 | pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; 270 | /* Configure control OUT Packet size to 64 bytes */ 271 | usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.SIZE = 3; 272 | /* Configure control IN Packet size to 64 bytes */ 273 | usb_endpoint_table[0].DeviceDescBank[1].PCKSIZE.bit.SIZE = 3; 274 | /* Configure the data buffer address for control OUT */ 275 | usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[0]; 276 | /* Configure the data buffer address for control IN */ 277 | usb_endpoint_table[0].DeviceDescBank[1].ADDR.reg = (uint32_t)&udd_ep_in_cache_buffer[0]; 278 | /* Set Multipacket size to 8 for control OUT and byte count to 0*/ 279 | usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8; 280 | usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; 281 | pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; 282 | 283 | // Reset current configuration value to 0 284 | pCdc->currentConfiguration = 0; 285 | } 286 | else 287 | { 288 | if (pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_RXSTP) 289 | { 290 | sam_ba_usb_CDC_Enumerate(pCdc); 291 | } 292 | } 293 | 294 | return pCdc->currentConfiguration; 295 | } 296 | 297 | /*---------------------------------------------------------------------------- 298 | * \brief Stall the control endpoint 299 | */ 300 | void USB_SendStall(Usb *pUsb, bool direction_in) 301 | { 302 | /* Check the direction */ 303 | if (direction_in) 304 | { 305 | /* Set STALL request on IN direction */ 306 | //pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; 307 | pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ = (1<<1); 308 | } 309 | else 310 | { 311 | /* Set STALL request on OUT direction */ 312 | //pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; 313 | pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ = (1<<0); 314 | } 315 | } 316 | 317 | /*---------------------------------------------------------------------------- 318 | * \brief Send zero length packet through the control endpoint 319 | */ 320 | void USB_SendZlp(Usb *pUsb) 321 | { 322 | /* Set the byte count as zero */ 323 | usb_endpoint_table[0].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = 0; 324 | /* Clear the transfer complete flag */ 325 | //pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT1 = true; 326 | pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT |= (1 << 1); 327 | /* Set the bank as ready */ 328 | pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.BK1RDY = true; 329 | /* Wait for transfer to complete */ 330 | while (!( pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT & (1<<1) )); 331 | } 332 | 333 | /*---------------------------------------------------------------------------- 334 | * \brief Set USB device address obtained from host 335 | */ 336 | void USB_SetAddress(Usb *pUsb, uint16_t wValue) 337 | { 338 | pUsb->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | wValue; 339 | } 340 | 341 | /*---------------------------------------------------------------------------- 342 | * \brief Configure USB device 343 | */ 344 | void USB_Configure(Usb *pUsb) 345 | { 346 | /* Configure BULK OUT endpoint for CDC Data interface*/ 347 | pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(3); 348 | /* Set maximum packet size as 64 bytes */ 349 | usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.SIZE = 3; 350 | pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; 351 | /* Configure the data buffer */ 352 | usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[1]; 353 | 354 | /* Configure BULK IN endpoint for CDC Data interface */ 355 | pUsb->DEVICE.DeviceEndpoint[USB_EP_IN].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(3); 356 | /* Set maximum packet size as 64 bytes */ 357 | usb_endpoint_table[USB_EP_IN].DeviceDescBank[1].PCKSIZE.bit.SIZE = 3; 358 | pUsb->DEVICE.DeviceEndpoint[USB_EP_IN].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; 359 | /* Configure the data buffer */ 360 | usb_endpoint_table[USB_EP_IN].DeviceDescBank[1].ADDR.reg = (uint32_t)&udd_ep_in_cache_buffer[1]; 361 | 362 | /* Configure INTERRUPT IN endpoint for CDC COMM interface*/ 363 | pUsb->DEVICE.DeviceEndpoint[USB_EP_COMM].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(4); 364 | /* Set maximum packet size as 64 bytes */ 365 | usb_endpoint_table[USB_EP_COMM].DeviceDescBank[1].PCKSIZE.bit.SIZE = 0; 366 | pUsb->DEVICE.DeviceEndpoint[USB_EP_COMM].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; 367 | } 368 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_driver_usb.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _BOARD_DRIVER_USB_H_ 21 | #define _BOARD_DRIVER_USB_H_ 22 | 23 | #include "sam_ba_cdc.h" 24 | 25 | extern UsbDeviceDescriptor usb_endpoint_table[MAX_EP]; 26 | extern uint8_t udd_ep_out_cache_buffer[2][64]; //1 for CTRL, 1 for BULK 27 | extern uint8_t udd_ep_in_cache_buffer[2][64]; //1 for CTRL, 1 for BULK 28 | 29 | P_USB_CDC USB_Open(P_USB_CDC pCdc, Usb *pUsb); 30 | 31 | void USB_Init(void); 32 | 33 | uint32_t USB_Write(Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num); 34 | uint32_t USB_Read(Usb *pUsb, char *pData, uint32_t length); 35 | uint32_t USB_Read_blocking(Usb *pUsb, char *pData, uint32_t length); 36 | 37 | uint8_t USB_IsConfigured(P_USB_CDC pCdc); 38 | 39 | void USB_SendStall(Usb *pUsb, bool direction_in); 40 | void USB_SendZlp(Usb *pUsb); 41 | 42 | void USB_SetAddress(Usb *pUsb, uint16_t wValue); 43 | void USB_Configure(Usb *pUsb); 44 | 45 | #endif // _BOARD_DRIVER_USB_H_ 46 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include "board_definitions.h" 22 | 23 | /** 24 | * \brief system_init() configures the needed clocks and according Flash Read Wait States. 25 | * At reset: 26 | * - OSC8M clock source is enabled with a divider by 8 (1MHz). 27 | * - Generic Clock Generator 0 (GCLKMAIN) is using OSC8M as source. 28 | * We need to: 29 | * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator), will be used as DFLL48M reference. 30 | * 2) Put XOSC32K as source of Generic Clock Generator 1 31 | * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) 32 | * 4) Enable DFLL48M clock 33 | * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. 34 | * 6) Modify PRESCaler value of OSCM to have 8MHz 35 | * 7) Put OSC8M as source for Generic Clock Generator 3 36 | */ 37 | // Constants for Clock generators 38 | #define GENERIC_CLOCK_GENERATOR_MAIN (0u) 39 | #define GENERIC_CLOCK_GENERATOR_XOSC32K (1u) 40 | #define GENERIC_CLOCK_GENERATOR_OSCULP32K (2u) /* Initialized at reset for WDT */ 41 | #define GENERIC_CLOCK_GENERATOR_OSC8M (3u) 42 | // Constants for Clock multiplexers 43 | #define GENERIC_CLOCK_MULTIPLEXER_DFLL48M (0u) 44 | 45 | void board_init(void) 46 | { 47 | /* Set 1 Flash Wait State for 48MHz, cf tables 20.9 and 35.27 in SAMD21 Datasheet */ 48 | NVMCTRL->CTRLB.bit.RWS = NVMCTRL_CTRLB_RWS_HALF_Val; 49 | 50 | /* Turn on the digital interface clock */ 51 | PM->APBAMASK.reg |= PM_APBAMASK_GCLK; 52 | 53 | /* ---------------------------------------------------------------------------------------------- 54 | * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator) 55 | */ 56 | SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP( 0x6u ) | /* cf table 15.10 of product datasheet in chapter 15.8.6 */ 57 | SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K; 58 | SYSCTRL->XOSC32K.bit.ENABLE = 1; /* separate call, as described in chapter 15.6.3 */ 59 | 60 | while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSC32KRDY) == 0 ) 61 | { 62 | /* Wait for oscillator stabilization */ 63 | } 64 | 65 | /* Software reset the module to ensure it is re-initialized correctly */ 66 | /* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete. 67 | * CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete, as described in chapter 13.8.1 68 | */ 69 | GCLK->CTRL.reg = GCLK_CTRL_SWRST; 70 | 71 | while ( (GCLK->CTRL.reg & GCLK_CTRL_SWRST) && (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) ) 72 | { 73 | /* Wait for reset to complete */ 74 | } 75 | 76 | /* ---------------------------------------------------------------------------------------------- 77 | * 2) Put XOSC32K as source of Generic Clock Generator 1 78 | */ 79 | GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ); // Generic Clock Generator 1 80 | 81 | while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) 82 | { 83 | /* Wait for synchronization */ 84 | } 85 | 86 | /* Write Generic Clock Generator 1 configuration */ 87 | GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) | // Generic Clock Generator 1 88 | GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator 89 | // GCLK_GENCTRL_OE | // Output clock to a pin for tests 90 | GCLK_GENCTRL_GENEN; 91 | 92 | while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) 93 | { 94 | /* Wait for synchronization */ 95 | } 96 | 97 | /* ---------------------------------------------------------------------------------------------- 98 | * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) 99 | */ 100 | GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GENERIC_CLOCK_MULTIPLEXER_DFLL48M ) | // Generic Clock Multiplexer 0 101 | GCLK_CLKCTRL_GEN_GCLK1 | // Generic Clock Generator 1 is source 102 | GCLK_CLKCTRL_CLKEN; 103 | 104 | while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) 105 | { 106 | /* Wait for synchronization */ 107 | } 108 | 109 | /* ---------------------------------------------------------------------------------------------- 110 | * 4) Enable DFLL48M clock 111 | */ 112 | 113 | /* DFLL Configuration in Closed Loop mode, cf product datasheet chapter 15.6.7.1 - Closed-Loop Operation */ 114 | 115 | /* Remove the OnDemand mode, Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905 */ 116 | SYSCTRL->DFLLCTRL.bit.ONDEMAND = 0; 117 | 118 | while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) 119 | { 120 | /* Wait for synchronization */ 121 | } 122 | 123 | SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 31 ) | // Coarse step is 31, half of the max value 124 | SYSCTRL_DFLLMUL_FSTEP( 511 ) | // Fine step is 511, half of the max value 125 | SYSCTRL_DFLLMUL_MUL( (VARIANT_MCK/VARIANT_MAINOSC) ); // External 32KHz is the reference 126 | 127 | while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) 128 | { 129 | /* Wait for synchronization */ 130 | } 131 | 132 | /* Write full configuration to DFLL control register */ 133 | SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */ 134 | SYSCTRL_DFLLCTRL_WAITLOCK | 135 | SYSCTRL_DFLLCTRL_QLDIS; /* Disable Quick lock */ 136 | 137 | while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) 138 | { 139 | /* Wait for synchronization */ 140 | } 141 | 142 | /* Enable the DFLL */ 143 | SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE; 144 | 145 | while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKC) == 0 || 146 | (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKF) == 0 ) 147 | { 148 | /* Wait for locks flags */ 149 | } 150 | 151 | while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) 152 | { 153 | /* Wait for synchronization */ 154 | } 155 | 156 | /* ---------------------------------------------------------------------------------------------- 157 | * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. 158 | */ 159 | GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_MAIN ); // Generic Clock Generator 0 160 | 161 | while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) 162 | { 163 | /* Wait for synchronization */ 164 | } 165 | 166 | /* Write Generic Clock Generator 0 configuration */ 167 | GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_MAIN ) | // Generic Clock Generator 0 168 | GCLK_GENCTRL_SRC_DFLL48M | // Selected source is DFLL 48MHz 169 | // GCLK_GENCTRL_OE | // Output clock to a pin for tests 170 | GCLK_GENCTRL_IDC | // Set 50/50 duty cycle 171 | GCLK_GENCTRL_GENEN; 172 | 173 | while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) 174 | { 175 | /* Wait for synchronization */ 176 | } 177 | 178 | #if 0 179 | /* ---------------------------------------------------------------------------------------------- 180 | * 6) Modify PRESCaler value of OSC8M to have 8MHz 181 | */ 182 | SYSCTRL->OSC8M.bit.PRESC = SYSCTRL_OSC8M_PRESC_1_Val; 183 | SYSCTRL->OSC8M.bit.ONDEMAND = 0; 184 | 185 | /* ---------------------------------------------------------------------------------------------- 186 | * 7) Put OSC8M as source for Generic Clock Generator 3 187 | */ 188 | GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_OSC8M ); // Generic Clock Generator 3 189 | 190 | /* Write Generic Clock Generator 3 configuration */ 191 | GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) | // Generic Clock Generator 3 192 | GCLK_GENCTRL_SRC_OSC8M | // Selected source is RC OSC 8MHz (already enabled at reset) 193 | // GCLK_GENCTRL_OE | // Output clock to a pin for tests 194 | GCLK_GENCTRL_GENEN; 195 | 196 | while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) 197 | { 198 | /* Wait for synchronization */ 199 | } 200 | #endif //0 201 | 202 | /* 203 | * Now that all system clocks are configured, we can set CPU and APBx BUS clocks. 204 | * These values are normally the ones present after Reset. 205 | */ 206 | PM->CPUSEL.reg = PM_CPUSEL_CPUDIV_DIV1; 207 | PM->APBASEL.reg = PM_APBASEL_APBADIV_DIV1_Val; 208 | PM->APBBSEL.reg = PM_APBBSEL_APBBDIV_DIV1_Val; 209 | PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1_Val; 210 | } 211 | -------------------------------------------------------------------------------- /Firmware/Bootloader/board_startup.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | 22 | struct ConstVectors 23 | { 24 | /* Stack pointer */ 25 | void* pvStack; 26 | 27 | /* Cortex-M handlers */ 28 | void* pfnReset_Handler; 29 | void* pfnNMI_Handler; 30 | void* pfnHardFault_Handler; 31 | void* pfnReservedM12; 32 | void* pfnReservedM11; 33 | void* pfnReservedM10; 34 | void* pfnReservedM9; 35 | void* pfnReservedM8; 36 | void* pfnReservedM7; 37 | void* pfnReservedM6; 38 | void* pfnSVC_Handler; 39 | void* pfnReservedM4; 40 | void* pfnReservedM3; 41 | void* pfnPendSV_Handler; 42 | void* pfnSysTick_Handler; 43 | }; 44 | 45 | /* Symbols exported from linker script */ 46 | extern uint32_t __etext ; 47 | extern uint32_t __data_start__ ; 48 | extern uint32_t __data_end__ ; 49 | extern uint32_t __bss_start__ ; 50 | extern uint32_t __bss_end__ ; 51 | extern uint32_t __StackTop; 52 | 53 | extern int main(void); 54 | extern void __libc_init_array(void); 55 | 56 | /* Exception Table */ 57 | __attribute__ ((section(".isr_vector"))) 58 | const struct ConstVectors exception_table = 59 | { 60 | /* Configure Initial Stack Pointer, using linker-generated symbols */ 61 | .pvStack = (void*) (&__StackTop), 62 | 63 | .pfnReset_Handler = (void*) Reset_Handler, 64 | .pfnNMI_Handler = (void*) NMI_Handler, 65 | .pfnHardFault_Handler = (void*) HardFault_Handler, 66 | .pfnReservedM12 = (void*) (0UL), /* Reserved */ 67 | .pfnReservedM11 = (void*) (0UL), /* Reserved */ 68 | .pfnReservedM10 = (void*) (0UL), /* Reserved */ 69 | .pfnReservedM9 = (void*) (0UL), /* Reserved */ 70 | .pfnReservedM8 = (void*) (0UL), /* Reserved */ 71 | .pfnReservedM7 = (void*) (0UL), /* Reserved */ 72 | .pfnReservedM6 = (void*) (0UL), /* Reserved */ 73 | .pfnSVC_Handler = (void*) SVC_Handler, 74 | .pfnReservedM4 = (void*) (0UL), /* Reserved */ 75 | .pfnReservedM3 = (void*) (0UL), /* Reserved */ 76 | .pfnPendSV_Handler = (void*) PendSV_Handler, 77 | .pfnSysTick_Handler = (void*) SysTick_Handler, 78 | }; 79 | 80 | /** 81 | * \brief This is the code that gets called on processor reset. 82 | * Initializes the device and call the main() routine. 83 | */ 84 | void Reset_Handler( void ) 85 | { 86 | uint32_t *pSrc, *pDest; 87 | 88 | /* Initialize the initialized data section */ 89 | pSrc = &__etext; 90 | pDest = &__data_start__; 91 | 92 | if ( (&__data_start__ != &__data_end__) && (pSrc != pDest) ) 93 | { 94 | for (; pDest < &__data_end__ ; pDest++, pSrc++ ) 95 | { 96 | *pDest = *pSrc ; 97 | } 98 | } 99 | 100 | /* Clear the zero section */ 101 | if ( &__bss_start__ != &__bss_end__ ) 102 | { 103 | for ( pDest = &__bss_start__ ; pDest < &__bss_end__ ; pDest++ ) 104 | { 105 | *pDest = 0ul ; 106 | } 107 | } 108 | 109 | // board_init(); // will be done in main() after app check 110 | 111 | /* Initialize the C library */ 112 | // __libc_init_array(); 113 | 114 | main(); 115 | 116 | while (1); 117 | } 118 | 119 | void NMI_Handler(void) 120 | { 121 | __BKPT(14); 122 | while (1); 123 | } 124 | 125 | void HardFault_Handler(void) 126 | { 127 | __BKPT(13); 128 | while (1); 129 | } 130 | 131 | void SVC_Handler(void) 132 | { 133 | __BKPT(5); 134 | while (1); 135 | } 136 | 137 | void PendSV_Handler(void) 138 | { 139 | __BKPT(2); 140 | while (1); 141 | } 142 | -------------------------------------------------------------------------------- /Firmware/Bootloader/bootloader_samd21x18.ld: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014-2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | /* Linker script to configure memory regions. 21 | * Need modifying for a specific board. 22 | * FLASH.ORIGIN: starting address of flash 23 | * FLASH.LENGTH: length of flash 24 | * RAM.ORIGIN: starting address of RAM bank 0 25 | * RAM.LENGTH: length of RAM bank 0 26 | */ 27 | MEMORY 28 | { 29 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x2000 /* First 8KB used by bootloader */ 30 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000-0x0004 /* 4 bytes used by bootloader to keep data between resets */ 31 | } 32 | 33 | /* Linker script to place sections and symbol values. Should be used together 34 | * with other linker script that defines memory regions FLASH and RAM. 35 | * It references following symbols, which must be defined in code: 36 | * Reset_Handler : Entry of reset handler 37 | * 38 | * It defines following symbols, which code can use without definition: 39 | * __exidx_start 40 | * __exidx_end 41 | * __copy_table_start__ 42 | * __copy_table_end__ 43 | * __zero_table_start__ 44 | * __zero_table_end__ 45 | * __etext 46 | * __data_start__ 47 | * __preinit_array_start 48 | * __preinit_array_end 49 | * __init_array_start 50 | * __init_array_end 51 | * __fini_array_start 52 | * __fini_array_end 53 | * __data_end__ 54 | * __bss_start__ 55 | * __bss_end__ 56 | * __end__ 57 | * end 58 | * __HeapLimit 59 | * __StackLimit 60 | * __StackTop 61 | * __stack 62 | * __sketch_vectors_ptr 63 | */ 64 | ENTRY(Reset_Handler) 65 | 66 | SECTIONS 67 | { 68 | . = ORIGIN(FLASH); 69 | 70 | .vectors : 71 | { 72 | KEEP(*(.isr_vector)) 73 | } > FLASH 74 | 75 | .text : 76 | { 77 | *(.text*) 78 | 79 | KEEP(*(.init)) 80 | KEEP(*(.fini)) 81 | 82 | /* .ctors */ 83 | *crtbegin.o(.ctors) 84 | *crtbegin?.o(.ctors) 85 | *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) 86 | *(SORT(.ctors.*)) 87 | *(.ctors) 88 | 89 | /* .dtors */ 90 | *crtbegin.o(.dtors) 91 | *crtbegin?.o(.dtors) 92 | *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) 93 | *(SORT(.dtors.*)) 94 | *(.dtors) 95 | 96 | *(.rodata*) 97 | 98 | KEEP(*(.eh_frame*)) 99 | } > FLASH 100 | 101 | .ARM.extab : 102 | { 103 | *(.ARM.extab* .gnu.linkonce.armextab.*) 104 | } > FLASH 105 | 106 | __exidx_start = .; 107 | .ARM.exidx : 108 | { 109 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 110 | } > FLASH 111 | __exidx_end = .; 112 | 113 | /* To copy multiple ROM to RAM sections, 114 | * uncomment .copy.table section and, 115 | * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ 116 | /* 117 | .copy.table : 118 | { 119 | . = ALIGN(4); 120 | __copy_table_start__ = .; 121 | LONG (__etext) 122 | LONG (__data_start__) 123 | LONG (__data_end__ - __data_start__) 124 | LONG (__etext2) 125 | LONG (__data2_start__) 126 | LONG (__data2_end__ - __data2_start__) 127 | __copy_table_end__ = .; 128 | } > FLASH 129 | */ 130 | 131 | /* To clear multiple BSS sections, 132 | * uncomment .zero.table section and, 133 | * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ 134 | /* 135 | .zero.table : 136 | { 137 | . = ALIGN(4); 138 | __zero_table_start__ = .; 139 | LONG (__bss_start__) 140 | LONG (__bss_end__ - __bss_start__) 141 | LONG (__bss2_start__) 142 | LONG (__bss2_end__ - __bss2_start__) 143 | __zero_table_end__ = .; 144 | } > FLASH 145 | */ 146 | 147 | __etext = .; 148 | PROVIDE(__sketch_vectors_ptr = ORIGIN(FLASH) + LENGTH(FLASH)); 149 | 150 | 151 | .data : AT (__etext) 152 | { 153 | __data_start__ = .; 154 | *(vtable) 155 | *(.data*) 156 | 157 | . = ALIGN(4); 158 | /* preinit data */ 159 | PROVIDE_HIDDEN (__preinit_array_start = .); 160 | KEEP(*(.preinit_array)) 161 | PROVIDE_HIDDEN (__preinit_array_end = .); 162 | 163 | . = ALIGN(4); 164 | /* init data */ 165 | PROVIDE_HIDDEN (__init_array_start = .); 166 | KEEP(*(SORT(.init_array.*))) 167 | KEEP(*(.init_array)) 168 | PROVIDE_HIDDEN (__init_array_end = .); 169 | 170 | 171 | . = ALIGN(4); 172 | /* finit data */ 173 | PROVIDE_HIDDEN (__fini_array_start = .); 174 | KEEP(*(SORT(.fini_array.*))) 175 | KEEP(*(.fini_array)) 176 | PROVIDE_HIDDEN (__fini_array_end = .); 177 | 178 | KEEP(*(.jcr*)) 179 | . = ALIGN(4); 180 | /* All data end */ 181 | __data_end__ = .; 182 | 183 | } > RAM 184 | 185 | .bss : 186 | { 187 | . = ALIGN(4); 188 | __bss_start__ = .; 189 | *(.bss*) 190 | *(COMMON) 191 | . = ALIGN(4); 192 | __bss_end__ = .; 193 | } > RAM 194 | 195 | .heap (COPY): 196 | { 197 | __end__ = .; 198 | PROVIDE(end = .); 199 | *(.heap*) 200 | __HeapLimit = .; 201 | } > RAM 202 | 203 | /* .stack_dummy section doesn't contains any symbols. It is only 204 | * used for linker to calculate size of stack sections, and assign 205 | * values to stack symbols later */ 206 | .stack_dummy (COPY): 207 | { 208 | *(.stack*) 209 | } > RAM 210 | 211 | /* Set stack top to end of RAM, and stack limit move down by 212 | * size of stack_dummy section */ 213 | __StackTop = ORIGIN(RAM) + LENGTH(RAM); 214 | __StackLimit = __StackTop - SIZEOF(.stack_dummy); 215 | PROVIDE(__stack = __StackTop); 216 | 217 | __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; 218 | 219 | /* Check if data + heap + stack exceeds RAM limit */ 220 | ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") 221 | } 222 | -------------------------------------------------------------------------------- /Firmware/Bootloader/build_all_bootloaders.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | BOARD_ID=sparkfun_9dof NAME=SparkFun_9DoF_Razor make clean all 4 | 5 | BOARD_ID=arduino_zero NAME=samd21_sam_ba make clean all 6 | 7 | BOARD_ID=genuino_zero NAME=samd21_sam_ba_genuino make clean all 8 | 9 | BOARD_ID=arduino_mkr1000 NAME=samd21_sam_ba_arduino_mkr1000 make clean all 10 | mv -v samd21_sam_ba_arduino_mkr1000.* ../mkr1000/ 11 | 12 | BOARD_ID=genuino_mkr1000 NAME=samd21_sam_ba_genuino_mkr1000 make clean all 13 | mv -v samd21_sam_ba_genuino_mkr1000.* ../mkr1000/ 14 | 15 | echo Done building bootloaders! 16 | 17 | -------------------------------------------------------------------------------- /Firmware/Bootloader/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | #include "sam_ba_monitor.h" 23 | #include "sam_ba_serial.h" 24 | #include "board_definitions.h" 25 | #include "board_driver_led.h" 26 | #include "sam_ba_usb.h" 27 | #include "sam_ba_cdc.h" 28 | 29 | extern uint32_t __sketch_vectors_ptr; // Exported value from linker script 30 | extern void board_init(void); 31 | 32 | #if (defined DEBUG) && (DEBUG == 1) 33 | volatile uint32_t* pulSketch_Start_Address; 34 | #endif 35 | 36 | static volatile bool main_b_cdc_enable = false; 37 | 38 | /** 39 | * \brief Check the application startup condition 40 | * 41 | */ 42 | static void check_start_application(void) 43 | { 44 | // LED_init(); 45 | // LED_off(); 46 | 47 | #if defined(BOOT_DOUBLE_TAP_ADDRESS) 48 | #define DOUBLE_TAP_MAGIC 0x07738135 49 | if (PM->RCAUSE.bit.POR) 50 | { 51 | /* On power-on initialize double-tap */ 52 | BOOT_DOUBLE_TAP_DATA = 0; 53 | } 54 | else 55 | { 56 | if (BOOT_DOUBLE_TAP_DATA == DOUBLE_TAP_MAGIC) 57 | { 58 | /* Second tap, stay in bootloader */ 59 | BOOT_DOUBLE_TAP_DATA = 0; 60 | return; 61 | } 62 | 63 | /* First tap */ 64 | BOOT_DOUBLE_TAP_DATA = DOUBLE_TAP_MAGIC; 65 | 66 | /* Wait 0.5sec to see if the user tap reset again. 67 | * The loop value is based on SAMD21 default 1MHz clock @ reset. 68 | */ 69 | for (uint32_t i=0; i<125000; i++) /* 500ms */ 70 | /* force compiler to not optimize this... */ 71 | __asm__ __volatile__(""); 72 | 73 | /* Timeout happened, continue boot... */ 74 | BOOT_DOUBLE_TAP_DATA = 0; 75 | } 76 | #endif 77 | 78 | #if (!defined DEBUG) || ((defined DEBUG) && (DEBUG == 0)) 79 | uint32_t* pulSketch_Start_Address; 80 | #endif 81 | 82 | /* 83 | * Test sketch stack pointer @ &__sketch_vectors_ptr 84 | * Stay in SAM-BA if value @ (&__sketch_vectors_ptr) == 0xFFFFFFFF (Erased flash cell value) 85 | */ 86 | if (__sketch_vectors_ptr == 0xFFFFFFFF) 87 | { 88 | /* Stay in bootloader */ 89 | return; 90 | } 91 | 92 | /* 93 | * Load the sketch Reset Handler address 94 | * __sketch_vectors_ptr is exported from linker script and point on first 32b word of sketch vector table 95 | * First 32b word is sketch stack 96 | * Second 32b word is sketch entry point: Reset_Handler() 97 | */ 98 | pulSketch_Start_Address = &__sketch_vectors_ptr ; 99 | pulSketch_Start_Address++ ; 100 | 101 | /* 102 | * Test vector table address of sketch @ &__sketch_vectors_ptr 103 | * Stay in SAM-BA if this function is not aligned enough, ie not valid 104 | */ 105 | if ( ((uint32_t)(&__sketch_vectors_ptr) & ~SCB_VTOR_TBLOFF_Msk) != 0x00) 106 | { 107 | /* Stay in bootloader */ 108 | return; 109 | } 110 | 111 | 112 | #if defined(BOOT_LOAD_PIN) 113 | volatile PortGroup *boot_port = (volatile PortGroup *)(&(PORT->Group[BOOT_LOAD_PIN / 32])); 114 | volatile bool boot_en; 115 | 116 | // Enable the input mode in Boot GPIO Pin 117 | boot_port->DIRCLR.reg = BOOT_PIN_MASK; 118 | boot_port->PINCFG[BOOT_LOAD_PIN & 0x1F].reg = PORT_PINCFG_INEN | PORT_PINCFG_PULLEN; 119 | boot_port->OUTSET.reg = BOOT_PIN_MASK; 120 | // Read the BOOT_LOAD_PIN status 121 | boot_en = (boot_port->IN.reg) & BOOT_PIN_MASK; 122 | 123 | // Check the bootloader enable condition 124 | if (!boot_en) 125 | { 126 | // Stay in bootloader 127 | return; 128 | } 129 | #endif 130 | 131 | 132 | // LED_on(); 133 | 134 | /* Rebase the Stack Pointer */ 135 | __set_MSP( (uint32_t)(__sketch_vectors_ptr) ); 136 | 137 | /* Rebase the vector table base address */ 138 | SCB->VTOR = ((uint32_t)(&__sketch_vectors_ptr) & SCB_VTOR_TBLOFF_Msk); 139 | 140 | /* Jump to application Reset Handler in the application */ 141 | asm("bx %0"::"r"(*pulSketch_Start_Address)); 142 | } 143 | 144 | #if DEBUG_ENABLE 145 | # define DEBUG_PIN_HIGH port_pin_set_output_level(BOOT_LED, 1) 146 | # define DEBUG_PIN_LOW port_pin_set_output_level(BOOT_LED, 0) 147 | #else 148 | # define DEBUG_PIN_HIGH do{}while(0) 149 | # define DEBUG_PIN_LOW do{}while(0) 150 | #endif 151 | 152 | /** 153 | * \brief SAMD21 SAM-BA Main loop. 154 | * \return Unused (ANSI-C compatibility). 155 | */ 156 | int main(void) 157 | { 158 | #if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES 159 | P_USB_CDC pCdc; 160 | #endif 161 | DEBUG_PIN_HIGH; 162 | 163 | /* Jump in application if condition is satisfied */ 164 | check_start_application(); 165 | 166 | /* We have determined we should stay in the monitor. */ 167 | /* System initialization */ 168 | board_init(); 169 | __enable_irq(); 170 | 171 | #if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES 172 | /* UART is enabled in all cases */ 173 | serial_open(); 174 | #endif 175 | 176 | #if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES 177 | pCdc = usb_init(); 178 | #endif 179 | 180 | DEBUG_PIN_LOW; 181 | 182 | /* Initialize LEDs */ 183 | LED_init(); 184 | LEDRX_init(); 185 | LEDRX_off(); 186 | LEDTX_init(); 187 | LEDTX_off(); 188 | 189 | /* Start the sys tick (1 ms) */ 190 | SysTick_Config(1000); 191 | 192 | /* Wait for a complete enum on usb or a '#' char on serial line */ 193 | while (1) 194 | { 195 | #if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES 196 | if (pCdc->IsConfigured(pCdc) != 0) 197 | { 198 | main_b_cdc_enable = true; 199 | } 200 | 201 | /* Check if a USB enumeration has succeeded and if comm port has been opened */ 202 | if (main_b_cdc_enable) 203 | { 204 | sam_ba_monitor_init(SAM_BA_INTERFACE_USBCDC); 205 | /* SAM-BA on USB loop */ 206 | while( 1 ) 207 | { 208 | sam_ba_monitor_run(); 209 | } 210 | } 211 | #endif 212 | 213 | #if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES 214 | /* Check if a '#' has been received */ 215 | if (!main_b_cdc_enable && serial_sharp_received()) 216 | { 217 | sam_ba_monitor_init(SAM_BA_INTERFACE_USART); 218 | /* SAM-BA on Serial loop */ 219 | while(1) 220 | { 221 | sam_ba_monitor_run(); 222 | } 223 | } 224 | #endif 225 | } 226 | } 227 | 228 | void SysTick_Handler(void) 229 | { 230 | LED_pulse(); 231 | 232 | sam_ba_monitor_sys_tick(); 233 | } 234 | -------------------------------------------------------------------------------- /Firmware/Bootloader/sam_ba_cdc.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include "sam_ba_cdc.h" 21 | #include "board_driver_usb.h" 22 | 23 | usb_cdc_line_coding_t line_coding= 24 | { 25 | 115200, // baudrate 26 | 0, // 1 Stop Bit 27 | 0, // None Parity 28 | 8 // 8 Data bits 29 | }; 30 | 31 | #define pCdc (&sam_ba_cdc) 32 | 33 | int cdc_putc(/*P_USB_CDC pCdc,*/ int value) 34 | { 35 | /* Send single byte on USB CDC */ 36 | USB_Write(pCdc->pUsb, (const char *)&value, 1, USB_EP_IN); 37 | 38 | return 1; 39 | } 40 | 41 | int cdc_getc(/*P_USB_CDC pCdc*/void) 42 | { 43 | uint8_t rx_char; 44 | 45 | /* Read singly byte on USB CDC */ 46 | USB_Read(pCdc->pUsb, (char *)&rx_char, 1); 47 | 48 | return (int)rx_char; 49 | } 50 | 51 | bool cdc_is_rx_ready(/*P_USB_CDC pCdc*/void) 52 | { 53 | /* Check whether the device is configured */ 54 | if ( !USB_IsConfigured(pCdc) ) 55 | return 0; 56 | 57 | /* Return transfer complete 0 flag status */ 58 | return (pCdc->pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT & (1<<0)); 59 | } 60 | 61 | uint32_t cdc_write_buf(/*P_USB_CDC pCdc,*/ void const* data, uint32_t length) 62 | { 63 | /* Send the specified number of bytes on USB CDC */ 64 | USB_Write(pCdc->pUsb, (const char *)data, length, USB_EP_IN); 65 | return length; 66 | } 67 | 68 | uint32_t cdc_read_buf(/*P_USB_CDC pCdc,*/ void* data, uint32_t length) 69 | { 70 | /* Check whether the device is configured */ 71 | if ( !USB_IsConfigured(pCdc) ) 72 | return 0; 73 | 74 | /* Read from USB CDC */ 75 | return USB_Read(pCdc->pUsb, (char *)data, length); 76 | } 77 | 78 | uint32_t cdc_read_buf_xmd(/*P_USB_CDC pCdc,*/ void* data, uint32_t length) 79 | { 80 | /* Check whether the device is configured */ 81 | if ( !USB_IsConfigured(pCdc) ) 82 | return 0; 83 | 84 | /* Blocking read till specified number of bytes is received */ 85 | // XXX: USB_Read_blocking is not reliable 86 | // return USB_Read_blocking(pCdc, (char *)data, length); 87 | 88 | char *dst = (char *)data; 89 | uint32_t remaining = length; 90 | while (remaining) 91 | { 92 | uint32_t readed = USB_Read(pCdc->pUsb, (char *)dst, remaining); 93 | remaining -= readed; 94 | dst += readed; 95 | } 96 | 97 | return length; 98 | } 99 | -------------------------------------------------------------------------------- /Firmware/Bootloader/sam_ba_cdc.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _SAM_BA_USB_CDC_H_ 21 | #define _SAM_BA_USB_CDC_H_ 22 | 23 | #include 24 | #include "sam_ba_usb.h" 25 | 26 | typedef struct 27 | { 28 | uint32_t dwDTERate; 29 | uint8_t bCharFormat; 30 | uint8_t bParityType; 31 | uint8_t bDataBits; 32 | } usb_cdc_line_coding_t; 33 | 34 | /* CDC Class Specific Request Code */ 35 | #define GET_LINE_CODING 0x21A1 36 | #define SET_LINE_CODING 0x2021 37 | #define SET_CONTROL_LINE_STATE 0x2221 38 | 39 | extern usb_cdc_line_coding_t line_coding; 40 | 41 | 42 | /** 43 | * \brief Sends a single byte through USB CDC 44 | * 45 | * \param Data to send 46 | * \return number of data sent 47 | */ 48 | int cdc_putc(/*P_USB_CDC pCdc,*/ int value); 49 | 50 | /** 51 | * \brief Reads a single byte through USB CDC 52 | * 53 | * \return Data read through USB 54 | */ 55 | int cdc_getc(/*P_USB_CDC pCdc*/); 56 | 57 | /** 58 | * \brief Checks if a character has been received on USB CDC 59 | * 60 | * \return \c 1 if a byte is ready to be read. 61 | */ 62 | bool cdc_is_rx_ready(/*P_USB_CDC pCdc*/); 63 | 64 | /** 65 | * \brief Sends buffer on USB CDC 66 | * 67 | * \param data pointer 68 | * \param number of data to send 69 | * \return number of data sent 70 | */ 71 | uint32_t cdc_write_buf(/*P_USB_CDC pCdc,*/ void const* data, uint32_t length); 72 | 73 | /** 74 | * \brief Gets data on USB CDC 75 | * 76 | * \param data pointer 77 | * \param number of data to read 78 | * \return number of data read 79 | */ 80 | uint32_t cdc_read_buf(/*P_USB_CDC pCdc,*/ void* data, uint32_t length); 81 | 82 | /** 83 | * \brief Gets specified number of bytes on USB CDC 84 | * 85 | * \param data pointer 86 | * \param number of data to read 87 | * \return number of data read 88 | */ 89 | uint32_t cdc_read_buf_xmd(/*P_USB_CDC pCdc,*/ void* data, uint32_t length); 90 | 91 | #endif // _SAM_BA_USB_CDC_H_ 92 | -------------------------------------------------------------------------------- /Firmware/Bootloader/sam_ba_monitor.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _MONITOR_SAM_BA_H_ 21 | #define _MONITOR_SAM_BA_H_ 22 | 23 | #define SAM_BA_VERSION "2.0" 24 | 25 | /* Enable the interfaces to save code size */ 26 | #define SAM_BA_BOTH_INTERFACES 0 27 | #define SAM_BA_UART_ONLY 1 28 | #define SAM_BA_USBCDC_ONLY 2 29 | 30 | #ifndef SAM_BA_INTERFACE 31 | #define SAM_BA_INTERFACE SAM_BA_BOTH_INTERFACES 32 | #endif 33 | 34 | /* Selects USB as the communication interface of the monitor */ 35 | #define SAM_BA_INTERFACE_USBCDC 0 36 | /* Selects USART as the communication interface of the monitor */ 37 | #define SAM_BA_INTERFACE_USART 1 38 | 39 | /* Selects USB as the communication interface of the monitor */ 40 | #define SIZEBUFMAX 64 41 | 42 | /** 43 | * \brief Initialize the monitor 44 | * 45 | */ 46 | void sam_ba_monitor_init(uint8_t com_interface); 47 | 48 | /** 49 | * \brief System tick function of the SAM-BA Monitor 50 | * 51 | */ 52 | void sam_ba_monitor_sys_tick(void); 53 | 54 | /** 55 | * \brief Main function of the SAM-BA Monitor 56 | * 57 | */ 58 | void sam_ba_monitor_run(void); 59 | 60 | /** 61 | * \brief 62 | * 63 | */ 64 | void sam_ba_putdata_term(uint8_t* data, uint32_t length); 65 | 66 | /** 67 | * \brief 68 | * 69 | */ 70 | void call_applet(uint32_t address); 71 | 72 | #endif // _MONITOR_SAM_BA_H_ 73 | -------------------------------------------------------------------------------- /Firmware/Bootloader/sam_ba_serial.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include "board_definitions.h" 22 | #include "sam_ba_serial.h" 23 | #include "board_driver_serial.h" 24 | 25 | /* Local reference to current Usart instance in use with this driver */ 26 | //struct usart_module usart_sam_ba; 27 | 28 | /* Variable to let the main task select the appropriate communication interface */ 29 | volatile uint8_t b_sharp_received; 30 | 31 | /* RX and TX Buffers + rw pointers for each buffer */ 32 | volatile uint8_t buffer_rx_usart[USART_BUFFER_SIZE]; 33 | 34 | volatile uint8_t idx_rx_read; 35 | volatile uint8_t idx_rx_write; 36 | 37 | volatile uint8_t buffer_tx_usart[USART_BUFFER_SIZE]; 38 | 39 | volatile uint8_t idx_tx_read; 40 | volatile uint8_t idx_tx_write; 41 | 42 | /* Test for timeout in AT91F_GetChar */ 43 | uint8_t error_timeout; 44 | uint16_t size_of_data; 45 | uint8_t mode_of_transfer; 46 | 47 | #define BOOT_USART_PAD(n) BOOT_USART_PAD##n 48 | 49 | /** 50 | * \brief Open the given USART 51 | */ 52 | void serial_open(void) 53 | { 54 | uint32_t port; 55 | uint32_t pin; 56 | 57 | /* Configure the port pins for SERCOM_USART */ 58 | if (BOOT_USART_PAD0 != PINMUX_UNUSED) 59 | { 60 | /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ 61 | port = (BOOT_USART_PAD0 & 0x200000) >> 21; 62 | pin = (BOOT_USART_PAD0 >> 16); 63 | PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; 64 | PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); 65 | PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD0 & 0xFF) << (4 * (pin & 0x01u)); 66 | } 67 | 68 | if (BOOT_USART_PAD1 != PINMUX_UNUSED) 69 | { 70 | /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ 71 | port = (BOOT_USART_PAD1 & 0x200000) >> 21; 72 | pin = BOOT_USART_PAD1 >> 16; 73 | PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; 74 | PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); 75 | PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD1 & 0xFF) << (4 * (pin & 0x01u)); 76 | } 77 | 78 | if (BOOT_USART_PAD2 != PINMUX_UNUSED) 79 | { 80 | /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ 81 | port = (BOOT_USART_PAD2 & 0x200000) >> 21; 82 | pin = BOOT_USART_PAD2 >> 16; 83 | PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; 84 | PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); 85 | PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD2 & 0xFF) << (4 * (pin & 0x01u)); 86 | } 87 | 88 | if (BOOT_USART_PAD3 != PINMUX_UNUSED) 89 | { 90 | /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ 91 | port = (BOOT_USART_PAD3 & 0x200000) >> 21; 92 | pin = BOOT_USART_PAD3 >> 16; 93 | PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; 94 | PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); 95 | PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD3 & 0xFF) << (4 * (pin & 0x01u)); 96 | } 97 | 98 | /* Enable clock for BOOT_USART_MODULE */ 99 | PM->APBCMASK.reg |= BOOT_USART_BUS_CLOCK_INDEX ; 100 | 101 | /* Set GCLK_GEN0 as source for GCLK_ID_SERCOMx_CORE */ 102 | GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( BOOT_USART_PER_CLOCK_INDEX ) | // Generic Clock 0 (SERCOMx) 103 | GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source 104 | GCLK_CLKCTRL_CLKEN ; 105 | 106 | while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) 107 | { 108 | /* Wait for synchronization */ 109 | } 110 | 111 | /* Baud rate 115200 - clock 48MHz -> BAUD value-63018 */ 112 | uart_basic_init(BOOT_USART_MODULE, 63018, BOOT_USART_PAD_SETTINGS); 113 | 114 | //Initialize flag 115 | b_sharp_received = false; 116 | idx_rx_read = 0; 117 | idx_rx_write = 0; 118 | idx_tx_read = 0; 119 | idx_tx_write = 0; 120 | 121 | error_timeout = 0; 122 | } 123 | 124 | /** 125 | * \brief Close communication line 126 | */ 127 | void serial_close(void) 128 | { 129 | uart_disable(BOOT_USART_MODULE); 130 | } 131 | 132 | /** 133 | * \brief Puts a byte on usart line 134 | * The type int is used to support printf redirection from compiler LIB. 135 | * 136 | * \param value Value to put 137 | * 138 | * \return \c 1 if function was successfully done, otherwise \c 0. 139 | */ 140 | int serial_putc(int value) 141 | { 142 | uart_write_byte(BOOT_USART_MODULE, (uint8_t)value); 143 | return 1; 144 | } 145 | 146 | int serial_getc(void) 147 | { 148 | uint16_t retval; 149 | //Wait until input buffer is filled 150 | while(!(serial_is_rx_ready())); 151 | retval = (uint16_t)uart_read_byte(BOOT_USART_MODULE); 152 | //usart_read_wait(&usart_sam_ba, &retval); 153 | return (int)retval; 154 | 155 | } 156 | 157 | int serial_sharp_received(void) 158 | { 159 | if (serial_is_rx_ready()) 160 | { 161 | if (serial_getc() == SHARP_CHARACTER) 162 | return (true); 163 | } 164 | return (false); 165 | } 166 | 167 | bool serial_is_rx_ready(void) 168 | { 169 | return (BOOT_USART_MODULE->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_RXC); 170 | } 171 | 172 | int serial_readc(void) 173 | { 174 | int retval; 175 | retval = buffer_rx_usart[idx_rx_read]; 176 | idx_rx_read = (idx_rx_read + 1) & (USART_BUFFER_SIZE - 1); 177 | return (retval); 178 | } 179 | 180 | //Send given data (polling) 181 | uint32_t serial_putdata(void const* data, uint32_t length) 182 | { 183 | uint32_t i; 184 | uint8_t* ptrdata; 185 | ptrdata = (uint8_t*) data; 186 | for (i = 0; i < length; i++) 187 | { 188 | serial_putc(*ptrdata); 189 | ptrdata++; 190 | } 191 | return (i); 192 | } 193 | 194 | //Get data from comm. device 195 | uint32_t serial_getdata(void* data, uint32_t length) 196 | { 197 | uint8_t* ptrdata; 198 | ptrdata = (uint8_t*) data; 199 | *ptrdata = serial_getc(); 200 | return (1); 201 | } 202 | 203 | static const uint16_t crc16Table[256]= 204 | { 205 | 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 206 | 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, 207 | 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, 208 | 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, 209 | 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, 210 | 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, 211 | 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, 212 | 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, 213 | 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, 214 | 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, 215 | 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, 216 | 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, 217 | 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, 218 | 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, 219 | 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, 220 | 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, 221 | 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, 222 | 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, 223 | 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, 224 | 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, 225 | 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, 226 | 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, 227 | 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, 228 | 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, 229 | 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, 230 | 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, 231 | 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, 232 | 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, 233 | 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, 234 | 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, 235 | 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, 236 | 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 237 | }; 238 | 239 | //*---------------------------------------------------------------------------- 240 | //* \brief Compute the CRC 241 | //*---------------------------------------------------------------------------- 242 | unsigned short serial_add_crc(char ptr, unsigned short crc) 243 | { 244 | return (crc << 8) ^ crc16Table[((crc >> 8) ^ ptr) & 0xff]; 245 | } 246 | 247 | //*---------------------------------------------------------------------------- 248 | //* \brief 249 | //*---------------------------------------------------------------------------- 250 | static uint16_t getbytes(uint8_t *ptr_data, uint16_t length) 251 | { 252 | uint16_t crc = 0; 253 | uint16_t cpt; 254 | uint8_t c; 255 | 256 | for (cpt = 0; cpt < length; ++cpt) 257 | { 258 | c = serial_getc(); 259 | if (error_timeout) 260 | return 1; 261 | crc = serial_add_crc(c, crc); 262 | //crc = (crc << 8) ^ xcrc16tab[(crc>>8) ^ c]; 263 | if (size_of_data || mode_of_transfer) 264 | { 265 | *ptr_data++ = c; 266 | if (length == PKTLEN_128) 267 | size_of_data--; 268 | } 269 | } 270 | 271 | return crc; 272 | } 273 | 274 | //*---------------------------------------------------------------------------- 275 | //* \brief Used by Xup to send packets. 276 | //*---------------------------------------------------------------------------- 277 | static int putPacket(uint8_t *tmppkt, uint8_t sno) 278 | { 279 | uint32_t i; 280 | uint16_t chksm; 281 | uint8_t data; 282 | 283 | chksm = 0; 284 | 285 | serial_putc(SOH); 286 | 287 | serial_putc(sno); 288 | serial_putc((uint8_t) ~(sno)); 289 | 290 | for (i = 0; i < PKTLEN_128; i++) 291 | { 292 | if (size_of_data || mode_of_transfer) 293 | { 294 | data = *tmppkt++; 295 | size_of_data--; 296 | } 297 | else 298 | data = 0x00; 299 | 300 | serial_putc(data); 301 | 302 | //chksm = (chksm<<8) ^ xcrc16tab[(chksm>>8)^data]; 303 | chksm = serial_add_crc(data, chksm); 304 | } 305 | 306 | /* An "endian independent way to extract the CRC bytes. */ 307 | serial_putc((uint8_t) (chksm >> 8)); 308 | serial_putc((uint8_t) chksm); 309 | 310 | return (serial_getc()); /* Wait for ack */ 311 | } 312 | 313 | //*---------------------------------------------------------------------------- 314 | //* \brief Called when a transfer from target to host is being made (considered 315 | //* an upload). 316 | //*---------------------------------------------------------------------------- 317 | //Send given data (polling) using xmodem (if necessary) 318 | uint32_t serial_putdata_xmd(void const* data, uint32_t length) 319 | { 320 | uint8_t c, sno = 1; 321 | uint8_t done; 322 | uint8_t * ptr_data = (uint8_t *) data; 323 | error_timeout = 0; 324 | if (!length) 325 | mode_of_transfer = 1; 326 | else 327 | { 328 | size_of_data = length; 329 | mode_of_transfer = 0; 330 | } 331 | 332 | if (length & (PKTLEN_128 - 1)) 333 | { 334 | length += PKTLEN_128; 335 | length &= ~(PKTLEN_128 - 1); 336 | } 337 | 338 | /* Startup synchronization... */ 339 | /* Wait to receive a NAK or 'C' from receiver. */ 340 | done = 0; 341 | while (!done) { 342 | c = (uint8_t) serial_getc(); 343 | if (error_timeout) 344 | { // Test for timeout in serial_getc 345 | error_timeout = 0; 346 | c = (uint8_t) serial_getc(); 347 | if (error_timeout) 348 | { 349 | error_timeout = 0; 350 | return (0); 351 | } 352 | } 353 | switch (c) 354 | { 355 | case NAK: 356 | done = 1; 357 | // ("CSM"); 358 | break; 359 | case 'C': 360 | done = 1; 361 | // ("CRC"); 362 | break; 363 | case 'q': /* ELS addition, not part of XMODEM spec. */ 364 | return (0); 365 | default: 366 | break; 367 | } 368 | } 369 | 370 | done = 0; 371 | sno = 1; 372 | while (!done) 373 | { 374 | c = (uint8_t) putPacket((uint8_t *) ptr_data, sno); 375 | if (error_timeout) 376 | { // Test for timeout in serial_getc 377 | error_timeout = 0; 378 | return (0); 379 | } 380 | switch (c) 381 | { 382 | case ACK: 383 | ++sno; 384 | length -= PKTLEN_128; 385 | ptr_data += PKTLEN_128; 386 | // ("A"); 387 | break; 388 | 389 | case NAK: 390 | // ("N"); 391 | break; 392 | 393 | case CAN: 394 | case EOT: 395 | default: 396 | done = 0; 397 | break; 398 | } 399 | 400 | if (!length) 401 | { 402 | serial_putc(EOT); 403 | serial_getc(); /* Flush the ACK */ 404 | break; 405 | } 406 | // ("!"); 407 | } 408 | 409 | mode_of_transfer = 0; 410 | // ("Xup_done."); 411 | return (1); 412 | // return(0); 413 | } 414 | 415 | /*---------------------------------------------------------------------------- 416 | * \brief Used by serial_getdata_xmd to retrieve packets. 417 | */ 418 | static uint8_t getPacket(uint8_t *ptr_data, uint8_t sno) 419 | { 420 | uint8_t seq[2]; 421 | uint16_t crc, xcrc; 422 | 423 | getbytes(seq, 2); 424 | xcrc = getbytes(ptr_data, PKTLEN_128); 425 | if (error_timeout) 426 | return (false); 427 | 428 | /* An "endian independent way to combine the CRC bytes. */ 429 | crc = (uint16_t) serial_getc() << 8; 430 | crc += (uint16_t) serial_getc(); 431 | 432 | if (error_timeout == 1) 433 | return (false); 434 | 435 | if ((crc != xcrc) || (seq[0] != sno) || (seq[1] != (uint8_t) (~sno))) 436 | { 437 | serial_putc(CAN); 438 | return (false); 439 | } 440 | 441 | serial_putc(ACK); 442 | return (true); 443 | } 444 | 445 | //*---------------------------------------------------------------------------- 446 | //* \brief Called when a transfer from host to target is being made (considered 447 | //* an download). 448 | //*---------------------------------------------------------------------------- 449 | //Get data from comm. device using xmodem (if necessary) 450 | uint32_t serial_getdata_xmd(void* data, uint32_t length) 451 | { 452 | uint32_t timeout; 453 | char c; 454 | uint8_t * ptr_data = (uint8_t *) data; 455 | uint32_t b_run, nbr_of_timeout = 100; 456 | uint8_t sno = 0x01; 457 | uint32_t data_transfered = 0; 458 | 459 | //Copied from legacy source code ... might need some tweaking 460 | uint32_t loops_per_second = CPU_FREQUENCY/60; 461 | 462 | error_timeout = 0; 463 | 464 | if (length == 0) 465 | mode_of_transfer = 1; 466 | else 467 | { 468 | size_of_data = length; 469 | mode_of_transfer = 0; 470 | } 471 | 472 | /* Startup synchronization... */ 473 | /* Continuously send NAK or 'C' until sender responds. */ 474 | // ("Xdown"); 475 | while (1) 476 | { 477 | serial_putc('C'); 478 | timeout = loops_per_second; 479 | while (!(serial_is_rx_ready()) && timeout) 480 | timeout--; 481 | if (timeout) 482 | break; 483 | 484 | if (!(--nbr_of_timeout)) 485 | return (0); 486 | // return -1; 487 | } 488 | 489 | b_run = true; 490 | // ("Got response"); 491 | while (b_run != false) 492 | { 493 | c = (char) serial_getc(); 494 | if (error_timeout) 495 | { // Test for timeout in serial_getc 496 | error_timeout = 0; 497 | return (0); 498 | // return (-1); 499 | } 500 | switch (c) 501 | { 502 | case SOH: /* 128-byte incoming packet */ 503 | // ("O"); 504 | b_run = getPacket(ptr_data, sno); 505 | if (error_timeout) 506 | { // Test for timeout in serial_getc 507 | error_timeout = 0; 508 | return (0); 509 | // return (-1); 510 | } 511 | if (b_run == true) 512 | { 513 | ++sno; 514 | ptr_data += PKTLEN_128; 515 | data_transfered += PKTLEN_128; 516 | } 517 | break; 518 | case EOT: // ("E"); 519 | serial_putc(ACK); 520 | b_run = false; 521 | break; 522 | case CAN: // ("C"); 523 | case ESC: /* "X" User-invoked abort */ 524 | default: 525 | b_run = false; 526 | break; 527 | } 528 | // ("!"); 529 | } 530 | mode_of_transfer = 0; 531 | return (true); 532 | // return(b_run); 533 | } 534 | 535 | -------------------------------------------------------------------------------- /Firmware/Bootloader/sam_ba_serial.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef _SAM_BA_SERIAL_H_ 21 | #define _SAM_BA_SERIAL_H_ 22 | 23 | #include 24 | #include 25 | 26 | 27 | /* USART buffer size (must be a power of two) */ 28 | #define USART_BUFFER_SIZE (128) 29 | 30 | /* Define the default time-out value for USART. */ 31 | #define USART_DEFAULT_TIMEOUT (1000) 32 | 33 | /* Xmodem related defines */ 34 | /* CRC16 polynomial */ 35 | #define CRC16POLY (0x1021) 36 | 37 | #define SHARP_CHARACTER '#' 38 | 39 | /* X/Ymodem protocol: */ 40 | #define SOH (0x01) 41 | //#define STX (0x02) 42 | #define EOT (0x04) 43 | #define ACK (0x06) 44 | #define NAK (0x15) 45 | #define CAN (0x18) 46 | #define ESC (0x1b) 47 | 48 | #define PKTLEN_128 (128) 49 | 50 | 51 | /** 52 | * \brief Open the given USART 53 | */ 54 | void serial_open(void); 55 | 56 | /** 57 | * \brief Stops the USART 58 | */ 59 | void serial_close(void); 60 | 61 | /** 62 | * \brief Puts a byte on usart line 63 | * 64 | * \param value Value to put 65 | * 66 | * \return \c 1 if function was successfully done, otherwise \c 0. 67 | */ 68 | int serial_putc(int value); 69 | 70 | /** 71 | * \brief Waits and gets a value on usart line 72 | * 73 | * \return value read on usart line 74 | */ 75 | int serial_getc(void); 76 | 77 | /** 78 | * \brief Returns true if the SAM-BA Uart received the sharp char 79 | * 80 | * \return Returns true if the SAM-BA Uart received the sharp char 81 | */ 82 | int serial_sharp_received(void); 83 | 84 | /** 85 | * \brief This function checks if a character has been received on the usart line 86 | * 87 | * \return \c 1 if a byte is ready to be read. 88 | */ 89 | bool serial_is_rx_ready(void); 90 | 91 | /** 92 | * \brief Gets a value on usart line 93 | * 94 | * \return value read on usart line 95 | */ 96 | int serial_readc(void); 97 | 98 | /** 99 | * \brief Send buffer on usart line 100 | * 101 | * \param data pointer 102 | * \param number of data to send 103 | * \return number of data sent 104 | */ 105 | uint32_t serial_putdata(void const* data, uint32_t length); //Send given data (polling) 106 | 107 | /** 108 | * \brief Gets data from usart line 109 | * 110 | * \param data pointer 111 | * \param number of data to get 112 | * \return value read on usart line 113 | */ 114 | uint32_t serial_getdata(void* data, uint32_t length); //Get data from comm. device 115 | 116 | /** 117 | * \brief Send buffer on usart line using Xmodem protocol 118 | * 119 | * \param data pointer 120 | * \param number of data to send 121 | * \return number of data sent 122 | */ 123 | uint32_t serial_putdata_xmd(void const* data, uint32_t length); //Send given data (polling) using xmodem (if necessary) 124 | 125 | /** 126 | * \brief Gets data from usart line using Xmodem protocol 127 | * 128 | * \param data pointer 129 | * \param number of data to get 130 | * \return value read on usart line 131 | */ 132 | uint32_t serial_getdata_xmd(void* data, uint32_t length); //Get data from comm. device using xmodem (if necessary) 133 | 134 | /** 135 | * \brief Compute the CRC 136 | * 137 | * \param Char to add to CRC 138 | * \param Previous CRC 139 | * \return The new computed CRC 140 | */ 141 | unsigned short serial_add_crc(char c, unsigned short crc); 142 | 143 | #endif // _SAM_BA_SERIAL_H_ 144 | -------------------------------------------------------------------------------- /Firmware/Bootloader/sam_ba_usb.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | #include "board_definitions.h" 23 | #include "sam_ba_usb.h" 24 | #include "board_driver_usb.h" 25 | #include "sam_ba_cdc.h" 26 | 27 | /* This data array will be copied into SRAM as its length is inferior to 64 bytes, 28 | * and so can stay in flash. 29 | */ 30 | static __attribute__((__aligned__(4))) 31 | const char devDescriptor[] = 32 | { 33 | /* Device descriptor */ 34 | 0x12, // bLength 35 | 0x01, // bDescriptorType 36 | 0x00, // bcdUSB L 37 | 0x02, // bcdUSB H 38 | 0x02, // bDeviceClass: CDC class code 39 | 0x00, // bDeviceSubclass: CDC class sub code 40 | 0x00, // bDeviceProtocol: CDC Device protocol 41 | 0x40, // bMaxPacketSize0 42 | USB_VID_LOW, // idVendor L 43 | USB_VID_HIGH, // idVendor H 44 | USB_PID_LOW, // idProduct L 45 | USB_PID_HIGH, // idProduct H 46 | 0x00, // bcdDevice L, here matching SAM-BA version 47 | 0x02, // bcdDevice H 48 | STRING_INDEX_MANUFACTURER, // iManufacturer 49 | STRING_INDEX_PRODUCT, // iProduct 50 | 0x00, // SerialNumber, should be based on product unique ID 51 | 0x01 // bNumConfigs 52 | }; 53 | 54 | /* This data array will be consumed directly by USB_Write() and must be in SRAM. 55 | * We cannot send data from product internal flash. 56 | */ 57 | static __attribute__((__aligned__(4))) 58 | char cfgDescriptor[] = 59 | { 60 | /* ============== CONFIGURATION 1 =========== */ 61 | /* Configuration 1 descriptor */ 62 | 0x09, // CbLength 63 | 0x02, // CbDescriptorType 64 | 0x43, // CwTotalLength 2 EP + Control 65 | 0x00, 66 | 0x02, // CbNumInterfaces 67 | 0x01, // CbConfigurationValue 68 | 0x00, // CiConfiguration 69 | 0x80, // CbmAttributes Bus powered without remote wakeup: 0x80, Self powered without remote wakeup: 0xc0 70 | 0x32, // CMaxPower, report using 100mA, enough for a bootloader 71 | 72 | /* Communication Class Interface Descriptor Requirement */ 73 | 0x09, // bLength 74 | 0x04, // bDescriptorType 75 | 0x00, // bInterfaceNumber 76 | 0x00, // bAlternateSetting 77 | 0x01, // bNumEndpoints 78 | 0x02, // bInterfaceClass 79 | 0x02, // bInterfaceSubclass 80 | 0x00, // bInterfaceProtocol 81 | 0x00, // iInterface 82 | 83 | /* Header Functional Descriptor */ 84 | 0x05, // bFunction Length 85 | 0x24, // bDescriptor type: CS_INTERFACE 86 | 0x00, // bDescriptor subtype: Header Func Desc 87 | 0x10, // bcdCDC:1.1 88 | 0x01, 89 | 90 | /* ACM Functional Descriptor */ 91 | 0x04, // bFunctionLength 92 | 0x24, // bDescriptor Type: CS_INTERFACE 93 | 0x02, // bDescriptor Subtype: ACM Func Desc 94 | 0x00, // bmCapabilities 95 | 96 | /* Union Functional Descriptor */ 97 | 0x05, // bFunctionLength 98 | 0x24, // bDescriptorType: CS_INTERFACE 99 | 0x06, // bDescriptor Subtype: Union Func Desc 100 | 0x00, // bMasterInterface: Communication Class Interface 101 | 0x01, // bSlaveInterface0: Data Class Interface 102 | 103 | /* Call Management Functional Descriptor */ 104 | 0x05, // bFunctionLength 105 | 0x24, // bDescriptor Type: CS_INTERFACE 106 | 0x01, // bDescriptor Subtype: Call Management Func Desc 107 | 0x00, // bmCapabilities: D1 + D0 108 | 0x01, // bDataInterface: Data Class Interface 1 109 | 110 | /* Endpoint 1 descriptor */ 111 | 0x07, // bLength 112 | 0x05, // bDescriptorType 113 | 0x83, // bEndpointAddress, Endpoint 03 - IN 114 | 0x03, // bmAttributes INT 115 | 0x08, // wMaxPacketSize 116 | 0x00, 117 | 0xFF, // bInterval 118 | 119 | /* Data Class Interface Descriptor Requirement */ 120 | 0x09, // bLength 121 | 0x04, // bDescriptorType 122 | 0x01, // bInterfaceNumber 123 | 0x00, // bAlternateSetting 124 | 0x02, // bNumEndpoints 125 | 0x0A, // bInterfaceClass 126 | 0x00, // bInterfaceSubclass 127 | 0x00, // bInterfaceProtocol 128 | 0x00, // iInterface 129 | 130 | /* First alternate setting */ 131 | /* Endpoint 1 descriptor */ 132 | 0x07, // bLength 133 | 0x05, // bDescriptorType 134 | 0x81, // bEndpointAddress, Endpoint 01 - IN 135 | 0x02, // bmAttributes BULK 136 | USB_EP_IN_SIZE, // wMaxPacketSize 137 | 0x00, 138 | 0x00, // bInterval 139 | 140 | /* Endpoint 2 descriptor */ 141 | 0x07, // bLength 142 | 0x05, // bDescriptorType 143 | 0x02, // bEndpointAddress, Endpoint 02 - OUT 144 | 0x02, // bmAttributes BULK 145 | USB_EP_OUT_SIZE, // wMaxPacketSize 146 | 0x00, 147 | 0x00 // bInterval 148 | }; 149 | 150 | #ifndef STRING_MANUFACTURER 151 | # define STRING_MANUFACTURER "Arduino LLC" 152 | #endif 153 | 154 | #ifndef STRING_PRODUCT 155 | # define STRING_PRODUCT "Arduino Zero" 156 | #endif 157 | 158 | USB_CDC sam_ba_cdc; 159 | 160 | /*---------------------------------------------------------------------------- 161 | * \brief This function is a callback invoked when a SETUP packet is received 162 | */ 163 | void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc) 164 | { 165 | Usb *pUsb = pCdc->pUsb; 166 | static volatile uint8_t bmRequestType, bRequest, dir; 167 | static volatile uint16_t wValue, wIndex, wLength, wStatus; 168 | 169 | /* Clear the Received Setup flag */ 170 | pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.RXSTP = true; 171 | 172 | /* Read the USB request parameters */ 173 | bmRequestType = udd_ep_out_cache_buffer[0][0]; 174 | bRequest = udd_ep_out_cache_buffer[0][1]; 175 | wValue = (udd_ep_out_cache_buffer[0][2] & 0xFF); 176 | wValue |= (udd_ep_out_cache_buffer[0][3] << 8); 177 | wIndex = (udd_ep_out_cache_buffer[0][4] & 0xFF); 178 | wIndex |= (udd_ep_out_cache_buffer[0][5] << 8); 179 | wLength = (udd_ep_out_cache_buffer[0][6] & 0xFF); 180 | wLength |= (udd_ep_out_cache_buffer[0][7] << 8); 181 | 182 | /* Clear the Bank 0 ready flag on Control OUT */ 183 | pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; 184 | 185 | /* Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1 */ 186 | switch ((bRequest << 8) | bmRequestType) 187 | { 188 | case STD_GET_DESCRIPTOR: 189 | if (wValue>>8 == STD_GET_DESCRIPTOR_DEVICE) 190 | { 191 | /* Return Device Descriptor */ 192 | USB_Write(pCdc->pUsb, devDescriptor, SAM_BA_MIN(sizeof(devDescriptor), wLength), USB_EP_CTRL); 193 | } 194 | else if (wValue>>8 == STD_GET_DESCRIPTOR_CONFIGURATION) 195 | { 196 | /* Return Configuration Descriptor */ 197 | USB_Write(pCdc->pUsb, cfgDescriptor, SAM_BA_MIN(sizeof(cfgDescriptor), wLength), USB_EP_CTRL); 198 | } 199 | else if (wValue>>8 == STD_GET_DESCRIPTOR_STRING) 200 | { 201 | switch ( wValue & 0xff ) 202 | { 203 | case STRING_INDEX_LANGUAGES: { 204 | uint16_t STRING_LANGUAGE[2] = { (STD_GET_DESCRIPTOR_STRING<<8) | 4, 0x0409 }; 205 | 206 | USB_Write(pCdc->pUsb, (const char*)STRING_LANGUAGE, SAM_BA_MIN(sizeof(STRING_LANGUAGE), wLength), USB_EP_CTRL); 207 | } 208 | break; 209 | 210 | case STRING_INDEX_MANUFACTURER: 211 | USB_SendString(pCdc->pUsb, STRING_MANUFACTURER, wLength ); 212 | break; 213 | 214 | case STRING_INDEX_PRODUCT: 215 | USB_SendString(pCdc->pUsb, STRING_PRODUCT, wLength ); 216 | break; 217 | default: 218 | /* Stall the request */ 219 | USB_SendStall(pUsb, true); 220 | break; 221 | } 222 | } 223 | else 224 | { 225 | /* Stall the request */ 226 | USB_SendStall(pUsb, true); 227 | } 228 | break; 229 | 230 | case STD_SET_ADDRESS: 231 | /* Send ZLP */ 232 | USB_SendZlp(pUsb); 233 | /* Set device address to the newly received address from host */ 234 | USB_SetAddress(pCdc->pUsb, wValue); 235 | break; 236 | 237 | case STD_SET_CONFIGURATION: 238 | /* Store configuration */ 239 | pCdc->currentConfiguration = (uint8_t)wValue; 240 | 241 | /* Send ZLP */ 242 | USB_SendZlp(pUsb); 243 | 244 | /* Configure the 3 needed endpoints */ 245 | USB_Configure(pUsb); 246 | break; 247 | 248 | case STD_GET_CONFIGURATION: 249 | /* Return current configuration value */ 250 | USB_Write(pCdc->pUsb, (char *) &(pCdc->currentConfiguration), sizeof(pCdc->currentConfiguration), USB_EP_CTRL); 251 | break; 252 | 253 | case STD_GET_STATUS_ZERO: 254 | wStatus = 0; 255 | USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL); 256 | break; 257 | 258 | case STD_GET_STATUS_INTERFACE: 259 | wStatus = 0; 260 | USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL); 261 | break; 262 | 263 | case STD_GET_STATUS_ENDPOINT: 264 | wStatus = 0; 265 | dir = wIndex & 80; 266 | wIndex &= 0x0F; 267 | if (wIndex <= 3) 268 | { 269 | if (dir) 270 | { 271 | //wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1) ? 1 : 0; 272 | wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<1)) ? 1 : 0; 273 | } 274 | else 275 | { 276 | //wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0) ? 1 : 0; 277 | wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<0)) ? 1 : 0; 278 | } 279 | /* Return current status of endpoint */ 280 | USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL); 281 | } 282 | else 283 | { 284 | /* Stall the request */ 285 | USB_SendStall(pUsb, true); 286 | } 287 | break; 288 | 289 | case STD_SET_FEATURE_ZERO: 290 | /* Stall the request */ 291 | USB_SendStall(pUsb, true); 292 | break; 293 | 294 | case STD_SET_FEATURE_INTERFACE: 295 | /* Send ZLP */ 296 | USB_SendZlp(pUsb); 297 | break; 298 | 299 | case STD_SET_FEATURE_ENDPOINT: 300 | dir = wIndex & 0x80; 301 | wIndex &= 0x0F; 302 | if ((wValue == 0) && wIndex && (wIndex <= 3)) 303 | { 304 | /* Set STALL request for the endpoint */ 305 | if (dir) 306 | { 307 | //pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; 308 | pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.bit.STALLRQ = (1<<1); 309 | } 310 | else 311 | { 312 | //pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; 313 | pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.bit.STALLRQ = (1<<0); 314 | } 315 | 316 | /* Send ZLP */ 317 | USB_SendZlp(pUsb); 318 | } 319 | else 320 | { 321 | /* Stall the request */ 322 | USB_SendStall(pUsb, true); 323 | } 324 | break; 325 | 326 | case STD_SET_INTERFACE: 327 | case STD_CLEAR_FEATURE_ZERO: 328 | /* Stall the request */ 329 | USB_SendStall(pUsb, true); 330 | break; 331 | 332 | case STD_CLEAR_FEATURE_INTERFACE: 333 | /* Send ZLP */ 334 | USB_SendZlp(pUsb); 335 | break; 336 | 337 | case STD_CLEAR_FEATURE_ENDPOINT: 338 | dir = wIndex & 0x80; 339 | wIndex &= 0x0F; 340 | 341 | if ((wValue == 0) && wIndex && (wIndex <= 3)) 342 | { 343 | if (dir) 344 | { 345 | if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<1)) 346 | { 347 | // Remove stall request 348 | //pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1; 349 | pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.bit.STALLRQ = (1<<1); 350 | if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL & (1<<1)) 351 | { 352 | pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL = (1<<1); 353 | // The Stall has occurred, then reset data toggle 354 | pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLIN; 355 | } 356 | } 357 | } 358 | else 359 | { 360 | if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<0)) 361 | { 362 | // Remove stall request 363 | //pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0; 364 | pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.bit.STALLRQ = (1<<0); 365 | if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL & (1<<0)) 366 | { 367 | pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL = (1<<0); 368 | // The Stall has occurred, then reset data toggle 369 | pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLOUT; 370 | } 371 | } 372 | } 373 | /* Send ZLP */ 374 | USB_SendZlp(pUsb); 375 | } 376 | else 377 | { 378 | USB_SendStall(pUsb, true); 379 | } 380 | break; 381 | 382 | // handle CDC class requests 383 | case SET_LINE_CODING: 384 | /* Send ZLP */ 385 | USB_SendZlp(pUsb); 386 | break; 387 | 388 | case GET_LINE_CODING: 389 | /* Send current line coding */ 390 | USB_Write(pCdc->pUsb, (char *) &line_coding, SAM_BA_MIN(sizeof(usb_cdc_line_coding_t), wLength), USB_EP_CTRL); 391 | break; 392 | 393 | case SET_CONTROL_LINE_STATE: 394 | /* Store the current connection */ 395 | pCdc->currentConnection = wValue; 396 | /* Send ZLP */ 397 | USB_SendZlp(pUsb); 398 | break; 399 | 400 | default: 401 | /* Stall the request */ 402 | USB_SendStall(pUsb, true); 403 | break; 404 | } 405 | } 406 | 407 | /*---------------------------------------------------------------------------- 408 | * \brief 409 | */ 410 | P_USB_CDC usb_init(void) 411 | { 412 | sam_ba_cdc.pUsb = USB; 413 | 414 | /* Initialize USB */ 415 | USB_Init(); 416 | /* Get the default CDC structure settings */ 417 | USB_Open(&sam_ba_cdc, sam_ba_cdc.pUsb); 418 | 419 | return &sam_ba_cdc; 420 | } 421 | 422 | /*---------------------------------------------------------------------------- 423 | * \brief Send a USB descriptor string. 424 | * 425 | * The input string is plain ASCII but is sent out as UTF-16 with the correct 2-byte prefix. 426 | */ 427 | uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t maxLength) 428 | { 429 | uint8_t string_descriptor[255]; // Max USB-allowed string length 430 | uint16_t* unicode_string=(uint16_t*)(string_descriptor+2); // point on 3 bytes of descriptor 431 | int resulting_length; 432 | 433 | string_descriptor[0] = (strlen(ascii_string)<<1) + 2; 434 | string_descriptor[1] = STD_GET_DESCRIPTOR_STRING; 435 | 436 | for ( resulting_length = 1 ; *ascii_string && (resulting_length>1) ; resulting_length++ ) 437 | { 438 | *unicode_string++ = (uint16_t)(*ascii_string++); 439 | } 440 | 441 | return USB_Write(pUsb, (const char*)string_descriptor, resulting_length<<1, USB_EP_CTRL); 442 | } 443 | -------------------------------------------------------------------------------- /Firmware/Bootloader/sam_ba_usb.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | See the GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef CDC_ENUMERATE_H 21 | #define CDC_ENUMERATE_H 22 | 23 | #include 24 | #include 25 | 26 | #define USB_EP_CTRL (0u) 27 | #define USB_EP_OUT (2u) 28 | #define USB_EP_OUT_SIZE (0x40u) 29 | #define USB_EP_IN (1u) 30 | #define USB_EP_IN_SIZE (0x40u) 31 | #define USB_EP_COMM (3u) 32 | #define MAX_EP (4u) 33 | 34 | /* USB standard request code */ 35 | #define STD_GET_STATUS_ZERO (0x0080u) 36 | #define STD_GET_STATUS_INTERFACE (0x0081u) 37 | #define STD_GET_STATUS_ENDPOINT (0x0082u) 38 | 39 | #define STD_CLEAR_FEATURE_ZERO (0x0100u) 40 | #define STD_CLEAR_FEATURE_INTERFACE (0x0101u) 41 | #define STD_CLEAR_FEATURE_ENDPOINT (0x0102u) 42 | 43 | #define STD_SET_FEATURE_ZERO (0x0300u) 44 | #define STD_SET_FEATURE_INTERFACE (0x0301u) 45 | #define STD_SET_FEATURE_ENDPOINT (0x0302u) 46 | 47 | #define STD_SET_ADDRESS (0x0500u) 48 | #define STD_GET_DESCRIPTOR (0x0680u) 49 | #define STD_SET_DESCRIPTOR (0x0700u) 50 | #define STD_GET_CONFIGURATION (0x0880u) 51 | #define STD_SET_CONFIGURATION (0x0900u) 52 | #define STD_GET_INTERFACE (0x0A81u) 53 | #define STD_SET_INTERFACE (0x0B01u) 54 | #define STD_SYNCH_FRAME (0x0C82u) 55 | 56 | #define STD_GET_DESCRIPTOR_DEVICE (1u) 57 | #define STD_GET_DESCRIPTOR_CONFIGURATION (2u) 58 | #define STD_GET_DESCRIPTOR_STRING (3u) 59 | #define STD_GET_DESCRIPTOR_INTERFACE (4u) 60 | #define STD_GET_DESCRIPTOR_ENDPOINT (5u) 61 | #define STD_GET_DESCRIPTOR_DEVICE_QUALIFIER (6u) 62 | #define STD_GET_DESCRIPTOR_OTHER_SPEED_CONFIGURATION (7u) 63 | #define STD_GET_DESCRIPTOR_INTERFACE_POWER1 (8u) 64 | 65 | #define FEATURE_ENDPOINT_HALT (0u) 66 | #define FEATURE_DEVICE_REMOTE_WAKEUP (1u) 67 | #define FEATURE_TEST_MODE (2u) 68 | 69 | #define STRING_INDEX_LANGUAGES (0x00u) 70 | #define STRING_INDEX_MANUFACTURER (0x01u) 71 | #define STRING_INDEX_PRODUCT (0x02u) 72 | 73 | #define SAM_BA_MIN(a, b) (((a) < (b)) ? (a) : (b)) 74 | 75 | 76 | typedef struct _USB_CDC 77 | { 78 | // Private members 79 | Usb *pUsb; 80 | uint8_t currentConfiguration; 81 | uint8_t currentConnection; 82 | // Public Methods: 83 | uint8_t (*IsConfigured)(struct _USB_CDC *pCdc); 84 | // uint32_t (*Write) (Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num); 85 | // uint32_t (*Read) (Usb *pUsb, char *pData, uint32_t length); 86 | } USB_CDC, *P_USB_CDC; 87 | 88 | /** 89 | * \brief Initializes the USB module 90 | * 91 | * \return Pointer to the USB CDC structure 92 | */ 93 | P_USB_CDC usb_init(void); 94 | 95 | void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc); 96 | 97 | uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t maxLength); 98 | 99 | extern USB_CDC sam_ba_cdc; 100 | 101 | 102 | 103 | #endif // CDC_ENUMERATE_H 104 | -------------------------------------------------------------------------------- /Firmware/_9DoF_Razor_M0_Firmware/config.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////// 2 | // Default Logging Parameters // 3 | //////////////////////////////// 4 | #define ENABLE_TIME_LOG true 5 | #define ENABLE_CALCULATED_LOG true 6 | #define ENABLE_ACCEL_LOG true 7 | #define ENABLE_GYRO_LOG true 8 | #define ENABLE_MAG_LOG true 9 | #define ENABLE_QUAT_LOG false 10 | #define ENABLE_EULER_LOG false 11 | #define ENABLE_HEADING_LOG false 12 | 13 | //////////////////////////////////////// 14 | // Enable Non-Volatile Memory Storage // 15 | //////////////////////////////////////// 16 | // If defined, FlashStorage library must be installed 17 | #define ENABLE_NVRAM_STORAGE 18 | 19 | //////////////////////// 20 | // Serial Port Config // 21 | //////////////////////// 22 | #define ENABLE_UART_LOGGING true 23 | // Select the Serial port to log to. Either SERIAL_PORT_USBVIRTUAL 24 | // or LOG_PORT SERIAL_PORT_HARDWARE (SerialUSB or Serial1) 25 | #define LOG_PORT SERIAL_PORT_USBVIRTUAL 26 | #define SERIAL_BAUD_RATE 115200 // Serial port baud 27 | 28 | //////////////// 29 | // LED Config // 30 | //////////////// 31 | #define HW_LED_PIN 13 // LED attached to pin 13 32 | #define UART_BLINK_RATE 1000 // Blink rate when only UART logging 33 | 34 | ///////////////////////// 35 | // IMU Default Configs // 36 | ///////////////////////// 37 | // Note: Some of these params can be overwritten using serial 38 | // commands. These are just defaults on initial programming 39 | #define DMP_SAMPLE_RATE 100 // Logging/DMP sample rate(4-200 Hz) 40 | #define IMU_COMPASS_SAMPLE_RATE 100 // Compass sample rate (4-100 Hz) 41 | #define IMU_AG_SAMPLE_RATE 100 // Accel/gyro sample rate Must be between 4Hz and 1kHz 42 | #define IMU_GYRO_FSR 2000 // Gyro full-scale range (250, 500, 1000, or 2000) 43 | #define IMU_ACCEL_FSR 2 // Accel full-scale range (2, 4, 8, or 16) 44 | #define IMU_AG_LPF 5 // Accel/Gyro LPF corner frequency (5, 10, 20, 42, 98, or 188 Hz) 45 | #define ENABLE_GYRO_CALIBRATION true 46 | 47 | /////////////////////// 48 | // SD Logging Config // 49 | /////////////////////// 50 | #define ENABLE_SD_LOGGING true // Default SD logging (can be changed via serial menu) 51 | #define LOG_FILE_INDEX_MAX 999 // Max number of "logXXX.txt" files 52 | #define LOG_FILE_PREFIX "log" // Prefix name for log files 53 | #define LOG_FILE_SUFFIX "txt" // Suffix name for log files 54 | #define SD_MAX_FILE_SIZE 5000000 // 5MB max file size, increment to next file before surpassing 55 | #define SD_LOG_WRITE_BUFFER_SIZE 1024 // Experimentally tested to produce 100Hz logs 56 | 57 | ///////////////////// 58 | // Serial Commands // 59 | ///////////////////// 60 | #define PAUSE_LOGGING ' ' // Space - Pause SD/UART logging 61 | #define ENABLE_TIME 't' // Enable/disable time log (milliseconds) 62 | #define ENABLE_ACCEL 'a' // Enable/disable accelerometer log (ax, ay, az) 63 | #define ENABLE_GYRO 'g' // Enable/disable gyroscope log (gx, gy, gz) 64 | #define ENABLE_COMPASS 'm' // Enable/disable magnetometer log (mx, my, mz) 65 | #define ENABLE_CALC 'c' // Enable/disable calculated values 66 | #define ENABLE_QUAT 'q' // Enable/disable quaternion logging (qw, qx, qy, qz) 67 | #define ENABLE_EULER 'e' // Enable/disable estimated euler angles (roll, pitch, yaw) 68 | #define ENABLE_HEADING 'h' // Enable/disable estimated heading logging 69 | #define SET_LOG_RATE 'r' // Adjust logging rate from 1-200 Hz (in 10 Hz increments) 70 | #define SET_ACCEL_FSR 'A' // Set accelerometer FSR (2, 4, 8, 16g) 71 | #define SET_GYRO_FSR 'G' // Set gyroscope FSR (250, 500, 1000, 2000 dps) 72 | #define ENABLE_SD_LOGGING 's' // Enable/disable SD-card logging 73 | 74 | ////////////////////////// 75 | // Hardware Definitions // 76 | ////////////////////////// 77 | // Danger - don't change unless using a different platform 78 | #define MPU9250_INT_PIN 4 79 | #define SD_CHIP_SELECT_PIN 38 80 | #define MPU9250_INT_ACTIVE LOW 81 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/9DOF_Razor_IMU/51dbea98591c547e73c2511f2339e35e4bd7ad48/LICENSE.md -------------------------------------------------------------------------------- /Libraries/Arduino/LICENSE.md: -------------------------------------------------------------------------------- 1 | SparkFun License Information 2 | ============================ 3 | 4 | **SparkFun code, firmware, and software is released under the [MIT License](http://opensource.org/licenses/MIT).** 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2016 SparkFun Electronics, Inc. 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | 29 | -------------------------------------------------------------------------------- /Libraries/Arduino/README.md: -------------------------------------------------------------------------------- 1 | SparkFun MPU-9250 Digital Motion Processor (DMP) Arduino Library 2 | ======================================== 3 | 4 | [![SparkFun MPU-9250](https://cdn.sparkfun.com//assets/parts/1/1/3/0/6/13762-00a.jpg)](https://www.sparkfun.com/products/13762) 5 | 6 | [*SparkFun MPU-9250 (SEN-13762)*](https://www.sparkfun.com/products/13762) 7 | 8 | Advanced Arduino library for the Invensense MPU-9250 inertial measurement unit (IMU), which enables the sensor's digital motion processing (DMP) features. Along with configuring and reading from the accelerometer, gyroscope, and magnetometer, this library also supports the chip's DMP features like: 9 | 10 | * Quaternion calculation 11 | * Pedometer 12 | * Gyroscope calibration 13 | * Tap detection 14 | * Orientation dtection 15 | 16 | For help getting started with this library, refer to the [Using the MPU-9250 DMP Arduino Library](https://learn.sparkfun.com/tutorials/9dof-razor-imu-m0-hookup-guide#using-the-mpu-9250-dmp-arduino-library) section of the 9DoF Razor IMU M0 Hookup Guide. 17 | 18 | **Note**: This library currently only supports and is tested on **SAMD processors**. It's a major part of the [SparkFun 9DoF Razor IMU M0](https://www.sparkfun.com/products/14001) firmware. 19 | 20 | Repository Contents 21 | ------------------- 22 | 23 | * **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE. 24 | * **/src** - Source files for the library (.cpp, .h). 25 | * **/src/util** - Source and headers for the MPU-9250 driver and dmp configuration. These are available and adapted from [Invensene's downloads page](https://www.invensense.com/developers/software-downloads/#sla_content_45). 26 | * **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE. 27 | * **library.properties** - General library properties for the Arduino package manager. 28 | 29 | Documentation 30 | -------------- 31 | 32 | * **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library. 33 | * **[SparkFun 9DoF Razor IMU M0 Repository](https://github.com/sparkfun/9DOF_Razor_IMU)** - Main repositor (including hardware files) for the MPU-9250-based SparkFun 9DoF Razor IMU M0 34 | * **[MPU-9250 Breakout Repository](https://github.com/sparkfun/MPU-9250_Breakout)** - Main repository (including hardware files) for the MPU-9250 Breakout. 35 | * **[Hookup Guide](https://learn.sparkfun.com/tutorials/9dof-razor-imu-m0-hookup-guide)** - Basic hookup guide for the SparkFun 9DoF Razor IMU M0, including a [section on using this library](https://learn.sparkfun.com/tutorials/9dof-razor-imu-m0-hookup-guide#using-the-mpu-9250-dmp-arduino-library). 36 | 37 | Products that use this Library 38 | --------------------------------- 39 | 40 | * [SparkFun 9DoF Razor IMU M0 (SEN-14001)](https://www.sparkfun.com/products/14001)- An MPU-9250 development board, which includes an Arduino-compatible SAMD21 processor, LiPo battery charger, and USB interface. 41 | * [SparkFun MPU-9250 Breakout (SEN-13762)](https://www.sparkfun.com/products/13762)- Easily adaptible breakout board for the MPU-9250. 42 | 43 | Version History 44 | --------------- 45 | 46 | 47 | License Information 48 | ------------------- 49 | 50 | This product is _**open source**_! 51 | 52 | Please review the LICENSE.md file for license information. 53 | 54 | If you have any questions or concerns on licensing, please contact techsupport@sparkfun.com. 55 | 56 | Distributed as-is; no warranty is given. 57 | 58 | - Your friends at SparkFun. 59 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/MPU9250_Basic/MPU9250_Basic.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | MPU9250_Basic 3 | Basic example sketch for MPU-9250 DMP Arduino Library 4 | Jim Lindblom @ SparkFun Electronics 5 | original creation date: November 23, 2016 6 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 7 | 8 | This example sketch demonstrates how to initialize the 9 | MPU-9250, and stream its sensor outputs to a serial monitor. 10 | 11 | Development environment specifics: 12 | Arduino IDE 1.6.12 13 | SparkFun 9DoF Razor IMU M0 14 | 15 | Supported Platforms: 16 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 17 | *************************************************************/ 18 | #include 19 | 20 | #define SerialPort SerialUSB 21 | 22 | MPU9250_DMP imu; 23 | 24 | void setup() 25 | { 26 | SerialPort.begin(115200); 27 | 28 | // Call imu.begin() to verify communication with and 29 | // initialize the MPU-9250 to it's default values. 30 | // Most functions return an error code - INV_SUCCESS (0) 31 | // indicates the IMU was present and successfully set up 32 | if (imu.begin() != INV_SUCCESS) 33 | { 34 | while (1) 35 | { 36 | SerialPort.println("Unable to communicate with MPU-9250"); 37 | SerialPort.println("Check connections, and try again."); 38 | SerialPort.println(); 39 | delay(5000); 40 | } 41 | } 42 | 43 | // Use setSensors to turn on or off MPU-9250 sensors. 44 | // Any of the following defines can be combined: 45 | // INV_XYZ_GYRO, INV_XYZ_ACCEL, INV_XYZ_COMPASS, 46 | // INV_X_GYRO, INV_Y_GYRO, or INV_Z_GYRO 47 | // Enable all sensors: 48 | imu.setSensors(INV_XYZ_GYRO | INV_XYZ_ACCEL | INV_XYZ_COMPASS); 49 | 50 | // Use setGyroFSR() and setAccelFSR() to configure the 51 | // gyroscope and accelerometer full scale ranges. 52 | // Gyro options are +/- 250, 500, 1000, or 2000 dps 53 | imu.setGyroFSR(2000); // Set gyro to 2000 dps 54 | // Accel options are +/- 2, 4, 8, or 16 g 55 | imu.setAccelFSR(2); // Set accel to +/-2g 56 | // Note: the MPU-9250's magnetometer FSR is set at 57 | // +/- 4912 uT (micro-tesla's) 58 | 59 | // setLPF() can be used to set the digital low-pass filter 60 | // of the accelerometer and gyroscope. 61 | // Can be any of the following: 188, 98, 42, 20, 10, 5 62 | // (values are in Hz). 63 | imu.setLPF(5); // Set LPF corner frequency to 5Hz 64 | 65 | // The sample rate of the accel/gyro can be set using 66 | // setSampleRate. Acceptable values range from 4Hz to 1kHz 67 | imu.setSampleRate(10); // Set sample rate to 10Hz 68 | 69 | // Likewise, the compass (magnetometer) sample rate can be 70 | // set using the setCompassSampleRate() function. 71 | // This value can range between: 1-100Hz 72 | imu.setCompassSampleRate(10); // Set mag rate to 10Hz 73 | } 74 | 75 | void loop() 76 | { 77 | // dataReady() checks to see if new accel/gyro data 78 | // is available. It will return a boolean true or false 79 | // (New magnetometer data cannot be checked, as the library 80 | // runs that sensor in single-conversion mode.) 81 | if ( imu.dataReady() ) 82 | { 83 | // Call update() to update the imu objects sensor data. 84 | // You can specify which sensors to update by combining 85 | // UPDATE_ACCEL, UPDATE_GYRO, UPDATE_COMPASS, and/or 86 | // UPDATE_TEMPERATURE. 87 | // (The update function defaults to accel, gyro, compass, 88 | // so you don't have to specify these values.) 89 | imu.update(UPDATE_ACCEL | UPDATE_GYRO | UPDATE_COMPASS); 90 | printIMUData(); 91 | } 92 | } 93 | 94 | void printIMUData(void) 95 | { 96 | // After calling update() the ax, ay, az, gx, gy, gz, mx, 97 | // my, mz, time, and/or temerature class variables are all 98 | // updated. Access them by placing the object. in front: 99 | 100 | // Use the calcAccel, calcGyro, and calcMag functions to 101 | // convert the raw sensor readings (signed 16-bit values) 102 | // to their respective units. 103 | float accelX = imu.calcAccel(imu.ax); 104 | float accelY = imu.calcAccel(imu.ay); 105 | float accelZ = imu.calcAccel(imu.az); 106 | float gyroX = imu.calcGyro(imu.gx); 107 | float gyroY = imu.calcGyro(imu.gy); 108 | float gyroZ = imu.calcGyro(imu.gz); 109 | float magX = imu.calcMag(imu.mx); 110 | float magY = imu.calcMag(imu.my); 111 | float magZ = imu.calcMag(imu.mz); 112 | 113 | SerialPort.println("Accel: " + String(accelX) + ", " + 114 | String(accelY) + ", " + String(accelZ) + " g"); 115 | SerialPort.println("Gyro: " + String(gyroX) + ", " + 116 | String(gyroY) + ", " + String(gyroZ) + " dps"); 117 | SerialPort.println("Mag: " + String(magX) + ", " + 118 | String(magY) + ", " + String(magZ) + " uT"); 119 | SerialPort.println("Time: " + String(imu.time) + " ms"); 120 | SerialPort.println(); 121 | } 122 | 123 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/MPU9250_Basic_Interrupt/MPU9250_Basic_Interrupt.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | MPU9250_Basic_Interrupt 3 | Basic interrupt sketch for MPU-9250 DMP Arduino Library 4 | Jim Lindblom @ SparkFun Electronics 5 | original creation date: November 23, 2016 6 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 7 | 8 | This example sketch demonstrates how to initialize the 9 | MPU-9250, and stream its sensor outputs to a serial monitor. 10 | It uses the MPU-9250's interrupt output to indicate when 11 | new data is ready. 12 | 13 | Development environment specifics: 14 | Arduino IDE 1.6.12 15 | SparkFun 9DoF Razor IMU M0 (interrupt on pin 4) 16 | 17 | Supported Platforms: 18 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 19 | *************************************************************/ 20 | #include 21 | 22 | #define SerialPort SerialUSB 23 | #define INTERRUPT_PIN 4 24 | 25 | MPU9250_DMP imu; 26 | 27 | void setup() 28 | { 29 | pinMode(INTERRUPT_PIN, INPUT_PULLUP); 30 | SerialPort.begin(115200); 31 | 32 | if (imu.begin() != INV_SUCCESS) 33 | { 34 | while (1) 35 | { 36 | SerialPort.println("Unable to communicate with MPU-9250"); 37 | SerialPort.println("Check connections, and try again."); 38 | SerialPort.println(); 39 | delay(5000); 40 | } 41 | } 42 | 43 | // Enable all sensors, and set sample rates to 4Hz. 44 | // (Slow so we can see the interrupt work.) 45 | imu.setSensors(INV_XYZ_GYRO | INV_XYZ_ACCEL | INV_XYZ_COMPASS); 46 | imu.setSampleRate(4); // Set accel/gyro sample rate to 4Hz 47 | imu.setCompassSampleRate(4); // Set mag rate to 4Hz 48 | 49 | // Use enableInterrupt() to configure the MPU-9250's 50 | // interrupt output as a "data ready" indicator. 51 | imu.enableInterrupt(); 52 | 53 | // The interrupt level can either be active-high or low. 54 | // Configure as active-low, since we'll be using the pin's 55 | // internal pull-up resistor. 56 | // Options are INT_ACTIVE_LOW or INT_ACTIVE_HIGH 57 | imu.setIntLevel(INT_ACTIVE_LOW); 58 | 59 | // The interrupt can be set to latch until data has 60 | // been read, or to work as a 50us pulse. 61 | // Use latching method -- we'll read from the sensor 62 | // as soon as we see the pin go LOW. 63 | // Options are INT_LATCHED or INT_50US_PULSE 64 | imu.setIntLatched(INT_LATCHED); 65 | } 66 | 67 | void loop() 68 | { 69 | // The interrupt pin is pulled up using an internal pullup 70 | // resistor, and the MPU-9250 is configured to trigger 71 | // the input LOW. 72 | if ( digitalRead(INTERRUPT_PIN) == LOW ) 73 | { 74 | // Call update() to update the imu objects sensor data. 75 | imu.update(UPDATE_ACCEL | UPDATE_GYRO | UPDATE_COMPASS); 76 | printIMUData(); 77 | } 78 | } 79 | 80 | void printIMUData(void) 81 | { 82 | // After calling update() the ax, ay, az, gx, gy, gz, mx, 83 | // my, mz, time, and/or temerature class variables are all 84 | // updated. Access them by placing the object. in front: 85 | 86 | // Use the calcAccel, calcGyro, and calcMag functions to 87 | // convert the raw sensor readings (signed 16-bit values) 88 | // to their respective units. 89 | float accelX = imu.calcAccel(imu.ax); 90 | float accelY = imu.calcAccel(imu.ay); 91 | float accelZ = imu.calcAccel(imu.az); 92 | float gyroX = imu.calcGyro(imu.gx); 93 | float gyroY = imu.calcGyro(imu.gy); 94 | float gyroZ = imu.calcGyro(imu.gz); 95 | float magX = imu.calcMag(imu.mx); 96 | float magY = imu.calcMag(imu.my); 97 | float magZ = imu.calcMag(imu.mz); 98 | 99 | SerialPort.println("Accel: " + String(accelX) + ", " + 100 | String(accelY) + ", " + String(accelZ) + " g"); 101 | SerialPort.println("Gyro: " + String(gyroX) + ", " + 102 | String(gyroY) + ", " + String(gyroZ) + " dps"); 103 | SerialPort.println("Mag: " + String(magX) + ", " + 104 | String(magY) + ", " + String(magZ) + " uT"); 105 | SerialPort.println("Time: " + String(imu.time) + " ms"); 106 | SerialPort.println(); 107 | } 108 | 109 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/MPU9250_DMP_Gyro_Cal/MPU9250_DMP_Gyro_Cal.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | MPU9250_DMP_Gyro_Cal 3 | Gyro calibration example for MPU-9250 DMP Arduino Library 4 | Jim Lindblom @ SparkFun Electronics 5 | original creation date: November 23, 2016 6 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 7 | 8 | This example sketch demonstrates how to use the MPU-9250's 9 | digital motion processor (DMP) to calibrate the gyroscope. 10 | After eight seconds of no motion, the DMP will compute 11 | gyro biases and subtract them. 12 | 13 | Development environment specifics: 14 | Arduino IDE 1.6.12 15 | SparkFun 9DoF Razor IMU M0 16 | 17 | Supported Platforms: 18 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 19 | *************************************************************/ 20 | #include 21 | 22 | #define SerialPort SerialUSB 23 | 24 | MPU9250_DMP imu; 25 | 26 | void setup() 27 | { 28 | SerialPort.begin(115200); 29 | 30 | // Call imu.begin() to verify communication and initialize 31 | if (imu.begin() != INV_SUCCESS) 32 | { 33 | while (1) 34 | { 35 | SerialPort.println("Unable to communicate with MPU-9250"); 36 | SerialPort.println("Check connections, and try again."); 37 | SerialPort.println(); 38 | delay(5000); 39 | } 40 | } 41 | 42 | imu.setSensors(INV_XYZ_GYRO); // Enable gyroscope only 43 | imu.setGyroFSR(2000); // Set gyro to 2000 dps 44 | 45 | imu.dmpBegin(DMP_FEATURE_GYRO_CAL | // Enable gyro cal 46 | DMP_FEATURE_SEND_CAL_GYRO,// Send cal'd gyro values 47 | 10); // Set DMP rate to 10 Hz 48 | } 49 | 50 | void loop() 51 | { 52 | // Check for new data in the FIFO 53 | if ( imu.fifoAvailable() ) 54 | { 55 | // Use dmpUpdateFifo to update the ax, gx, mx, etc. values 56 | if ( imu.dmpUpdateFifo() == INV_SUCCESS) 57 | { 58 | printIMUData(); 59 | } 60 | } 61 | } 62 | 63 | void printIMUData(void) 64 | { 65 | // After calling dmpUpdateFifo() the ax, gx, mx, etc. values 66 | // are all updated. 67 | float gyroX = imu.calcGyro(imu.gx); 68 | float gyroY = imu.calcGyro(imu.gy); 69 | float gyroZ = imu.calcGyro(imu.gz); 70 | 71 | SerialPort.println("Gyro: " + String(gyroX) + ", " + 72 | String(gyroY) + ", " + String(gyroZ) + " dps"); 73 | SerialPort.println("Time: " + String(imu.time) + " ms"); 74 | SerialPort.println(); 75 | } 76 | 77 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/MPU9250_DMP_Orientation/MPU9250_DMP_Orientation.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | MPU9250_DMP_Orientation 3 | Orientation example for MPU-9250 DMP Arduino Library 4 | Jim Lindblom @ SparkFun Electronics 5 | original creation date: November 23, 2016 6 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 7 | 8 | Uses the MPU-9250's digital motion processing engine to 9 | determine orientation of the board. 10 | 11 | Development environment specifics: 12 | Arduino IDE 1.6.12 13 | SparkFun 9DoF Razor IMU M0 14 | 15 | Supported Platforms: 16 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 17 | *************************************************************/ 18 | #include 19 | 20 | #define SerialPort SerialUSB 21 | 22 | MPU9250_DMP imu; 23 | 24 | unsigned long stepCount = 0; 25 | unsigned long stepTime = 0; 26 | unsigned long lastStepCount = 0; 27 | 28 | const signed char orientationMatrix[9] = { 29 | 1, 0, 0, 30 | 0, 1, 0, 31 | 0, 0, 1 32 | }; 33 | unsigned char lastOrient = 0; 34 | 35 | void setup() 36 | { 37 | SerialPort.begin(115200); 38 | 39 | // Call imu.begin() to verify communication and initialize 40 | if (imu.begin() != INV_SUCCESS) 41 | { 42 | while (1) 43 | { 44 | SerialPort.println("Unable to communicate with MPU-9250"); 45 | SerialPort.println("Check connections, and try again."); 46 | SerialPort.println(); 47 | delay(5000); 48 | } 49 | } 50 | 51 | imu.dmpBegin(DMP_FEATURE_ANDROID_ORIENT); 52 | imu.dmpSetOrientation(orientationMatrix); 53 | } 54 | 55 | void loop() 56 | { 57 | if ( imu.fifoAvailable() ) 58 | { 59 | imu.dmpUpdateFifo(); 60 | unsigned char orient = imu.dmpGetOrientation(); 61 | if (orient != lastOrient) 62 | { 63 | switch (orient) 64 | { 65 | case ORIENT_PORTRAIT: 66 | SerialPort.println("Portrait"); 67 | break; 68 | case ORIENT_LANDSCAPE: 69 | SerialPort.println("Landscape"); 70 | break; 71 | case ORIENT_REVERSE_PORTRAIT: 72 | SerialPort.println("Portrait (Reverse)"); 73 | break; 74 | case ORIENT_REVERSE_LANDSCAPE: 75 | SerialPort.println("Landscape (Reverse)"); 76 | break; 77 | } 78 | lastOrient = orient; 79 | } 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/MPU9250_DMP_Pedometer/MPU9250_DMP_Pedometer.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | MPU9250_DMP_Pedometer 3 | Pedometer example for MPU-9250 DMP Arduino Library 4 | Jim Lindblom @ SparkFun Electronics 5 | original creation date: November 23, 2016 6 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 7 | 8 | The MPU-9250's digital motion processor (DMP) can estimate 9 | steps taken -- effecting a pedometer. 10 | 11 | After uploading the code, try shaking the 9DoF up and 12 | down at a "stepping speed." 13 | 14 | Development environment specifics: 15 | Arduino IDE 1.6.12 16 | SparkFun 9DoF Razor IMU M0 17 | 18 | Supported Platforms: 19 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 20 | *************************************************************/ 21 | #include 22 | 23 | #define SerialPort SerialUSB 24 | 25 | MPU9250_DMP imu; 26 | 27 | unsigned long stepCount = 0; 28 | unsigned long stepTime = 0; 29 | unsigned long lastStepCount = 0; 30 | 31 | void setup() 32 | { 33 | SerialPort.begin(115200); 34 | 35 | // Call imu.begin() to verify communication and initialize 36 | if (imu.begin() != INV_SUCCESS) 37 | { 38 | while (1) 39 | { 40 | SerialPort.println("Unable to communicate with MPU-9250"); 41 | SerialPort.println("Check connections, and try again."); 42 | SerialPort.println(); 43 | delay(5000); 44 | } 45 | } 46 | 47 | imu.dmpBegin(DMP_FEATURE_PEDOMETER); 48 | imu.dmpSetPedometerSteps(stepCount); 49 | imu.dmpSetPedometerTime(stepTime); 50 | } 51 | 52 | void loop() 53 | { 54 | stepCount = imu.dmpGetPedometerSteps(); 55 | stepTime = imu.dmpGetPedometerTime(); 56 | 57 | if (stepCount != lastStepCount) 58 | { 59 | lastStepCount = stepCount; 60 | SerialPort.print("Walked " + String(stepCount) + 61 | " steps"); 62 | SerialPort.println(" (" + 63 | String((float)stepTime / 1000.0) + " s)"); 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/MPU9250_DMP_Quaternion/MPU9250_DMP_Quaternion.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | MPU9250_DMP_Quaternion 3 | Quaternion example for MPU-9250 DMP Arduino Library 4 | Jim Lindblom @ SparkFun Electronics 5 | original creation date: November 23, 2016 6 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 7 | 8 | The MPU-9250's digital motion processor (DMP) can calculate 9 | four unit quaternions, which can be used to represent the 10 | rotation of an object. 11 | 12 | This exmaple demonstrates how to configure the DMP to 13 | calculate quaternions, and prints them out to the serial 14 | monitor. It also calculates pitch, roll, and yaw from those 15 | values. 16 | 17 | Development environment specifics: 18 | Arduino IDE 1.6.12 19 | SparkFun 9DoF Razor IMU M0 20 | 21 | Supported Platforms: 22 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 23 | *************************************************************/ 24 | #include 25 | 26 | #define SerialPort SerialUSB 27 | 28 | MPU9250_DMP imu; 29 | 30 | void setup() 31 | { 32 | SerialPort.begin(115200); 33 | 34 | // Call imu.begin() to verify communication and initialize 35 | if (imu.begin() != INV_SUCCESS) 36 | { 37 | while (1) 38 | { 39 | SerialPort.println("Unable to communicate with MPU-9250"); 40 | SerialPort.println("Check connections, and try again."); 41 | SerialPort.println(); 42 | delay(5000); 43 | } 44 | } 45 | 46 | imu.dmpBegin(DMP_FEATURE_6X_LP_QUAT | // Enable 6-axis quat 47 | DMP_FEATURE_GYRO_CAL, // Use gyro calibration 48 | 10); // Set DMP FIFO rate to 10 Hz 49 | // DMP_FEATURE_LP_QUAT can also be used. It uses the 50 | // accelerometer in low-power mode to estimate quat's. 51 | // DMP_FEATURE_LP_QUAT and 6X_LP_QUAT are mutually exclusive 52 | } 53 | 54 | void loop() 55 | { 56 | // Check for new data in the FIFO 57 | if ( imu.fifoAvailable() ) 58 | { 59 | // Use dmpUpdateFifo to update the ax, gx, mx, etc. values 60 | if ( imu.dmpUpdateFifo() == INV_SUCCESS) 61 | { 62 | // computeEulerAngles can be used -- after updating the 63 | // quaternion values -- to estimate roll, pitch, and yaw 64 | imu.computeEulerAngles(); 65 | printIMUData(); 66 | } 67 | } 68 | } 69 | 70 | void printIMUData(void) 71 | { 72 | // After calling dmpUpdateFifo() the ax, gx, mx, etc. values 73 | // are all updated. 74 | // Quaternion values are, by default, stored in Q30 long 75 | // format. calcQuat turns them into a float between -1 and 1 76 | float q0 = imu.calcQuat(imu.qw); 77 | float q1 = imu.calcQuat(imu.qx); 78 | float q2 = imu.calcQuat(imu.qy); 79 | float q3 = imu.calcQuat(imu.qz); 80 | 81 | SerialPort.println("Q: " + String(q0, 4) + ", " + 82 | String(q1, 4) + ", " + String(q2, 4) + 83 | ", " + String(q3, 4)); 84 | SerialPort.println("R/P/Y: " + String(imu.roll) + ", " 85 | + String(imu.pitch) + ", " + String(imu.yaw)); 86 | SerialPort.println("Time: " + String(imu.time) + " ms"); 87 | SerialPort.println(); 88 | } 89 | 90 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/MPU9250_DMP_Tap/MPU9250_DMP_Tap.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | MPU9250_DMP_Tap 3 | Tap-detection example for MPU-9250 DMP Arduino Library 4 | Jim Lindblom @ SparkFun Electronics 5 | original creation date: November 23, 2016 6 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 7 | 8 | The MPU-9250's digital motion processor (DMP) can monitor for 9 | single or double tap events on any of the three accelerometer 10 | axes. 11 | 12 | This example turns tap-detection on in the z-axis. Try to 13 | tap it to the max count of 8! 14 | 15 | Development environment specifics: 16 | Arduino IDE 1.6.12 17 | SparkFun 9DoF Razor IMU M0 18 | 19 | Supported Platforms: 20 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 21 | *************************************************************/ 22 | #include 23 | 24 | #define SerialPort SerialUSB 25 | 26 | MPU9250_DMP imu; 27 | 28 | void setup() 29 | { 30 | SerialPort.begin(115200); 31 | 32 | // Call imu.begin() to verify communication and initialize 33 | if (imu.begin() != INV_SUCCESS) 34 | { 35 | while (1) 36 | { 37 | SerialPort.println("Unable to communicate with MPU-9250"); 38 | SerialPort.println("Check connections, and try again."); 39 | SerialPort.println(); 40 | delay(5000); 41 | } 42 | } 43 | 44 | // Enable tap detection in the DMP. Set FIFO sample rate to 10Hz. 45 | imu.dmpBegin(DMP_FEATURE_TAP, 10); 46 | // dmpSetTap parameters, in order, are: 47 | // x threshold: 1-1600 (0 to disable) 48 | // y threshold: 1-1600 (0 to disable) 49 | // z threshold: 1-1600 (0 to disable) 50 | // (Threshold units are mg/ms) 51 | // taps: Minimum number of taps needed for interrupt (1-4) 52 | // tap time: milliseconds between valid taps 53 | // tap time multi: max milliseconds between multi-taps 54 | unsigned short xThresh = 0; // Disable x-axis tap 55 | unsigned short yThresh = 0; // Disable y-axis tap 56 | unsigned short zThresh = 100; // Set z-axis tap thresh to 100 mg/ms 57 | unsigned char taps = 1; // Set minimum taps to 1 58 | unsigned short tapTime = 100; // Set tap time to 100ms 59 | unsigned short tapMulti = 1000;// Set multi-tap time to 1s 60 | imu.dmpSetTap(xThresh, yThresh, zThresh, taps, tapTime, tapMulti); 61 | } 62 | 63 | void loop() 64 | { 65 | // Check for new data in the FIFO 66 | if ( imu.fifoAvailable() ) 67 | { 68 | // DMP FIFO must be updated in order to update tap data 69 | imu.dmpUpdateFifo(); 70 | // Check for new tap data by polling tapAvailable 71 | if ( imu.tapAvailable() ) 72 | { 73 | // If a new tap happened, get the direction and count 74 | // by reading getTapDir and getTapCount 75 | unsigned char tapDir = imu.getTapDir(); 76 | unsigned char tapCnt = imu.getTapCount(); 77 | switch (tapDir) 78 | { 79 | case TAP_X_UP: 80 | SerialPort.print("Tap X+ "); 81 | break; 82 | case TAP_X_DOWN: 83 | SerialPort.print("Tap X- "); 84 | break; 85 | case TAP_Y_UP: 86 | SerialPort.print("Tap Y+ "); 87 | break; 88 | case TAP_Y_DOWN: 89 | SerialPort.print("Tap Y- "); 90 | break; 91 | case TAP_Z_UP: 92 | SerialPort.print("Tap Z+ "); 93 | break; 94 | case TAP_Z_DOWN: 95 | SerialPort.print("Tap Z- "); 96 | break; 97 | } 98 | SerialPort.println(tapCnt); 99 | } 100 | } 101 | } 102 | 103 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/MPU9250_FIFO_Basic/MPU9250_FIFO_Basic.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | MPU9250_FIFO_Basic 3 | Basic example sketch for MPU-9250 DMP Arduino Library 4 | Jim Lindblom @ SparkFun Electronics 5 | original creation date: November 23, 2016 6 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 7 | 8 | This example sketch demonstrates how to use the MPU-9250's 9 | 512 byte first-in, first-out (FIFO) buffer. The FIFO can be 10 | set to store either accelerometer and/or gyroscope (not the 11 | magnetometer, though :( ). 12 | 13 | Development environment specifics: 14 | Arduino IDE 1.6.12 15 | SparkFun 9DoF Razor IMU M0 16 | 17 | Supported Platforms: 18 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 19 | *************************************************************/ 20 | #include 21 | 22 | #define SerialPort SerialUSB 23 | 24 | MPU9250_DMP imu; 25 | 26 | void setup() 27 | { 28 | SerialPort.begin(115200); 29 | 30 | // Call imu.begin() to verify communication with and 31 | // initialize the MPU-9250 to it's default values. 32 | // Most functions return an error code - INV_SUCCESS (0) 33 | // indicates the IMU was present and successfully set up 34 | if (imu.begin() != INV_SUCCESS) 35 | { 36 | while (1) 37 | { 38 | SerialPort.println("Unable to communicate with MPU-9250"); 39 | SerialPort.println("Check connections, and try again."); 40 | SerialPort.println(); 41 | delay(5000); 42 | } 43 | } 44 | 45 | // The sample rate of the accel/gyro can be set using 46 | // setSampleRate. Acceptable values range from 4Hz to 1kHz 47 | imu.setSampleRate(100); // Set sample rate to 100Hz 48 | 49 | // Use configureFifo to set which sensors should be stored 50 | // in the buffer. 51 | // Parameter to this function can be: INV_XYZ_GYRO, 52 | // INV_XYZ_ACCEL, INV_X_GYRO, INV_Y_GYRO, or INV_Z_GYRO 53 | imu.configureFifo(INV_XYZ_GYRO |INV_XYZ_ACCEL); 54 | } 55 | 56 | void loop() 57 | { 58 | // fifoAvailable returns the number of bytes in the FIFO 59 | // The FIFO is 512 bytes max. We'll read when it reaches 60 | // half of that. 61 | if ( imu.fifoAvailable() >= 256) 62 | { 63 | // Then read while there is data in the FIFO 64 | while ( imu.fifoAvailable() > 0) 65 | { 66 | // Call updateFifo to update ax, ay, az, gx, gy, and/or gz 67 | if ( imu.updateFifo() == INV_SUCCESS) 68 | { 69 | printIMUData(); 70 | } 71 | } 72 | } 73 | } 74 | 75 | void printIMUData(void) 76 | { 77 | // After calling update() the ax, ay, az, gx, gy, gz, mx, 78 | // my, mz, time, and/or temerature class variables are all 79 | // updated. Access them by placing the object. in front: 80 | 81 | // Use the calcAccel, calcGyro, and calcMag functions to 82 | // convert the raw sensor readings (signed 16-bit values) 83 | // to their respective units. 84 | float accelX = imu.calcAccel(imu.ax); 85 | float accelY = imu.calcAccel(imu.ay); 86 | float accelZ = imu.calcAccel(imu.az); 87 | float gyroX = imu.calcGyro(imu.gx); 88 | float gyroY = imu.calcGyro(imu.gy); 89 | float gyroZ = imu.calcGyro(imu.gz); 90 | 91 | SerialPort.println("Accel: " + String(accelX) + ", " + 92 | String(accelY) + ", " + String(accelZ) + " g"); 93 | SerialPort.println("Gyro: " + String(gyroX) + ", " + 94 | String(gyroY) + ", " + String(gyroZ) + " dps"); 95 | SerialPort.println("Time: " + String(imu.time) + " ms"); 96 | SerialPort.println(); 97 | } 98 | -------------------------------------------------------------------------------- /Libraries/Arduino/keywords.txt: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Syntax Coloring Map for SparkFun MPU-9250 Arduino Library # 3 | ################################################################################ 4 | 5 | ################################################################################ 6 | # Datatypes (KEYWORD1) 7 | ################################################################################ 8 | SparkFunMPU9250-DMP KEYWORD1 9 | MPU9250_DMP KEYWORD1 10 | ax KEYWORD1 11 | ay KEYWORD1 12 | az KEYWORD1 13 | gx KEYWORD1 14 | gy KEYWORD1 15 | gz KEYWORD1 16 | mx KEYWORD1 17 | my KEYWORD1 18 | mz KEYWORD1 19 | qw KEYWORD1 20 | qx KEYWORD1 21 | qy KEYWORD1 22 | qz KEYWORD1 23 | temperature KEYWORD1 24 | time KEYWORD1 25 | pitch KEYWORD1 26 | roll KEYWORD1 27 | yaw KEYWORD1 28 | heading KEYWORD1 29 | 30 | ################################################################################ 31 | # Methods and Functions (KEYWORD2) 32 | ################################################################################ 33 | begin KEYWORD2 34 | setSensors KEYWORD2 35 | setGyroFSR KEYWORD2 36 | getGyroFSR KEYWORD2 37 | getGyroSens KEYWORD2 38 | setAccelFSR KEYWORD2 39 | getAccelFSR KEYWORD2 40 | getAccelSens KEYWORD2 41 | getMagFSR KEYWORD2 42 | getMagSens KEYWORD2 43 | setLPF KEYWORD2 44 | getLPF KEYWORD2 45 | setSampleRate KEYWORD2 46 | getSampleRate KEYWORD2 47 | setCompassSampleRate KEYWORD2 48 | getCompassSampleRate KEYWORD2 49 | lowPowerAccel KEYWORD2 50 | dataReady KEYWORD2 51 | update KEYWORD2 52 | updateAccel KEYWORD2 53 | updateGyro KEYWORD2 54 | updateCompass KEYWORD2 55 | updateTemperature KEYWORD2 56 | getFifoConfig KEYWORD2 57 | configureFifo KEYWORD2 58 | resetFifo KEYWORD2 59 | fifoAvailable KEYWORD2 60 | updateFifo KEYWORD2 61 | selfTest KEYWORD2 62 | enableInterrupt KEYWORD2 63 | setIntLevel KEYWORD2 64 | setIntLatched KEYWORD2 65 | getIntStatus KEYWORD2 66 | dmpBegin KEYWORD2 67 | dmpLoad KEYWORD2 68 | dmpGetFifoRate KEYWORD2 69 | dmpSetFifoRate KEYWORD2 70 | dmpUpdateFifo KEYWORD2 71 | dmpEnableFeatures KEYWORD2 72 | dmpGetEnabledFeatures KEYWORD2 73 | dmpSetInterruptMode KEYWORD2 74 | dmpSetGyroBias KEYWORD2 75 | dmpSetAccelBias KEYWORD2 76 | dmpSetTap KEYWORD2 77 | tapAvailable KEYWORD2 78 | getTapDir KEYWORD2 79 | getTapCount KEYWORD2 80 | dmpSetOrientation KEYWORD2 81 | dmpGetOrientation KEYWORD2 82 | dmpEnable3Quat KEYWORD2 83 | dmpEnable6Quat KEYWORD2 84 | dmpGetPedometerSteps KEYWORD2 85 | dmpSetPedometerSteps KEYWORD2 86 | dmpGetPedometerTime KEYWORD2 87 | dmpSetPedometerTime KEYWORD2 88 | calcAccel KEYWORD2 89 | calcGyro KEYWORD2 90 | calcMag KEYWORD2 91 | calcQuat KEYWORD2 92 | qToFloat KEYWORD2 93 | computeEulerAngles KEYWORD2 94 | computeCompassHeading KEYWORD2 95 | 96 | ################################################################################ 97 | # Constants (LITERAL1) 98 | ################################################################################ 99 | INV_SUCCESS LITERAL1 100 | INV_XYZ_GYRO LITERAL1 101 | INV_XYZ_ACCEL LITERAL1 102 | INV_XYZ_COMPASS LITERAL1 103 | INV_X_GYRO LITERAL1 104 | INV_Y_GYRO LITERAL1 105 | INV_Z_GYRO LITERAL1 106 | UPDATE_ACCEL LITERAL1 107 | UPDATE_GYRO LITERAL1 108 | UPDATE_COMPASS LITERAL1 109 | UPDATE_TEMP LITERAL1 110 | FIFO_BUFFER_SIZE LITERAL1 111 | INT_ACTIVE_LOW LITERAL1 112 | INT_ACTIVE_HIGH LITERAL1 113 | INT_LATCHED LITERAL1 114 | INT_50US_PULSE LITERAL1 115 | DMP_FEATURE_TAP LITERAL1 116 | DMP_FEATURE_ANDROID_ORIENT LITERAL1 117 | DMP_FEATURE_LP_QUAT LITERAL1 118 | DMP_FEATURE_6X_LP_QUAT LITERAL1 119 | DMP_FEATURE_GYRO_CAL LITERAL1 120 | DMP_FEATURE_SEND_RAW_ACCEL LITERAL1 121 | DMP_FEATURE_SEND_RAW_GYRO LITERAL1 122 | DMP_FEATURE_SEND_CAL_GYRO LITERAL1 123 | DMP_FEATURE_PEDOMETER LITERAL1 124 | ORIENT_PORTRAIT LITERAL1 125 | ORIENT_LANDSCAPE LITERAL1 126 | ORIENT_REVERSE_PORTRAIT LITERAL1 127 | ORIENT_REVERSE_LANDSCAPE LITERAL1 128 | TAP_X_UP LITERAL1 129 | TAP_X_DOWN LITERAL1 130 | TAP_Y_UP LITERAL1 131 | TAP_Y_DOWN LITERAL1 132 | TAP_Z_UP LITERAL1 133 | TAP_Z_DOWN LITERAL1 -------------------------------------------------------------------------------- /Libraries/Arduino/library.properties: -------------------------------------------------------------------------------- 1 | name=SparkFun MPU-9250 Digital Motion Processing (DMP) Arduino Library 2 | version=1.0.0 3 | author=SparkFun Electronics 4 | maintainer=SparkFun Electronics 5 | sentence=Driver for InvenSense's MPU-9250 9-DOF IMU (3-axis gyroscope, 3-axis accelerometer & 3-axis magnetometer) 6 | paragraph=The MPU-9250 is a system-in-package featuring acceleration full-scales of ±2 / ±4 / ±8 / ±16 (g), rotational full-scales of ±250 / ±500 / ±1000 / ±2000 (°/sec) and a magnetic field full scale of ±4800 µT. The MPU-9250 includes an I2C serial bus interface that supports speeds up to 400 kHz. 7 | category=Sensors 8 | url=https://github.com/sparkfun/MPU-9250_Breakout 9 | architectures=samd 10 | -------------------------------------------------------------------------------- /Libraries/Arduino/src/MPU9250_RegisterMap.h: -------------------------------------------------------------------------------- 1 | /* 2 | */ 3 | #ifndef _MPU9250_REGISTER_MAP_H_ 4 | #define _MPU9250_REGISTER_MAP_H_ 5 | 6 | enum mpu9250_register { 7 | MPU9250_SELF_TEST_X_GYRO = 0x00, 8 | MPU9250_SELF_TEST_Y_GYRO = 0x01, 9 | MPU9250_SELF_TEST_Z_GYRO = 0x02, 10 | MPU9250_SELF_TEST_X_ACCEL = 0x0D, 11 | MPU9250_SELF_TEST_Y_ACCEL = 0x0E, 12 | MPU9250_SELF_TEST_Z_ACCEL = 0x0F, 13 | MPU9250_XG_OFFSET_H = 0x13, 14 | MPU9250_XG_OFFSET_L = 0x14, 15 | MPU9250_YG_OFFSET_H = 0x15, 16 | MPU9250_YG_OFFSET_L = 0x16, 17 | MPU9250_ZG_OFFSET_H = 0x17, 18 | MPU9250_ZG_OFFSET_L = 0x18, 19 | MPU9250_SMPLRT_DIV = 0x19, 20 | MPU9250_CONFIG = 0x1A, 21 | MPU9250_GYRO_CONFIG = 0x1B, 22 | MPU9250_ACCEL_CONFIG = 0x1C, 23 | MPU9250_ACCEL_CONFIG_2 = 0x1D, 24 | MPU9250_LP_ACCEL_ODR = 0x1E, 25 | MPU9250_WOM_THR = 0x1F, 26 | MPU9250_FIFO_EN = 0x23, 27 | MPU9250_I2C_MST_CTRL = 0x24, 28 | MPU9250_I2C_SLV0_ADDR = 0x25, 29 | MPU9250_I2C_SLV0_REG = 0x26, 30 | MPU9250_I2C_SLV0_CTRL = 0x27, 31 | MPU9250_I2C_SLV1_ADDR = 0x28, 32 | MPU9250_I2C_SLV1_REG = 0x29, 33 | MPU9250_I2C_SLV1_CTRL = 0x2A, 34 | MPU9250_I2C_SLV2_ADDR = 0x2B, 35 | MPU9250_I2C_SLV2_REG = 0x2C, 36 | MPU9250_I2C_SLV2_CTRL = 0x2D, 37 | MPU9250_I2C_SLV3_ADDR = 0x2E, 38 | MPU9250_I2C_SLV3_REG = 0x2F, 39 | MPU9250_I2C_SLV3_CTRL = 0x30, 40 | MPU9250_I2C_SLV4_ADDR = 0x31, 41 | MPU9250_I2C_SLV4_REG = 0x32, 42 | MPU9250_I2C_SLV4_DO = 0x33, 43 | MPU9250_I2C_SLV4_CTRL = 0x34, 44 | MPU9250_I2C_SLV4_DI = 0x35, 45 | MPU9250_I2C_MST_STATUS = 0x36, 46 | MPU9250_INT_PIN_CFG = 0x37, 47 | MPU9250_INT_ENABLE = 0x38, 48 | MPU9250_INT_STATUS = 0x3A, 49 | MPU9250_ACCEL_XOUT_H = 0x3B, 50 | MPU9250_ACCEL_XOUT_L = 0x3C, 51 | MPU9250_ACCEL_YOUT_H = 0x3D, 52 | MPU9250_ACCEL_YOUT_L = 0x3E, 53 | MPU9250_ACCEL_ZOUT_H = 0x3F, 54 | MPU9250_ACCEL_ZOUT_L = 0x40, 55 | MPU9250_TEMP_OUT_H = 0x41, 56 | MPU9250_TEMP_OUT_L = 0x42, 57 | MPU9250_GYRO_XOUT_H = 0x43, 58 | MPU9250_GYRO_XOUT_L = 0x44, 59 | MPU9250_GYRO_YOUT_H = 0x45, 60 | MPU9250_GYRO_YOUT_L = 0x46, 61 | MPU9250_GYRO_ZOUT_H = 0x47, 62 | MPU9250_GYRO_ZOUT_L = 0x48, 63 | MPU9250_EXT_SENS_DATA_00 = 0x49, 64 | MPU9250_EXT_SENS_DATA_01 = 0x4A, 65 | MPU9250_EXT_SENS_DATA_02 = 0x4B, 66 | MPU9250_EXT_SENS_DATA_03 = 0x4C, 67 | MPU9250_EXT_SENS_DATA_04 = 0x4D, 68 | MPU9250_EXT_SENS_DATA_05 = 0x4E, 69 | MPU9250_EXT_SENS_DATA_06 = 0x4F, 70 | MPU9250_EXT_SENS_DATA_07 = 0x50, 71 | MPU9250_EXT_SENS_DATA_08 = 0x51, 72 | MPU9250_EXT_SENS_DATA_09 = 0x52, 73 | MPU9250_EXT_SENS_DATA_10 = 0x53, 74 | MPU9250_EXT_SENS_DATA_11 = 0x54, 75 | MPU9250_EXT_SENS_DATA_12 = 0x55, 76 | MPU9250_EXT_SENS_DATA_13 = 0x56, 77 | MPU9250_EXT_SENS_DATA_14 = 0x57, 78 | MPU9250_EXT_SENS_DATA_15 = 0x58, 79 | MPU9250_EXT_SENS_DATA_16 = 0x59, 80 | MPU9250_EXT_SENS_DATA_17 = 0x5A, 81 | MPU9250_EXT_SENS_DATA_18 = 0x5B, 82 | MPU9250_EXT_SENS_DATA_19 = 0x5C, 83 | MPU9250_EXT_SENS_DATA_20 = 0x5D, 84 | MPU9250_EXT_SENS_DATA_21 = 0x5E, 85 | MPU9250_EXT_SENS_DATA_22 = 0x5F, 86 | MPU9250_EXT_SENS_DATA_23 = 0x60, 87 | MPU9250_I2C_SLV0_DO = 0x63, 88 | MPU9250_I2C_SLV1_DO = 0x64, 89 | MPU9250_I2C_SLV2_DO = 0x65, 90 | MPU9250_I2C_SLV3_DO = 0x66, 91 | MPU9250_I2C_MST_DELAY_CTRL =0x67, 92 | MPU9250_SIGNAL_PATH_RESET = 0x68, 93 | MPU9250_MOT_DETECT_CTRL = 0x69, 94 | MPU9250_USER_CTRL = 0x6A, 95 | MPU9250_PWR_MGMT_1 = 0x6B, 96 | MPU9250_PWR_MGMT_2 = 0x6C, 97 | MPU9250_FIFO_COUNTH = 0x72, 98 | MPU9250_FIFO_COUNTL = 0x73, 99 | MPU9250_FIFO_R_W = 0x74, 100 | MPU9250_WHO_AM_I = 0x75, 101 | MPU9250_XA_OFFSET_H = 0x77, 102 | MPU9250_XA_OFFSET_L = 0x78, 103 | MPU9250_YA_OFFSET_H = 0x7A, 104 | MPU9250_YA_OFFSET_L = 0x7B, 105 | MPU9250_ZA_OFFSET_H = 0x7D, 106 | MPU9250_ZA_OFFSET_L = 0x7E 107 | }; 108 | 109 | enum interrupt_status_bits { 110 | INT_STATUS_RAW_DATA_RDY_INT = 0, 111 | INT_STATUS_FSYNC_INT = 3, 112 | INT_STATUS_FIFO_OVERFLOW_INT = 4, 113 | INT_STATUS_WOM_INT = 6, 114 | }; 115 | 116 | enum gyro_config_bits { 117 | GYRO_CONFIG_FCHOICE_B = 0, 118 | GYRO_CONFIG_GYRO_FS_SEL = 3, 119 | GYRO_CONFIG_ZGYRO_CTEN = 5, 120 | GYRO_CONFIG_YGYRO_CTEN = 6, 121 | GYRO_CONFIG_XGYRO_CTEN = 7, 122 | }; 123 | #define MPU9250_GYRO_FS_SEL_MASK 0x3 124 | #define MPU9250_GYRO_FCHOICE_MASK 0x3 125 | 126 | enum accel_config_bit { 127 | ACCEL_CONFIG_ACCEL_FS_SEL = 3, 128 | ACCEL_CONFIG_AZ_ST_EN = 5, 129 | ACCEL_CONFIG_AY_ST_EN = 6, 130 | ACCEL_CONFIG_AX_ST_EN = 7, 131 | }; 132 | #define MPU9250_ACCEL_FS_SEL_MASK 0x3 133 | 134 | enum accel_config_2_bits { 135 | ACCEL_CONFIG_2_A_DLPFCFG = 0, 136 | ACCEL_CONFIG_2_ACCEL_FCHOICE_B = 3, 137 | }; 138 | 139 | enum pwr_mgmt_1_bits { 140 | PWR_MGMT_1_CLKSEL = 0, 141 | PWR_MGMT_1_PD_PTAT = 3, 142 | PWR_MGMT_1_GYRO_STANDBY = 4, 143 | PWR_MGMT_1_CYCLE = 5, 144 | PWR_MGMT_1_SLEEP = 6, 145 | PWR_MGMT_1_H_RESET = 7 146 | }; 147 | 148 | enum pwr_mgmt_2_bits { 149 | PWR_MGMT_2_DISABLE_ZG = 0, 150 | PWR_MGMT_2_DISABLE_YG = 1, 151 | PWR_MGMT_2_DISABLE_XG = 2, 152 | PWR_MGMT_2_DISABLE_ZA = 3, 153 | PWR_MGMT_2_DISABLE_YA = 4, 154 | PWR_MGMT_2_DISABLE_XA = 5, 155 | }; 156 | 157 | enum int_enable_bits { 158 | INT_ENABLE_RAW_RDY_EN = 0, 159 | INT_ENABLE_FSYNC_INT_EN = 3, 160 | INT_ENABLE_FIFO_OVERFLOW_EN = 4, 161 | INT_ENABLE_WOM_EN = 6, 162 | }; 163 | 164 | enum int_pin_cfg_bits { 165 | INT_PIN_CFG_BYPASS_EN = 1, 166 | INT_PIN_CFG_FSYNC_INT_MODE_EN = 2, 167 | INT_PIN_CFG_ACTL_FSYNC = 3, 168 | INT_PIN_CFG_INT_ANYRD_2CLEAR = 4, 169 | INT_PIN_CFG_LATCH_INT_EN = 5, 170 | INT_PIN_CFG_OPEN = 6, 171 | INT_PIN_CFG_ACTL = 7, 172 | }; 173 | #define INT_PIN_CFG_INT_MASK 0xF0 174 | 175 | #define MPU9250_WHO_AM_I_RESULT 0x71 176 | 177 | enum ak8963_register { 178 | AK8963_WIA = 0x0, 179 | AK8963_INFO = 0x1, 180 | AK8963_ST1 = 0x2, 181 | AK8963_HXL = 0x3, 182 | AK8963_HXH = 0x4, 183 | AK8963_HYL = 0x5, 184 | AK8963_HYH = 0x6, 185 | AK8963_HZL = 0x7, 186 | AK8963_HZH = 0x8, 187 | AK8963_ST2 = 0x9, 188 | AK8963_CNTL = 0xA, 189 | AK8963_RSV = 0xB, 190 | AK8963_ASTC = 0xC, 191 | AK8963_TS1 = 0xD, 192 | AK8963_TS2 = 0xE, 193 | AK8963_I2CDIS = 0xF, 194 | AK8963_ASAX = 0x10, 195 | AK8963_ASAY = 0x11, 196 | AK8963_ASAZ = 0x12, 197 | }; 198 | #define MAG_CTRL_OP_MODE_MASK 0xF 199 | 200 | #define AK8963_ST1_DRDY_BIT 0 201 | 202 | #define AK8963_WHO_AM_I_RESULT 0x48 203 | 204 | #endif // _MPU9250_REGISTER_MAP_H_ -------------------------------------------------------------------------------- /Libraries/Arduino/src/util/MPU9250_RegisterMap.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | MPU9250_RegisterMap.h - MPU-9250 Digital Motion Processor Arduino Library 3 | Jim Lindblom @ SparkFun Electronics 4 | original creation date: November 23, 2016 5 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 6 | 7 | This library implements motion processing functions of Invensense's MPU-9250. 8 | It is based on their Emedded MotionDriver 6.12 library. 9 | https://www.invensense.com/developers/software-downloads/ 10 | 11 | Development environment specifics: 12 | Arduino IDE 1.6.12 13 | SparkFun 9DoF Razor IMU M0 14 | 15 | Supported Platforms: 16 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 17 | ******************************************************************************/ 18 | #ifndef _MPU9250_REGISTER_MAP_H_ 19 | #define _MPU9250_REGISTER_MAP_H_ 20 | 21 | enum mpu9250_register { 22 | MPU9250_SELF_TEST_X_GYRO = 0x00, 23 | MPU9250_SELF_TEST_Y_GYRO = 0x01, 24 | MPU9250_SELF_TEST_Z_GYRO = 0x02, 25 | MPU9250_SELF_TEST_X_ACCEL = 0x0D, 26 | MPU9250_SELF_TEST_Y_ACCEL = 0x0E, 27 | MPU9250_SELF_TEST_Z_ACCEL = 0x0F, 28 | MPU9250_XG_OFFSET_H = 0x13, 29 | MPU9250_XG_OFFSET_L = 0x14, 30 | MPU9250_YG_OFFSET_H = 0x15, 31 | MPU9250_YG_OFFSET_L = 0x16, 32 | MPU9250_ZG_OFFSET_H = 0x17, 33 | MPU9250_ZG_OFFSET_L = 0x18, 34 | MPU9250_SMPLRT_DIV = 0x19, 35 | MPU9250_CONFIG = 0x1A, 36 | MPU9250_GYRO_CONFIG = 0x1B, 37 | MPU9250_ACCEL_CONFIG = 0x1C, 38 | MPU9250_ACCEL_CONFIG_2 = 0x1D, 39 | MPU9250_LP_ACCEL_ODR = 0x1E, 40 | MPU9250_WOM_THR = 0x1F, 41 | MPU9250_FIFO_EN = 0x23, 42 | MPU9250_I2C_MST_CTRL = 0x24, 43 | MPU9250_I2C_SLV0_ADDR = 0x25, 44 | MPU9250_I2C_SLV0_REG = 0x26, 45 | MPU9250_I2C_SLV0_CTRL = 0x27, 46 | MPU9250_I2C_SLV1_ADDR = 0x28, 47 | MPU9250_I2C_SLV1_REG = 0x29, 48 | MPU9250_I2C_SLV1_CTRL = 0x2A, 49 | MPU9250_I2C_SLV2_ADDR = 0x2B, 50 | MPU9250_I2C_SLV2_REG = 0x2C, 51 | MPU9250_I2C_SLV2_CTRL = 0x2D, 52 | MPU9250_I2C_SLV3_ADDR = 0x2E, 53 | MPU9250_I2C_SLV3_REG = 0x2F, 54 | MPU9250_I2C_SLV3_CTRL = 0x30, 55 | MPU9250_I2C_SLV4_ADDR = 0x31, 56 | MPU9250_I2C_SLV4_REG = 0x32, 57 | MPU9250_I2C_SLV4_DO = 0x33, 58 | MPU9250_I2C_SLV4_CTRL = 0x34, 59 | MPU9250_I2C_SLV4_DI = 0x35, 60 | MPU9250_I2C_MST_STATUS = 0x36, 61 | MPU9250_INT_PIN_CFG = 0x37, 62 | MPU9250_INT_ENABLE = 0x38, 63 | MPU9250_INT_STATUS = 0x3A, 64 | MPU9250_ACCEL_XOUT_H = 0x3B, 65 | MPU9250_ACCEL_XOUT_L = 0x3C, 66 | MPU9250_ACCEL_YOUT_H = 0x3D, 67 | MPU9250_ACCEL_YOUT_L = 0x3E, 68 | MPU9250_ACCEL_ZOUT_H = 0x3F, 69 | MPU9250_ACCEL_ZOUT_L = 0x40, 70 | MPU9250_TEMP_OUT_H = 0x41, 71 | MPU9250_TEMP_OUT_L = 0x42, 72 | MPU9250_GYRO_XOUT_H = 0x43, 73 | MPU9250_GYRO_XOUT_L = 0x44, 74 | MPU9250_GYRO_YOUT_H = 0x45, 75 | MPU9250_GYRO_YOUT_L = 0x46, 76 | MPU9250_GYRO_ZOUT_H = 0x47, 77 | MPU9250_GYRO_ZOUT_L = 0x48, 78 | MPU9250_EXT_SENS_DATA_00 = 0x49, 79 | MPU9250_EXT_SENS_DATA_01 = 0x4A, 80 | MPU9250_EXT_SENS_DATA_02 = 0x4B, 81 | MPU9250_EXT_SENS_DATA_03 = 0x4C, 82 | MPU9250_EXT_SENS_DATA_04 = 0x4D, 83 | MPU9250_EXT_SENS_DATA_05 = 0x4E, 84 | MPU9250_EXT_SENS_DATA_06 = 0x4F, 85 | MPU9250_EXT_SENS_DATA_07 = 0x50, 86 | MPU9250_EXT_SENS_DATA_08 = 0x51, 87 | MPU9250_EXT_SENS_DATA_09 = 0x52, 88 | MPU9250_EXT_SENS_DATA_10 = 0x53, 89 | MPU9250_EXT_SENS_DATA_11 = 0x54, 90 | MPU9250_EXT_SENS_DATA_12 = 0x55, 91 | MPU9250_EXT_SENS_DATA_13 = 0x56, 92 | MPU9250_EXT_SENS_DATA_14 = 0x57, 93 | MPU9250_EXT_SENS_DATA_15 = 0x58, 94 | MPU9250_EXT_SENS_DATA_16 = 0x59, 95 | MPU9250_EXT_SENS_DATA_17 = 0x5A, 96 | MPU9250_EXT_SENS_DATA_18 = 0x5B, 97 | MPU9250_EXT_SENS_DATA_19 = 0x5C, 98 | MPU9250_EXT_SENS_DATA_20 = 0x5D, 99 | MPU9250_EXT_SENS_DATA_21 = 0x5E, 100 | MPU9250_EXT_SENS_DATA_22 = 0x5F, 101 | MPU9250_EXT_SENS_DATA_23 = 0x60, 102 | MPU9250_I2C_SLV0_DO = 0x63, 103 | MPU9250_I2C_SLV1_DO = 0x64, 104 | MPU9250_I2C_SLV2_DO = 0x65, 105 | MPU9250_I2C_SLV3_DO = 0x66, 106 | MPU9250_I2C_MST_DELAY_CTRL =0x67, 107 | MPU9250_SIGNAL_PATH_RESET = 0x68, 108 | MPU9250_MOT_DETECT_CTRL = 0x69, 109 | MPU9250_USER_CTRL = 0x6A, 110 | MPU9250_PWR_MGMT_1 = 0x6B, 111 | MPU9250_PWR_MGMT_2 = 0x6C, 112 | MPU9250_FIFO_COUNTH = 0x72, 113 | MPU9250_FIFO_COUNTL = 0x73, 114 | MPU9250_FIFO_R_W = 0x74, 115 | MPU9250_WHO_AM_I = 0x75, 116 | MPU9250_XA_OFFSET_H = 0x77, 117 | MPU9250_XA_OFFSET_L = 0x78, 118 | MPU9250_YA_OFFSET_H = 0x7A, 119 | MPU9250_YA_OFFSET_L = 0x7B, 120 | MPU9250_ZA_OFFSET_H = 0x7D, 121 | MPU9250_ZA_OFFSET_L = 0x7E 122 | }; 123 | 124 | enum interrupt_status_bits { 125 | INT_STATUS_RAW_DATA_RDY_INT = 0, 126 | INT_STATUS_FSYNC_INT = 3, 127 | INT_STATUS_FIFO_OVERFLOW_INT = 4, 128 | INT_STATUS_WOM_INT = 6, 129 | }; 130 | 131 | enum gyro_config_bits { 132 | GYRO_CONFIG_FCHOICE_B = 0, 133 | GYRO_CONFIG_GYRO_FS_SEL = 3, 134 | GYRO_CONFIG_ZGYRO_CTEN = 5, 135 | GYRO_CONFIG_YGYRO_CTEN = 6, 136 | GYRO_CONFIG_XGYRO_CTEN = 7, 137 | }; 138 | #define MPU9250_GYRO_FS_SEL_MASK 0x3 139 | #define MPU9250_GYRO_FCHOICE_MASK 0x3 140 | 141 | enum accel_config_bit { 142 | ACCEL_CONFIG_ACCEL_FS_SEL = 3, 143 | ACCEL_CONFIG_AZ_ST_EN = 5, 144 | ACCEL_CONFIG_AY_ST_EN = 6, 145 | ACCEL_CONFIG_AX_ST_EN = 7, 146 | }; 147 | #define MPU9250_ACCEL_FS_SEL_MASK 0x3 148 | 149 | enum accel_config_2_bits { 150 | ACCEL_CONFIG_2_A_DLPFCFG = 0, 151 | ACCEL_CONFIG_2_ACCEL_FCHOICE_B = 3, 152 | }; 153 | 154 | enum pwr_mgmt_1_bits { 155 | PWR_MGMT_1_CLKSEL = 0, 156 | PWR_MGMT_1_PD_PTAT = 3, 157 | PWR_MGMT_1_GYRO_STANDBY = 4, 158 | PWR_MGMT_1_CYCLE = 5, 159 | PWR_MGMT_1_SLEEP = 6, 160 | PWR_MGMT_1_H_RESET = 7 161 | }; 162 | 163 | enum pwr_mgmt_2_bits { 164 | PWR_MGMT_2_DISABLE_ZG = 0, 165 | PWR_MGMT_2_DISABLE_YG = 1, 166 | PWR_MGMT_2_DISABLE_XG = 2, 167 | PWR_MGMT_2_DISABLE_ZA = 3, 168 | PWR_MGMT_2_DISABLE_YA = 4, 169 | PWR_MGMT_2_DISABLE_XA = 5, 170 | }; 171 | 172 | enum int_enable_bits { 173 | INT_ENABLE_RAW_RDY_EN = 0, 174 | INT_ENABLE_FSYNC_INT_EN = 3, 175 | INT_ENABLE_FIFO_OVERFLOW_EN = 4, 176 | INT_ENABLE_WOM_EN = 6, 177 | }; 178 | 179 | enum int_pin_cfg_bits { 180 | INT_PIN_CFG_BYPASS_EN = 1, 181 | INT_PIN_CFG_FSYNC_INT_MODE_EN = 2, 182 | INT_PIN_CFG_ACTL_FSYNC = 3, 183 | INT_PIN_CFG_INT_ANYRD_2CLEAR = 4, 184 | INT_PIN_CFG_LATCH_INT_EN = 5, 185 | INT_PIN_CFG_OPEN = 6, 186 | INT_PIN_CFG_ACTL = 7, 187 | }; 188 | #define INT_PIN_CFG_INT_MASK 0xF0 189 | 190 | #define MPU9250_WHO_AM_I_RESULT 0x71 191 | 192 | enum ak8963_register { 193 | AK8963_WIA = 0x0, 194 | AK8963_INFO = 0x1, 195 | AK8963_ST1 = 0x2, 196 | AK8963_HXL = 0x3, 197 | AK8963_HXH = 0x4, 198 | AK8963_HYL = 0x5, 199 | AK8963_HYH = 0x6, 200 | AK8963_HZL = 0x7, 201 | AK8963_HZH = 0x8, 202 | AK8963_ST2 = 0x9, 203 | AK8963_CNTL = 0xA, 204 | AK8963_RSV = 0xB, 205 | AK8963_ASTC = 0xC, 206 | AK8963_TS1 = 0xD, 207 | AK8963_TS2 = 0xE, 208 | AK8963_I2CDIS = 0xF, 209 | AK8963_ASAX = 0x10, 210 | AK8963_ASAY = 0x11, 211 | AK8963_ASAZ = 0x12, 212 | }; 213 | #define MAG_CTRL_OP_MODE_MASK 0xF 214 | 215 | #define AK8963_ST1_DRDY_BIT 0 216 | 217 | #define AK8963_WHO_AM_I_RESULT 0x48 218 | 219 | #endif // _MPU9250_REGISTER_MAP_H_ -------------------------------------------------------------------------------- /Libraries/Arduino/src/util/arduino_mpu9250_clk.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | arduino_mpu9250_clk.c - MPU-9250 Digital Motion Processor Arduino Library 3 | Jim Lindblom @ SparkFun Electronics 4 | original creation date: November 23, 2016 5 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 6 | 7 | This library implements motion processing functions of Invensense's MPU-9250. 8 | It is based on their Emedded MotionDriver 6.12 library. 9 | https://www.invensense.com/developers/software-downloads/ 10 | 11 | Development environment specifics: 12 | Arduino IDE 1.6.12 13 | SparkFun 9DoF Razor IMU M0 14 | 15 | Supported Platforms: 16 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 17 | ******************************************************************************/ 18 | #include "arduino_mpu9250_clk.h" 19 | #include 20 | 21 | int arduino_get_clock_ms(unsigned long *count) 22 | { 23 | *count = millis(); 24 | return 0; 25 | } 26 | 27 | int arduino_delay_ms(unsigned long num_ms) 28 | { 29 | delay(num_ms); 30 | return 0; 31 | } -------------------------------------------------------------------------------- /Libraries/Arduino/src/util/arduino_mpu9250_clk.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | arduino_mpu9250_clk.h - MPU-9250 Digital Motion Processor Arduino Library 3 | Jim Lindblom @ SparkFun Electronics 4 | original creation date: November 23, 2016 5 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 6 | 7 | This library implements motion processing functions of Invensense's MPU-9250. 8 | It is based on their Emedded MotionDriver 6.12 library. 9 | https://www.invensense.com/developers/software-downloads/ 10 | 11 | Development environment specifics: 12 | Arduino IDE 1.6.12 13 | SparkFun 9DoF Razor IMU M0 14 | 15 | Supported Platforms: 16 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 17 | ******************************************************************************/ 18 | #ifndef _ARDUINO_MPU9250_CLK_H_ 19 | #define _ARDUINO_MPU9250_CLK_H_ 20 | 21 | int arduino_get_clock_ms(unsigned long *count); 22 | int arduino_delay_ms(unsigned long num_ms); 23 | 24 | #endif // _ARDUINO_MPU9250_CLK_H_ -------------------------------------------------------------------------------- /Libraries/Arduino/src/util/arduino_mpu9250_i2c.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | arduino_mpu9250_i2c.cpp - MPU-9250 Digital Motion Processor Arduino Library 3 | Jim Lindblom @ SparkFun Electronics 4 | original creation date: November 23, 2016 5 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 6 | 7 | This library implements motion processing functions of Invensense's MPU-9250. 8 | It is based on their Emedded MotionDriver 6.12 library. 9 | https://www.invensense.com/developers/software-downloads/ 10 | 11 | Development environment specifics: 12 | Arduino IDE 1.6.12 13 | SparkFun 9DoF Razor IMU M0 14 | 15 | Supported Platforms: 16 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 17 | ******************************************************************************/ 18 | #include "arduino_mpu9250_i2c.h" 19 | #include 20 | #include 21 | 22 | int arduino_i2c_write(unsigned char slave_addr, unsigned char reg_addr, 23 | unsigned char length, unsigned char * data) 24 | { 25 | Wire.beginTransmission(slave_addr); 26 | Wire.write(reg_addr); 27 | for (unsigned char i = 0; i < length; i++) 28 | { 29 | Wire.write(data[i]); 30 | } 31 | Wire.endTransmission(true); 32 | 33 | return 0; 34 | } 35 | int arduino_i2c_read(unsigned char slave_addr, unsigned char reg_addr, 36 | unsigned char length, unsigned char * data) 37 | { 38 | Wire.beginTransmission(slave_addr); 39 | Wire.write(reg_addr); 40 | Wire.endTransmission(false); 41 | Wire.requestFrom(slave_addr, length); 42 | for (unsigned char i = 0; i < length; i++) 43 | { 44 | data[i] = Wire.read(); 45 | } 46 | Wire.endTransmission(true); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Libraries/Arduino/src/util/arduino_mpu9250_i2c.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | arduino_mpu9250_i2c.h - MPU-9250 Digital Motion Processor Arduino Library 3 | Jim Lindblom @ SparkFun Electronics 4 | original creation date: November 23, 2016 5 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 6 | 7 | This library implements motion processing functions of Invensense's MPU-9250. 8 | It is based on their Emedded MotionDriver 6.12 library. 9 | https://www.invensense.com/developers/software-downloads/ 10 | 11 | Development environment specifics: 12 | Arduino IDE 1.6.12 13 | SparkFun 9DoF Razor IMU M0 14 | 15 | Supported Platforms: 16 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 17 | ******************************************************************************/ 18 | #ifndef _ARDUINO_MPU9250_I2C_H_ 19 | #define _ARDUINO_MPU9250_I2C_H_ 20 | 21 | #if defined(__cplusplus) 22 | extern "C" { 23 | #endif 24 | 25 | int arduino_i2c_write(unsigned char slave_addr, unsigned char reg_addr, 26 | unsigned char length, unsigned char * data); 27 | int arduino_i2c_read(unsigned char slave_addr, unsigned char reg_addr, 28 | unsigned char length, unsigned char * data); 29 | 30 | #if defined(__cplusplus) 31 | } 32 | #endif 33 | 34 | #endif // _ARDUINO_MPU9250_I2C_H_ -------------------------------------------------------------------------------- /Libraries/Arduino/src/util/arduino_mpu9250_log.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | arduino_mpu9250_log.cpp - MPU-9250 Digital Motion Processor Arduino Library 3 | Jim Lindblom @ SparkFun Electronics 4 | original creation date: November 23, 2016 5 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 6 | 7 | This library implements motion processing functions of Invensense's MPU-9250. 8 | It is based on their Emedded MotionDriver 6.12 library. 9 | https://www.invensense.com/developers/software-downloads/ 10 | 11 | Development environment specifics: 12 | Arduino IDE 1.6.12 13 | SparkFun 9DoF Razor IMU M0 14 | 15 | Supported Platforms: 16 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 17 | ******************************************************************************/ 18 | #include "arduino_mpu9250_log.h" 19 | #include 20 | #include 21 | 22 | // Based on log_stm32.c from Invensense motion_driver_6.12 23 | 24 | #define BUF_SIZE (256) 25 | #define PACKET_LENGTH (23) 26 | 27 | #define PACKET_DEBUG (1) 28 | #define PACKET_QUAT (2) 29 | #define PACKET_DATA (3) 30 | 31 | void logString(char * string) 32 | { 33 | } 34 | 35 | int _MLPrintLog (int priority, const char* tag, const char* fmt, ...) 36 | { 37 | } 38 | 39 | void eMPL_send_quat(long *quat) 40 | { 41 | } 42 | 43 | void eMPL_send_data(unsigned char type, long *data) 44 | { 45 | } -------------------------------------------------------------------------------- /Libraries/Arduino/src/util/arduino_mpu9250_log.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | arduino_mpu9250_log.h - MPU-9250 Digital Motion Processor Arduino Library 3 | Jim Lindblom @ SparkFun Electronics 4 | original creation date: November 23, 2016 5 | https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library 6 | 7 | This library implements motion processing functions of Invensense's MPU-9250. 8 | It is based on their Emedded MotionDriver 6.12 library. 9 | https://www.invensense.com/developers/software-downloads/ 10 | 11 | Development environment specifics: 12 | Arduino IDE 1.6.12 13 | SparkFun 9DoF Razor IMU M0 14 | 15 | Supported Platforms: 16 | - ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) 17 | ******************************************************************************/ 18 | #ifndef _ARDUINO_MPU9250_LOG_H_ 19 | #define _ARDUINO_MPU9250_LOG_H_ 20 | 21 | #define MPL_LOG_UNKNOWN (0) 22 | #define MPL_LOG_DEFAULT (1) 23 | #define MPL_LOG_VERBOSE (2) 24 | #define MPL_LOG_DEBUG (3) 25 | #define MPL_LOG_INFO (4) 26 | #define MPL_LOG_WARN (5) 27 | #define MPL_LOG_ERROR (6) 28 | #define MPL_LOG_SILENT (8) 29 | 30 | typedef enum { 31 | PACKET_DATA_ACCEL = 0, 32 | PACKET_DATA_GYRO, 33 | PACKET_DATA_COMPASS, 34 | PACKET_DATA_QUAT, 35 | PACKET_DATA_EULER, 36 | PACKET_DATA_ROT, 37 | PACKET_DATA_HEADING, 38 | PACKET_DATA_LINEAR_ACCEL, 39 | NUM_DATA_PACKETS 40 | } eMPL_packet_e; 41 | 42 | #if defined(__cplusplus) 43 | extern "C" { 44 | #endif 45 | 46 | #include 47 | 48 | void logString(char * string); 49 | int _MLPrintLog (int priority, const char* tag, const char* fmt, ...); 50 | void eMPL_send_quat(long *quat); 51 | void eMPL_send_data(unsigned char type, long *data); 52 | 53 | #if defined(__cplusplus) 54 | } 55 | #endif 56 | 57 | 58 | #endif // _ARDUINO_MPU9250_LOG_H_ -------------------------------------------------------------------------------- /Libraries/Arduino/src/util/dmpmap.h: -------------------------------------------------------------------------------- 1 | /* 2 | $License: 3 | Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. 4 | $ 5 | */ 6 | #ifndef DMPMAP_H 7 | #define DMPMAP_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" 11 | { 12 | #endif 13 | 14 | #define DMP_PTAT 0 15 | #define DMP_XGYR 2 16 | #define DMP_YGYR 4 17 | #define DMP_ZGYR 6 18 | #define DMP_XACC 8 19 | #define DMP_YACC 10 20 | #define DMP_ZACC 12 21 | #define DMP_ADC1 14 22 | #define DMP_ADC2 16 23 | #define DMP_ADC3 18 24 | #define DMP_BIASUNC 20 25 | #define DMP_FIFORT 22 26 | #define DMP_INVGSFH 24 27 | #define DMP_INVGSFL 26 28 | #define DMP_1H 28 29 | #define DMP_1L 30 30 | #define DMP_BLPFSTCH 32 31 | #define DMP_BLPFSTCL 34 32 | #define DMP_BLPFSXH 36 33 | #define DMP_BLPFSXL 38 34 | #define DMP_BLPFSYH 40 35 | #define DMP_BLPFSYL 42 36 | #define DMP_BLPFSZH 44 37 | #define DMP_BLPFSZL 46 38 | #define DMP_BLPFMTC 48 39 | #define DMP_SMC 50 40 | #define DMP_BLPFMXH 52 41 | #define DMP_BLPFMXL 54 42 | #define DMP_BLPFMYH 56 43 | #define DMP_BLPFMYL 58 44 | #define DMP_BLPFMZH 60 45 | #define DMP_BLPFMZL 62 46 | #define DMP_BLPFC 64 47 | #define DMP_SMCTH 66 48 | #define DMP_0H2 68 49 | #define DMP_0L2 70 50 | #define DMP_BERR2H 72 51 | #define DMP_BERR2L 74 52 | #define DMP_BERR2NH 76 53 | #define DMP_SMCINC 78 54 | #define DMP_ANGVBXH 80 55 | #define DMP_ANGVBXL 82 56 | #define DMP_ANGVBYH 84 57 | #define DMP_ANGVBYL 86 58 | #define DMP_ANGVBZH 88 59 | #define DMP_ANGVBZL 90 60 | #define DMP_BERR1H 92 61 | #define DMP_BERR1L 94 62 | #define DMP_ATCH 96 63 | #define DMP_BIASUNCSF 98 64 | #define DMP_ACT2H 100 65 | #define DMP_ACT2L 102 66 | #define DMP_GSFH 104 67 | #define DMP_GSFL 106 68 | #define DMP_GH 108 69 | #define DMP_GL 110 70 | #define DMP_0_5H 112 71 | #define DMP_0_5L 114 72 | #define DMP_0_0H 116 73 | #define DMP_0_0L 118 74 | #define DMP_1_0H 120 75 | #define DMP_1_0L 122 76 | #define DMP_1_5H 124 77 | #define DMP_1_5L 126 78 | #define DMP_TMP1AH 128 79 | #define DMP_TMP1AL 130 80 | #define DMP_TMP2AH 132 81 | #define DMP_TMP2AL 134 82 | #define DMP_TMP3AH 136 83 | #define DMP_TMP3AL 138 84 | #define DMP_TMP4AH 140 85 | #define DMP_TMP4AL 142 86 | #define DMP_XACCW 144 87 | #define DMP_TMP5 146 88 | #define DMP_XACCB 148 89 | #define DMP_TMP8 150 90 | #define DMP_YACCB 152 91 | #define DMP_TMP9 154 92 | #define DMP_ZACCB 156 93 | #define DMP_TMP10 158 94 | #define DMP_DZH 160 95 | #define DMP_DZL 162 96 | #define DMP_XGCH 164 97 | #define DMP_XGCL 166 98 | #define DMP_YGCH 168 99 | #define DMP_YGCL 170 100 | #define DMP_ZGCH 172 101 | #define DMP_ZGCL 174 102 | #define DMP_YACCW 176 103 | #define DMP_TMP7 178 104 | #define DMP_AFB1H 180 105 | #define DMP_AFB1L 182 106 | #define DMP_AFB2H 184 107 | #define DMP_AFB2L 186 108 | #define DMP_MAGFBH 188 109 | #define DMP_MAGFBL 190 110 | #define DMP_QT1H 192 111 | #define DMP_QT1L 194 112 | #define DMP_QT2H 196 113 | #define DMP_QT2L 198 114 | #define DMP_QT3H 200 115 | #define DMP_QT3L 202 116 | #define DMP_QT4H 204 117 | #define DMP_QT4L 206 118 | #define DMP_CTRL1H 208 119 | #define DMP_CTRL1L 210 120 | #define DMP_CTRL2H 212 121 | #define DMP_CTRL2L 214 122 | #define DMP_CTRL3H 216 123 | #define DMP_CTRL3L 218 124 | #define DMP_CTRL4H 220 125 | #define DMP_CTRL4L 222 126 | #define DMP_CTRLS1 224 127 | #define DMP_CTRLSF1 226 128 | #define DMP_CTRLS2 228 129 | #define DMP_CTRLSF2 230 130 | #define DMP_CTRLS3 232 131 | #define DMP_CTRLSFNLL 234 132 | #define DMP_CTRLS4 236 133 | #define DMP_CTRLSFNL2 238 134 | #define DMP_CTRLSFNL 240 135 | #define DMP_TMP30 242 136 | #define DMP_CTRLSFJT 244 137 | #define DMP_TMP31 246 138 | #define DMP_TMP11 248 139 | #define DMP_CTRLSF2_2 250 140 | #define DMP_TMP12 252 141 | #define DMP_CTRLSF1_2 254 142 | #define DMP_PREVPTAT 256 143 | #define DMP_ACCZB 258 144 | #define DMP_ACCXB 264 145 | #define DMP_ACCYB 266 146 | #define DMP_1HB 272 147 | #define DMP_1LB 274 148 | #define DMP_0H 276 149 | #define DMP_0L 278 150 | #define DMP_ASR22H 280 151 | #define DMP_ASR22L 282 152 | #define DMP_ASR6H 284 153 | #define DMP_ASR6L 286 154 | #define DMP_TMP13 288 155 | #define DMP_TMP14 290 156 | #define DMP_FINTXH 292 157 | #define DMP_FINTXL 294 158 | #define DMP_FINTYH 296 159 | #define DMP_FINTYL 298 160 | #define DMP_FINTZH 300 161 | #define DMP_FINTZL 302 162 | #define DMP_TMP1BH 304 163 | #define DMP_TMP1BL 306 164 | #define DMP_TMP2BH 308 165 | #define DMP_TMP2BL 310 166 | #define DMP_TMP3BH 312 167 | #define DMP_TMP3BL 314 168 | #define DMP_TMP4BH 316 169 | #define DMP_TMP4BL 318 170 | #define DMP_STXG 320 171 | #define DMP_ZCTXG 322 172 | #define DMP_STYG 324 173 | #define DMP_ZCTYG 326 174 | #define DMP_STZG 328 175 | #define DMP_ZCTZG 330 176 | #define DMP_CTRLSFJT2 332 177 | #define DMP_CTRLSFJTCNT 334 178 | #define DMP_PVXG 336 179 | #define DMP_TMP15 338 180 | #define DMP_PVYG 340 181 | #define DMP_TMP16 342 182 | #define DMP_PVZG 344 183 | #define DMP_TMP17 346 184 | #define DMP_MNMFLAGH 352 185 | #define DMP_MNMFLAGL 354 186 | #define DMP_MNMTMH 356 187 | #define DMP_MNMTML 358 188 | #define DMP_MNMTMTHRH 360 189 | #define DMP_MNMTMTHRL 362 190 | #define DMP_MNMTHRH 364 191 | #define DMP_MNMTHRL 366 192 | #define DMP_ACCQD4H 368 193 | #define DMP_ACCQD4L 370 194 | #define DMP_ACCQD5H 372 195 | #define DMP_ACCQD5L 374 196 | #define DMP_ACCQD6H 376 197 | #define DMP_ACCQD6L 378 198 | #define DMP_ACCQD7H 380 199 | #define DMP_ACCQD7L 382 200 | #define DMP_ACCQD0H 384 201 | #define DMP_ACCQD0L 386 202 | #define DMP_ACCQD1H 388 203 | #define DMP_ACCQD1L 390 204 | #define DMP_ACCQD2H 392 205 | #define DMP_ACCQD2L 394 206 | #define DMP_ACCQD3H 396 207 | #define DMP_ACCQD3L 398 208 | #define DMP_XN2H 400 209 | #define DMP_XN2L 402 210 | #define DMP_XN1H 404 211 | #define DMP_XN1L 406 212 | #define DMP_YN2H 408 213 | #define DMP_YN2L 410 214 | #define DMP_YN1H 412 215 | #define DMP_YN1L 414 216 | #define DMP_YH 416 217 | #define DMP_YL 418 218 | #define DMP_B0H 420 219 | #define DMP_B0L 422 220 | #define DMP_A1H 424 221 | #define DMP_A1L 426 222 | #define DMP_A2H 428 223 | #define DMP_A2L 430 224 | #define DMP_SEM1 432 225 | #define DMP_FIFOCNT 434 226 | #define DMP_SH_TH_X 436 227 | #define DMP_PACKET 438 228 | #define DMP_SH_TH_Y 440 229 | #define DMP_FOOTER 442 230 | #define DMP_SH_TH_Z 444 231 | #define DMP_TEMP29 448 232 | #define DMP_TEMP30 450 233 | #define DMP_XACCB_PRE 452 234 | #define DMP_XACCB_PREL 454 235 | #define DMP_YACCB_PRE 456 236 | #define DMP_YACCB_PREL 458 237 | #define DMP_ZACCB_PRE 460 238 | #define DMP_ZACCB_PREL 462 239 | #define DMP_TMP22 464 240 | #define DMP_TAP_TIMER 466 241 | #define DMP_TAP_THX 468 242 | #define DMP_TAP_THY 472 243 | #define DMP_TAP_THZ 476 244 | #define DMP_TAPW_MIN 478 245 | #define DMP_TMP25 480 246 | #define DMP_TMP26 482 247 | #define DMP_TMP27 484 248 | #define DMP_TMP28 486 249 | #define DMP_ORIENT 488 250 | #define DMP_THRSH 490 251 | #define DMP_ENDIANH 492 252 | #define DMP_ENDIANL 494 253 | #define DMP_BLPFNMTCH 496 254 | #define DMP_BLPFNMTCL 498 255 | #define DMP_BLPFNMXH 500 256 | #define DMP_BLPFNMXL 502 257 | #define DMP_BLPFNMYH 504 258 | #define DMP_BLPFNMYL 506 259 | #define DMP_BLPFNMZH 508 260 | #define DMP_BLPFNMZL 510 261 | #ifdef __cplusplus 262 | } 263 | #endif 264 | #endif // DMPMAP_H 265 | -------------------------------------------------------------------------------- /Libraries/Arduino/src/util/inv_mpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | $License: 3 | Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. 4 | See included License.txt for License information. 5 | $ 6 | */ 7 | /** 8 | * @addtogroup DRIVERS Sensor Driver Layer 9 | * @brief Hardware drivers to communicate with sensors via I2C. 10 | * 11 | * @{ 12 | * @file inv_mpu.h 13 | * @brief An I2C-based driver for Invensense gyroscopes. 14 | * @details This driver currently works for the following devices: 15 | * MPU6050 16 | * MPU6500 17 | * MPU9150 (or MPU6050 w/ AK8975 on the auxiliary bus) 18 | * MPU9250 (or MPU6500 w/ AK8963 on the auxiliary bus) 19 | */ 20 | 21 | #ifndef _INV_MPU_H_ 22 | #define _INV_MPU_H_ 23 | 24 | #define INV_X_GYRO (0x40) 25 | #define INV_Y_GYRO (0x20) 26 | #define INV_Z_GYRO (0x10) 27 | #define INV_XYZ_GYRO (INV_X_GYRO | INV_Y_GYRO | INV_Z_GYRO) 28 | #define INV_XYZ_ACCEL (0x08) 29 | #define INV_XYZ_COMPASS (0x01) 30 | 31 | struct int_param_s { 32 | #if defined EMPL_TARGET_MSP430 || defined MOTION_DRIVER_TARGET_MSP430 33 | void (*cb)(void); 34 | unsigned short pin; 35 | unsigned char lp_exit; 36 | unsigned char active_low; 37 | #elif defined EMPL_TARGET_UC3L0 38 | unsigned long pin; 39 | void (*cb)(volatile void*); 40 | void *arg; 41 | #elif defined EMPL_TARGET_STM32F4 42 | void (*cb)(void); 43 | #endif 44 | }; 45 | 46 | #define MPU_INT_STATUS_DATA_READY (0x0001) 47 | #define MPU_INT_STATUS_DMP (0x0002) 48 | #define MPU_INT_STATUS_PLL_READY (0x0004) 49 | #define MPU_INT_STATUS_I2C_MST (0x0008) 50 | #define MPU_INT_STATUS_FIFO_OVERFLOW (0x0010) 51 | #define MPU_INT_STATUS_ZMOT (0x0020) 52 | #define MPU_INT_STATUS_MOT (0x0040) 53 | #define MPU_INT_STATUS_FREE_FALL (0x0080) 54 | #define MPU_INT_STATUS_DMP_0 (0x0100) 55 | #define MPU_INT_STATUS_DMP_1 (0x0200) 56 | #define MPU_INT_STATUS_DMP_2 (0x0400) 57 | #define MPU_INT_STATUS_DMP_3 (0x0800) 58 | #define MPU_INT_STATUS_DMP_4 (0x1000) 59 | #define MPU_INT_STATUS_DMP_5 (0x2000) 60 | 61 | /* Set up APIs */ 62 | int set_int_enable(unsigned char enable); 63 | int mpu_init(struct int_param_s *int_param); 64 | int mpu_init_slave(void); 65 | int mpu_set_bypass(unsigned char bypass_on); 66 | 67 | /* Configuration APIs */ 68 | int mpu_lp_accel_mode(unsigned short rate); 69 | int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time, 70 | unsigned short lpa_freq); 71 | int mpu_set_int_level(unsigned char active_low); 72 | int mpu_set_int_latched(unsigned char enable); 73 | 74 | int mpu_set_dmp_state(unsigned char enable); 75 | int mpu_get_dmp_state(unsigned char *enabled); 76 | 77 | int mpu_get_lpf(unsigned short *lpf); 78 | int mpu_set_lpf(unsigned short lpf); 79 | 80 | int mpu_get_gyro_fsr(unsigned short *fsr); 81 | int mpu_set_gyro_fsr(unsigned short fsr); 82 | 83 | int mpu_get_accel_fsr(unsigned char *fsr); 84 | int mpu_set_accel_fsr(unsigned char fsr); 85 | 86 | int mpu_get_compass_fsr(unsigned short *fsr); 87 | 88 | int mpu_get_gyro_sens(float *sens); 89 | int mpu_get_accel_sens(unsigned short *sens); 90 | 91 | int mpu_get_sample_rate(unsigned short *rate); 92 | int mpu_set_sample_rate(unsigned short rate); 93 | int mpu_get_compass_sample_rate(unsigned short *rate); 94 | int mpu_set_compass_sample_rate(unsigned short rate); 95 | 96 | int mpu_get_fifo_config(unsigned char *sensors); 97 | int mpu_configure_fifo(unsigned char sensors); 98 | 99 | int mpu_get_power_state(unsigned char *power_on); 100 | int mpu_set_sensors(unsigned char sensors); 101 | 102 | int mpu_read_6500_accel_bias(long *accel_bias); 103 | int mpu_set_gyro_bias_reg(long * gyro_bias); 104 | int mpu_set_accel_bias_6500_reg(const long *accel_bias); 105 | int mpu_read_6050_accel_bias(long *accel_bias); 106 | int mpu_set_accel_bias_6050_reg(const long *accel_bias); 107 | 108 | /* Data getter/setter APIs */ 109 | int mpu_get_gyro_reg(short *data, unsigned long *timestamp); 110 | int mpu_get_accel_reg(short *data, unsigned long *timestamp); 111 | int mpu_get_compass_reg(short *data, unsigned long *timestamp); 112 | int mpu_get_temperature(long *data, unsigned long *timestamp); 113 | 114 | int mpu_get_int_status(short *status); 115 | int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, 116 | unsigned char *sensors, unsigned char *more); 117 | int mpu_read_fifo_stream(unsigned short length, unsigned char *data, 118 | unsigned char *more); 119 | int mpu_reset_fifo(void); 120 | 121 | int mpu_write_mem(unsigned short mem_addr, unsigned short length, 122 | unsigned char *data); 123 | int mpu_read_mem(unsigned short mem_addr, unsigned short length, 124 | unsigned char *data); 125 | int mpu_load_firmware(unsigned short length, const unsigned char *firmware, 126 | unsigned short start_addr, unsigned short sample_rate); 127 | 128 | int mpu_reg_dump(void); 129 | int mpu_read_reg(unsigned char reg, unsigned char *data); 130 | int mpu_run_self_test(long *gyro, long *accel); 131 | int mpu_run_6500_self_test(long *gyro, long *accel, unsigned char debug); 132 | int mpu_register_tap_cb(void (*func)(unsigned char, unsigned char)); 133 | 134 | #endif /* #ifndef _INV_MPU_H_ */ 135 | 136 | -------------------------------------------------------------------------------- /Libraries/Arduino/src/util/inv_mpu_dmp_motion_driver.h: -------------------------------------------------------------------------------- 1 | /* 2 | $License: 3 | Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. 4 | See included License.txt for License information. 5 | $ 6 | */ 7 | /** 8 | * @addtogroup DRIVERS Sensor Driver Layer 9 | * @brief Hardware drivers to communicate with sensors via I2C. 10 | * 11 | * @{ 12 | * @file inv_mpu_dmp_motion_driver.h 13 | * @brief DMP image and interface functions. 14 | * @details All functions are preceded by the dmp_ prefix to 15 | * differentiate among MPL and general driver function calls. 16 | */ 17 | #ifndef _INV_MPU_DMP_MOTION_DRIVER_H_ 18 | #define _INV_MPU_DMP_MOTION_DRIVER_H_ 19 | 20 | #define TAP_X (0x01) 21 | #define TAP_Y (0x02) 22 | #define TAP_Z (0x04) 23 | #define TAP_XYZ (0x07) 24 | 25 | #define TAP_X_UP (0x01) 26 | #define TAP_X_DOWN (0x02) 27 | #define TAP_Y_UP (0x03) 28 | #define TAP_Y_DOWN (0x04) 29 | #define TAP_Z_UP (0x05) 30 | #define TAP_Z_DOWN (0x06) 31 | 32 | #define ANDROID_ORIENT_PORTRAIT (0x00) 33 | #define ANDROID_ORIENT_LANDSCAPE (0x01) 34 | #define ANDROID_ORIENT_REVERSE_PORTRAIT (0x02) 35 | #define ANDROID_ORIENT_REVERSE_LANDSCAPE (0x03) 36 | 37 | #define DMP_INT_GESTURE (0x01) 38 | #define DMP_INT_CONTINUOUS (0x02) 39 | 40 | #define DMP_FEATURE_TAP (0x001) 41 | #define DMP_FEATURE_ANDROID_ORIENT (0x002) 42 | #define DMP_FEATURE_LP_QUAT (0x004) 43 | #define DMP_FEATURE_PEDOMETER (0x008) 44 | #define DMP_FEATURE_6X_LP_QUAT (0x010) 45 | #define DMP_FEATURE_GYRO_CAL (0x020) 46 | #define DMP_FEATURE_SEND_RAW_ACCEL (0x040) 47 | #define DMP_FEATURE_SEND_RAW_GYRO (0x080) 48 | #define DMP_FEATURE_SEND_CAL_GYRO (0x100) 49 | 50 | #define INV_WXYZ_QUAT (0x100) 51 | 52 | /* Set up functions. */ 53 | int dmp_load_motion_driver_firmware(void); 54 | int dmp_set_fifo_rate(unsigned short rate); 55 | int dmp_get_fifo_rate(unsigned short *rate); 56 | int dmp_enable_feature(unsigned short mask); 57 | int dmp_get_enabled_features(unsigned short *mask); 58 | int dmp_set_interrupt_mode(unsigned char mode); 59 | int dmp_set_orientation(unsigned short orient); 60 | int dmp_set_gyro_bias(long *bias); 61 | int dmp_set_accel_bias(long *bias); 62 | 63 | /* Tap functions. */ 64 | int dmp_register_tap_cb(void (*func)(unsigned char, unsigned char)); 65 | int dmp_set_tap_thresh(unsigned char axis, unsigned short thresh); 66 | int dmp_set_tap_axes(unsigned char axis); 67 | int dmp_set_tap_count(unsigned char min_taps); 68 | int dmp_set_tap_time(unsigned short time); 69 | int dmp_set_tap_time_multi(unsigned short time); 70 | int dmp_set_shake_reject_thresh(long sf, unsigned short thresh); 71 | int dmp_set_shake_reject_time(unsigned short time); 72 | int dmp_set_shake_reject_timeout(unsigned short time); 73 | 74 | /* Android orientation functions. */ 75 | int dmp_register_android_orient_cb(void (*func)(unsigned char)); 76 | 77 | /* LP quaternion functions. */ 78 | int dmp_enable_lp_quat(unsigned char enable); 79 | int dmp_enable_6x_lp_quat(unsigned char enable); 80 | 81 | /* Pedometer functions. */ 82 | int dmp_get_pedometer_step_count(unsigned long *count); 83 | int dmp_set_pedometer_step_count(unsigned long count); 84 | int dmp_get_pedometer_walk_time(unsigned long *time); 85 | int dmp_set_pedometer_walk_time(unsigned long time); 86 | 87 | /* DMP gyro calibration functions. */ 88 | int dmp_enable_gyro_cal(unsigned char enable); 89 | 90 | /* Read function. This function should be called whenever the MPU interrupt is 91 | * detected. 92 | */ 93 | int dmp_read_fifo(short *gyro, short *accel, long *quat, 94 | unsigned long *timestamp, short *sensors, unsigned char *more); 95 | 96 | #endif /* #ifndef _INV_MPU_DMP_MOTION_DRIVER_H_ */ 97 | 98 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SparkFun 9DoF Razor IMU M0 2 | ======================================== 3 | 4 | [![SparkFun 9DoF Razor IMU M0](https://cdn.sparkfun.com/r/500-500/assets/parts/1/1/7/7/5/14001-04.jpg)](https://www.sparkfun.com/products/14001) 5 | 6 | [*SparkFun 9DoF Razor IMU M0 (SEN-14001)*](https://www.sparkfun.com/products/14001) 7 | 8 | The [SparkFun 9DoF Razor IMU M0](https://www.sparkfun.com/products/14001) combines a [SAMD21](https://www.sparkfun.com/products/13664) microprocessor with an [MPU-9250](https://www.sparkfun.com/products/13762) 9DoF (nine degrees of freedom) sensor to create a tiny, re-programmable, multi-purpose inertial measurement unit (IMU). It can be programmed to monitor and log motion, transmit Euler angles over a serial port, or to even act as a step-counting pedometer. 9 | 10 | The 9DoF Razor's MPU-9250 features three, three-axis sensors -- an accelerometer, gyroscope, and magnetometer -- which gives it the ability to sense linear acceleration, angular rotation velocity, and magnetic field vector's. The on-board microprocessor -- Atmel's [SAMD21G18A](http://www.atmel.com/devices/ATSAMD21G18.aspx) -- is an Arduino-compatible, 32-bit ARM Cortex-M0+ microcontroller also featured on the [Arduino Zero](https://www.arduino.cc/en/Main/ArduinoBoardZero) and [SAMD21 Mini Breakout](https://www.sparkfun.com/products/13664) boards. 11 | 12 | Repository Contents 13 | ------------------- 14 | 15 | * **/Documentation** - Data sheets, additional product information 16 | * **/Firmware** - Example code 17 | * **/Hardware** - Eagle design files (.brd, .sch) 18 | * **/Libraries** - Libraries for use with the 9DoF Razor IMU M0 19 | * **/Production Files** - Production panel files (.brd) 20 | 21 | Documentation 22 | -------------- 23 | * **[SparkFun MPU-9250 DMP Arduino Library](https://github.com/sparkfun/SparkFun_MPU-9250-DMP_Arduino_Library)** - Arduino library for the 9DoF Razor IMU M0's MPU-9250, enabling the 9DoF's digital motion processor (DMP). 24 | * **[Hookup Guide](https://learn.sparkfun.com/tutorials/9dof-razor-imu-m0-hookup-guide)** - Basic hookup guide for the 9DoF Razor IMU M0. 25 | * **[SparkFun Fritzing repo](https://github.com/sparkfun/Fritzing_Parts)** - Fritzing diagrams for SparkFun products. 26 | * **[SparkFun 3D Model repo](https://github.com/sparkfun/3D_Models)** - 3D models of SparkFun products. 27 | 28 | Product Versions 29 | ---------------- 30 | * [SparkFun 9DoF Razor IMU M0 (SEN-14001)](https://www.sparkfun.com/products/14001)- Latest release. 31 | * [SparkFun 9DoF Razor IMU (SEN-10736)](https://www.sparkfun.com/products/retired/10736) - Initial release, featuring an ATmega328, ADXL345 (accelerometer), ITG-3200 (gyroscope), and HMC5883L (magnetometer). 32 | 33 | Version History 34 | --------------- 35 | * [V_3.0](https://github.com/sparkfun/9DOF_Razor_IMU/releases/tag/V_3.0) - Hardware and firmware files for version 3.0 -- released as SEN-14001. 36 | * [V_2.3](https://github.com/sparkfun/9DOF_Razor_IMU/releases/tag/V_2.3) - Hardware and firmware design files for version 2.3 -- released as SEN-10736. 37 | 38 | License Information 39 | ------------------- 40 | 41 | This product is _**open source**_! 42 | 43 | Please review the LICENSE.md file for license information. 44 | 45 | If you have any questions or concerns on licensing, please contact techsupport@sparkfun.com. 46 | 47 | Distributed as-is; no warranty is given. 48 | 49 | - Your friends at SparkFun. 50 | --------------------------------------------------------------------------------