├── .gitignore ├── Makefile ├── README.md ├── chconf.h ├── halconf.h ├── main.c ├── mcuconf.h ├── myADC.c ├── myADC.h ├── myMisc.c ├── myMisc.h ├── myPWM.c ├── myPWM.h ├── myUSB.c ├── myUSB.h └── usbdescriptor.h /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .dep 3 | build 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Build global options 3 | # NOTE: Can be overridden externally. 4 | # 5 | 6 | # Compiler options here. 7 | ifeq ($(USE_OPT),) 8 | USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 9 | endif 10 | 11 | # C specific options here (added to USE_OPT). 12 | ifeq ($(USE_COPT),) 13 | USE_COPT = 14 | endif 15 | 16 | # C++ specific options here (added to USE_OPT). 17 | ifeq ($(USE_CPPOPT),) 18 | USE_CPPOPT = -fno-rtti 19 | endif 20 | 21 | # Enable this if you want the linker to remove unused code and data 22 | ifeq ($(USE_LINK_GC),) 23 | USE_LINK_GC = yes 24 | endif 25 | 26 | # If enabled, this option allows to compile the application in THUMB mode. 27 | ifeq ($(USE_THUMB),) 28 | USE_THUMB = yes 29 | endif 30 | 31 | # Enable this if you want to see the full log while compiling. 32 | ifeq ($(USE_VERBOSE_COMPILE),) 33 | USE_VERBOSE_COMPILE = no 34 | endif 35 | 36 | # 37 | # Build global options 38 | ############################################################################## 39 | 40 | ############################################################################## 41 | # Architecture or project specific options 42 | # 43 | 44 | # Enables the use of FPU on Cortex-M4. 45 | # Enable this if you really want to use the STM FWLib. 46 | ifeq ($(USE_FPU),) 47 | USE_FPU = yes 48 | endif 49 | 50 | # Enable this if you really want to use the STM FWLib. 51 | ifeq ($(USE_FWLIB),) 52 | USE_FWLIB = no 53 | endif 54 | 55 | # 56 | # Architecture or project specific options 57 | ############################################################################## 58 | 59 | ############################################################################## 60 | # Project, sources and paths 61 | # 62 | 63 | # Define project name here 64 | PROJECT = ch 65 | 66 | # Imported source files and paths 67 | CHIBIOS = ../../chibios 68 | include $(CHIBIOS)/boards/ST_STM32F4_DISCOVERY/board.mk 69 | include $(CHIBIOS)/os/hal/platforms/STM32F4xx/platform.mk 70 | include $(CHIBIOS)/os/hal/hal.mk 71 | include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F4xx/port.mk 72 | include $(CHIBIOS)/os/kernel/kernel.mk 73 | #include $(CHIBIOS)/test/test.mk 74 | 75 | # Define linker script file here 76 | LDSCRIPT= $(PORTLD)/STM32F407xG.ld 77 | #LDSCRIPT= $(PORTLD)/STM32F407xG_CCM.ld 78 | 79 | # C sources that can be compiled in ARM or THUMB mode depending on the global 80 | # setting. 81 | CSRC = $(PORTSRC) \ 82 | $(KERNSRC) \ 83 | $(HALSRC) \ 84 | $(PLATFORMSRC) \ 85 | $(BOARDSRC) \ 86 | $(CHIBIOS)/os/various/shell.c \ 87 | $(CHIBIOS)/os/various/chprintf.c \ 88 | main.c \ 89 | myPWM.c \ 90 | myADC.c \ 91 | myUSB.c \ 92 | myMisc.c 93 | 94 | # C++ sources that can be compiled in ARM or THUMB mode depending on the global 95 | # setting. 96 | CPPSRC = 97 | 98 | # C sources to be compiled in ARM mode regardless of the global setting. 99 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 100 | # option that results in lower performance and larger code size. 101 | ACSRC = 102 | 103 | # C++ sources to be compiled in ARM mode regardless of the global setting. 104 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 105 | # option that results in lower performance and larger code size. 106 | ACPPSRC = 107 | 108 | # C sources to be compiled in THUMB mode regardless of the global setting. 109 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 110 | # option that results in lower performance and larger code size. 111 | TCSRC = 112 | 113 | # C sources to be compiled in THUMB mode regardless of the global setting. 114 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 115 | # option that results in lower performance and larger code size. 116 | TCPPSRC = 117 | 118 | # List ASM source files here 119 | ASMSRC = $(PORTASM) 120 | 121 | INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \ 122 | $(HALINC) $(PLATFORMINC) $(BOARDINC) \ 123 | $(CHIBIOS)/os/various 124 | 125 | # 126 | # Project, sources and paths 127 | ############################################################################## 128 | 129 | ############################################################################## 130 | # Compiler settings 131 | # 132 | 133 | MCU = cortex-m4 134 | 135 | #TRGT = arm-elf- 136 | TRGT = arm-none-eabi- 137 | CC = $(TRGT)gcc 138 | CPPC = $(TRGT)g++ 139 | # Enable loading with g++ only if you need C++ runtime support. 140 | # NOTE: You can use C++ even without C++ support if you are careful. C++ 141 | # runtime support makes code size explode. 142 | LD = $(TRGT)gcc 143 | #LD = $(TRGT)g++ 144 | CP = $(TRGT)objcopy 145 | AS = $(TRGT)gcc -x assembler-with-cpp 146 | OD = $(TRGT)objdump 147 | HEX = $(CP) -O ihex 148 | BIN = $(CP) -O binary 149 | 150 | # ARM-specific options here 151 | AOPT = 152 | 153 | # THUMB-specific options here 154 | TOPT = -mthumb -DTHUMB 155 | 156 | # Define C warning options here 157 | CWARN = -Wall -Wextra -Wstrict-prototypes 158 | 159 | # Define C++ warning options here 160 | CPPWARN = -Wall -Wextra 161 | 162 | # 163 | # Compiler settings 164 | ############################################################################## 165 | 166 | ############################################################################## 167 | # Start of default section 168 | # 169 | 170 | # List all default C defines here, like -D_DEBUG=1 171 | DDEFS = 172 | 173 | # List all default ASM defines here, like -D_DEBUG=1 174 | DADEFS = 175 | 176 | # List all default directories to look for include files here 177 | DINCDIR = 178 | 179 | # List the default directory to look for the libraries here 180 | DLIBDIR = 181 | 182 | # List all default libraries here 183 | DLIBS = 184 | 185 | # 186 | # End of default section 187 | ############################################################################## 188 | 189 | ############################################################################## 190 | # Start of user section 191 | # 192 | 193 | # List all user C define here, like -D_DEBUG=1 194 | UDEFS = 195 | 196 | # Define ASM defines here 197 | UADEFS = 198 | 199 | # List all user directories here 200 | UINCDIR = 201 | 202 | # List the user directory to look for the libraries here 203 | ULIBDIR = 204 | 205 | # List all user libraries here 206 | ULIBS = 207 | 208 | # 209 | # End of user defines 210 | ############################################################################## 211 | 212 | ifeq ($(USE_FPU),yes) 213 | USE_OPT += -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant 214 | DDEFS += -DCORTEX_USE_FPU=TRUE 215 | else 216 | DDEFS += -DCORTEX_USE_FPU=FALSE 217 | endif 218 | 219 | ifeq ($(USE_FWLIB),yes) 220 | include $(CHIBIOS)/ext/stm32lib/stm32lib.mk 221 | CSRC += $(STM32SRC) 222 | INCDIR += $(STM32INC) 223 | USE_OPT += -DUSE_STDPERIPH_DRIVER 224 | endif 225 | 226 | include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk 227 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | STM32F4-Discovery-example-code 2 | ============================== 3 | 4 | This is my example code for the STM32F4 Discovers using the RTOS ChibiOS. 5 | 6 | requirements 7 | ------------ 8 | * Chibios 2.5.0+ (or a recent development snapshot) 9 | * arm toolchain (e.g. arm-none-eabi from summon-arm) 10 | 11 | features 12 | -------- 13 | * serial over USB console 14 | * PWM initialization and control 15 | * ADC measuring, continuous and single scan 16 | * background blinker thread 17 | * code structured into separate files 18 | 19 | usage 20 | ----- 21 | * edit the Makefile and point "CHIBIOS = ../../chibios" to your ChibiOS folder 22 | * make 23 | * connect the STM32F4 Discovery with both USB connectors 24 | * flash the STM32F4: st-flash write build/ch.bin 0x8000000 25 | * use your favorite terminal programm to connect to the Serial Port (/dev/ttyACM0 for me, probably COM1 on Windows) 26 | 27 | console commands 28 | ---------------- 29 | * help 30 | * exit 31 | * info 32 | * systime 33 | * mem 34 | * threads 35 | * toggle 1/2/3/4 (toggles #led, short: t) 36 | * blinkspeed #speed (changes blinker period to #speed ms, short: bs) 37 | * cycle #duty (changes the duty cycle of PWM1 to #duty, short: c) 38 | * ramp #from #to #step \[delay\] (creates a ramp for PWM1 with the given parameters, short: r) 39 | * measure (measures 16384 analog samples on pin PC1 and prints the first and the average, short: m) 40 | * measureAnalog (measures 16384 samples and converts the average to Volts, short: ma) 41 | * measureDirect (measures 16384 samples and prints them all, short: md) 42 | * measureContinuous (starts a background analog conversion, short: mc) 43 | * readContinuousData (prints what has been collected by the background conversion, short: rd) 44 | * stopContinuous (stops the analog conversion, short sc) 45 | 46 | 47 | 48 | 49 | 50 | disclaimer 51 | ---------- 52 | Neither am I a good C programmer nor do I have extensive knowledge about 53 | ChibiOS, the STM32F4 or uCs in general. I wrote this code to make myself 54 | familiar with the STM32F4 Discovery and I figured ChibiOS was a usefull tool. 55 | From my POV the code is not that bad, but your opinion may differ. In 56 | that case, please don't laugh at my code but provide constructive criticism. 57 | I just realized: I'm no pro at Git, Github and Markdown either... 58 | 59 | Since I started from the USB-CDC code example from ChibiOS which is GPLv3, 60 | I think I am forced to release this code under GPLv3 though I don't care what you do 61 | with the code. I asked Giovanni and he said "there is not much meat" in it anyways. 62 | 63 | -------------------------------------------------------------------------------- /chconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 3 | 2011,2012 Giovanni Di Sirio. 4 | 5 | This file is part of ChibiOS/RT. 6 | 7 | ChibiOS/RT is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | ChibiOS/RT is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | /** 22 | * @file templates/chconf.h 23 | * @brief Configuration file template. 24 | * @details A copy of this file must be placed in each project directory, it 25 | * contains the application specific kernel settings. 26 | * 27 | * @addtogroup config 28 | * @details Kernel related settings and hooks. 29 | * @{ 30 | */ 31 | 32 | #ifndef _CHCONF_H_ 33 | #define _CHCONF_H_ 34 | 35 | /*===========================================================================*/ 36 | /** 37 | * @name Kernel parameters and options 38 | * @{ 39 | */ 40 | /*===========================================================================*/ 41 | 42 | /** 43 | * @brief System tick frequency. 44 | * @details Frequency of the system timer that drives the system ticks. This 45 | * setting also defines the system tick time unit. 46 | */ 47 | #if !defined(CH_FREQUENCY) || defined(__DOXYGEN__) 48 | #define CH_FREQUENCY 1000 49 | #endif 50 | 51 | /** 52 | * @brief Round robin interval. 53 | * @details This constant is the number of system ticks allowed for the 54 | * threads before preemption occurs. Setting this value to zero 55 | * disables the preemption for threads with equal priority and the 56 | * round robin becomes cooperative. Note that higher priority 57 | * threads can still preempt, the kernel is always preemptive. 58 | * 59 | * @note Disabling the round robin preemption makes the kernel more compact 60 | * and generally faster. 61 | */ 62 | #if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__) 63 | #define CH_TIME_QUANTUM 20 64 | #endif 65 | 66 | /** 67 | * @brief Managed RAM size. 68 | * @details Size of the RAM area to be managed by the OS. If set to zero 69 | * then the whole available RAM is used. The core memory is made 70 | * available to the heap allocator and/or can be used directly through 71 | * the simplified core memory allocator. 72 | * 73 | * @note In order to let the OS manage the whole RAM the linker script must 74 | * provide the @p __heap_base__ and @p __heap_end__ symbols. 75 | * @note Requires @p CH_USE_MEMCORE. 76 | */ 77 | #if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__) 78 | #define CH_MEMCORE_SIZE 0 79 | #endif 80 | 81 | /** 82 | * @brief Idle thread automatic spawn suppression. 83 | * @details When this option is activated the function @p chSysInit() 84 | * does not spawn the idle thread automatically. The application has 85 | * then the responsibility to do one of the following: 86 | * - Spawn a custom idle thread at priority @p IDLEPRIO. 87 | * - Change the main() thread priority to @p IDLEPRIO then enter 88 | * an endless loop. In this scenario the @p main() thread acts as 89 | * the idle thread. 90 | * . 91 | * @note Unless an idle thread is spawned the @p main() thread must not 92 | * enter a sleep state. 93 | */ 94 | #if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__) 95 | #define CH_NO_IDLE_THREAD FALSE 96 | #endif 97 | 98 | /** @} */ 99 | 100 | /*===========================================================================*/ 101 | /** 102 | * @name Performance options 103 | * @{ 104 | */ 105 | /*===========================================================================*/ 106 | 107 | /** 108 | * @brief OS optimization. 109 | * @details If enabled then time efficient rather than space efficient code 110 | * is used when two possible implementations exist. 111 | * 112 | * @note This is not related to the compiler optimization options. 113 | * @note The default is @p TRUE. 114 | */ 115 | #if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__) 116 | #define CH_OPTIMIZE_SPEED TRUE 117 | #endif 118 | 119 | /** @} */ 120 | 121 | /*===========================================================================*/ 122 | /** 123 | * @name Subsystem options 124 | * @{ 125 | */ 126 | /*===========================================================================*/ 127 | 128 | /** 129 | * @brief Threads registry APIs. 130 | * @details If enabled then the registry APIs are included in the kernel. 131 | * 132 | * @note The default is @p TRUE. 133 | */ 134 | #if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__) 135 | #define CH_USE_REGISTRY TRUE 136 | #endif 137 | 138 | /** 139 | * @brief Threads synchronization APIs. 140 | * @details If enabled then the @p chThdWait() function is included in 141 | * the kernel. 142 | * 143 | * @note The default is @p TRUE. 144 | */ 145 | #if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__) 146 | #define CH_USE_WAITEXIT TRUE 147 | #endif 148 | 149 | /** 150 | * @brief Semaphores APIs. 151 | * @details If enabled then the Semaphores APIs are included in the kernel. 152 | * 153 | * @note The default is @p TRUE. 154 | */ 155 | #if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__) 156 | #define CH_USE_SEMAPHORES TRUE 157 | #endif 158 | 159 | /** 160 | * @brief Semaphores queuing mode. 161 | * @details If enabled then the threads are enqueued on semaphores by 162 | * priority rather than in FIFO order. 163 | * 164 | * @note The default is @p FALSE. Enable this if you have special requirements. 165 | * @note Requires @p CH_USE_SEMAPHORES. 166 | */ 167 | #if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__) 168 | #define CH_USE_SEMAPHORES_PRIORITY FALSE 169 | #endif 170 | 171 | /** 172 | * @brief Atomic semaphore API. 173 | * @details If enabled then the semaphores the @p chSemSignalWait() API 174 | * is included in the kernel. 175 | * 176 | * @note The default is @p TRUE. 177 | * @note Requires @p CH_USE_SEMAPHORES. 178 | */ 179 | #if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__) 180 | #define CH_USE_SEMSW TRUE 181 | #endif 182 | 183 | /** 184 | * @brief Mutexes APIs. 185 | * @details If enabled then the mutexes APIs are included in the kernel. 186 | * 187 | * @note The default is @p TRUE. 188 | */ 189 | #if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__) 190 | #define CH_USE_MUTEXES TRUE 191 | #endif 192 | 193 | /** 194 | * @brief Conditional Variables APIs. 195 | * @details If enabled then the conditional variables APIs are included 196 | * in the kernel. 197 | * 198 | * @note The default is @p TRUE. 199 | * @note Requires @p CH_USE_MUTEXES. 200 | */ 201 | #if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__) 202 | #define CH_USE_CONDVARS TRUE 203 | #endif 204 | 205 | /** 206 | * @brief Conditional Variables APIs with timeout. 207 | * @details If enabled then the conditional variables APIs with timeout 208 | * specification are included in the kernel. 209 | * 210 | * @note The default is @p TRUE. 211 | * @note Requires @p CH_USE_CONDVARS. 212 | */ 213 | #if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__) 214 | #define CH_USE_CONDVARS_TIMEOUT TRUE 215 | #endif 216 | 217 | /** 218 | * @brief Events Flags APIs. 219 | * @details If enabled then the event flags APIs are included in the kernel. 220 | * 221 | * @note The default is @p TRUE. 222 | */ 223 | #if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__) 224 | #define CH_USE_EVENTS TRUE 225 | #endif 226 | 227 | /** 228 | * @brief Events Flags APIs with timeout. 229 | * @details If enabled then the events APIs with timeout specification 230 | * are included in the kernel. 231 | * 232 | * @note The default is @p TRUE. 233 | * @note Requires @p CH_USE_EVENTS. 234 | */ 235 | #if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__) 236 | #define CH_USE_EVENTS_TIMEOUT TRUE 237 | #endif 238 | 239 | /** 240 | * @brief Synchronous Messages APIs. 241 | * @details If enabled then the synchronous messages APIs are included 242 | * in the kernel. 243 | * 244 | * @note The default is @p TRUE. 245 | */ 246 | #if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__) 247 | #define CH_USE_MESSAGES TRUE 248 | #endif 249 | 250 | /** 251 | * @brief Synchronous Messages queuing mode. 252 | * @details If enabled then messages are served by priority rather than in 253 | * FIFO order. 254 | * 255 | * @note The default is @p FALSE. Enable this if you have special requirements. 256 | * @note Requires @p CH_USE_MESSAGES. 257 | */ 258 | #if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__) 259 | #define CH_USE_MESSAGES_PRIORITY FALSE 260 | #endif 261 | 262 | /** 263 | * @brief Mailboxes APIs. 264 | * @details If enabled then the asynchronous messages (mailboxes) APIs are 265 | * included in the kernel. 266 | * 267 | * @note The default is @p TRUE. 268 | * @note Requires @p CH_USE_SEMAPHORES. 269 | */ 270 | #if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__) 271 | #define CH_USE_MAILBOXES TRUE 272 | #endif 273 | 274 | /** 275 | * @brief I/O Queues APIs. 276 | * @details If enabled then the I/O queues APIs are included in the kernel. 277 | * 278 | * @note The default is @p TRUE. 279 | */ 280 | #if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__) 281 | #define CH_USE_QUEUES TRUE 282 | #endif 283 | 284 | /** 285 | * @brief Core Memory Manager APIs. 286 | * @details If enabled then the core memory manager APIs are included 287 | * in the kernel. 288 | * 289 | * @note The default is @p TRUE. 290 | */ 291 | #if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__) 292 | #define CH_USE_MEMCORE TRUE 293 | #endif 294 | 295 | /** 296 | * @brief Heap Allocator APIs. 297 | * @details If enabled then the memory heap allocator APIs are included 298 | * in the kernel. 299 | * 300 | * @note The default is @p TRUE. 301 | * @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or 302 | * @p CH_USE_SEMAPHORES. 303 | * @note Mutexes are recommended. 304 | */ 305 | #if !defined(CH_USE_HEAP) || defined(__DOXYGEN__) 306 | #define CH_USE_HEAP TRUE 307 | #endif 308 | 309 | /** 310 | * @brief C-runtime allocator. 311 | * @details If enabled the the heap allocator APIs just wrap the C-runtime 312 | * @p malloc() and @p free() functions. 313 | * 314 | * @note The default is @p FALSE. 315 | * @note Requires @p CH_USE_HEAP. 316 | * @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the 317 | * appropriate documentation. 318 | */ 319 | #if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__) 320 | #define CH_USE_MALLOC_HEAP FALSE 321 | #endif 322 | 323 | /** 324 | * @brief Memory Pools Allocator APIs. 325 | * @details If enabled then the memory pools allocator APIs are included 326 | * in the kernel. 327 | * 328 | * @note The default is @p TRUE. 329 | */ 330 | #if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__) 331 | #define CH_USE_MEMPOOLS TRUE 332 | #endif 333 | 334 | /** 335 | * @brief Dynamic Threads APIs. 336 | * @details If enabled then the dynamic threads creation APIs are included 337 | * in the kernel. 338 | * 339 | * @note The default is @p TRUE. 340 | * @note Requires @p CH_USE_WAITEXIT. 341 | * @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS. 342 | */ 343 | #if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__) 344 | #define CH_USE_DYNAMIC TRUE 345 | #endif 346 | 347 | /** @} */ 348 | 349 | /*===========================================================================*/ 350 | /** 351 | * @name Debug options 352 | * @{ 353 | */ 354 | /*===========================================================================*/ 355 | 356 | /** 357 | * @brief Debug option, system state check. 358 | * @details If enabled the correct call protocol for system APIs is checked 359 | * at runtime. 360 | * 361 | * @note The default is @p FALSE. 362 | */ 363 | #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) 364 | #define CH_DBG_SYSTEM_STATE_CHECK TRUE 365 | #endif 366 | 367 | /** 368 | * @brief Debug option, parameters checks. 369 | * @details If enabled then the checks on the API functions input 370 | * parameters are activated. 371 | * 372 | * @note The default is @p FALSE. 373 | */ 374 | #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) 375 | #define CH_DBG_ENABLE_CHECKS TRUE 376 | #endif 377 | 378 | /** 379 | * @brief Debug option, consistency checks. 380 | * @details If enabled then all the assertions in the kernel code are 381 | * activated. This includes consistency checks inside the kernel, 382 | * runtime anomalies and port-defined checks. 383 | * 384 | * @note The default is @p FALSE. 385 | */ 386 | #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) 387 | #define CH_DBG_ENABLE_ASSERTS TRUE 388 | #endif 389 | 390 | /** 391 | * @brief Debug option, trace buffer. 392 | * @details If enabled then the context switch circular trace buffer is 393 | * activated. 394 | * 395 | * @note The default is @p FALSE. 396 | */ 397 | #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) 398 | #define CH_DBG_ENABLE_TRACE TRUE 399 | #endif 400 | 401 | /** 402 | * @brief Debug option, stack checks. 403 | * @details If enabled then a runtime stack check is performed. 404 | * 405 | * @note The default is @p FALSE. 406 | * @note The stack check is performed in a architecture/port dependent way. 407 | * It may not be implemented or some ports. 408 | * @note The default failure mode is to halt the system with the global 409 | * @p panic_msg variable set to @p NULL. 410 | */ 411 | #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) 412 | #define CH_DBG_ENABLE_STACK_CHECK TRUE 413 | #endif 414 | 415 | /** 416 | * @brief Debug option, stacks initialization. 417 | * @details If enabled then the threads working area is filled with a byte 418 | * value when a thread is created. This can be useful for the 419 | * runtime measurement of the used stack. 420 | * 421 | * @note The default is @p FALSE. 422 | */ 423 | #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) 424 | #define CH_DBG_FILL_THREADS TRUE 425 | #endif 426 | 427 | /** 428 | * @brief Debug option, threads profiling. 429 | * @details If enabled then a field is added to the @p Thread structure that 430 | * counts the system ticks occurred while executing the thread. 431 | * 432 | * @note The default is @p TRUE. 433 | * @note This debug option is defaulted to TRUE because it is required by 434 | * some test cases into the test suite. 435 | */ 436 | #if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__) 437 | #define CH_DBG_THREADS_PROFILING TRUE 438 | #endif 439 | 440 | /** @} */ 441 | 442 | /*===========================================================================*/ 443 | /** 444 | * @name Kernel hooks 445 | * @{ 446 | */ 447 | /*===========================================================================*/ 448 | 449 | /** 450 | * @brief Threads descriptor structure extension. 451 | * @details User fields added to the end of the @p Thread structure. 452 | */ 453 | #if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__) 454 | #define THREAD_EXT_FIELDS \ 455 | /* Add threads custom fields here.*/ 456 | #endif 457 | 458 | /** 459 | * @brief Threads initialization hook. 460 | * @details User initialization code added to the @p chThdInit() API. 461 | * 462 | * @note It is invoked from within @p chThdInit() and implicitly from all 463 | * the threads creation APIs. 464 | */ 465 | #if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__) 466 | #define THREAD_EXT_INIT_HOOK(tp) { \ 467 | /* Add threads initialization code here.*/ \ 468 | } 469 | #endif 470 | 471 | /** 472 | * @brief Threads finalization hook. 473 | * @details User finalization code added to the @p chThdExit() API. 474 | * 475 | * @note It is inserted into lock zone. 476 | * @note It is also invoked when the threads simply return in order to 477 | * terminate. 478 | */ 479 | #if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__) 480 | #define THREAD_EXT_EXIT_HOOK(tp) { \ 481 | /* Add threads finalization code here.*/ \ 482 | } 483 | #endif 484 | 485 | /** 486 | * @brief Context switch hook. 487 | * @details This hook is invoked just before switching between threads. 488 | */ 489 | #if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__) 490 | #define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \ 491 | /* System halt code here.*/ \ 492 | } 493 | #endif 494 | 495 | /** 496 | * @brief Idle Loop hook. 497 | * @details This hook is continuously invoked by the idle thread loop. 498 | */ 499 | #if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__) 500 | #define IDLE_LOOP_HOOK() { \ 501 | /* Idle loop code here.*/ \ 502 | } 503 | #endif 504 | 505 | /** 506 | * @brief System tick event hook. 507 | * @details This hook is invoked in the system tick handler immediately 508 | * after processing the virtual timers queue. 509 | */ 510 | #if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__) 511 | #define SYSTEM_TICK_EVENT_HOOK() { \ 512 | /* System tick event code here.*/ \ 513 | } 514 | #endif 515 | 516 | /** 517 | * @brief System halt hook. 518 | * @details This hook is invoked in case to a system halting error before 519 | * the system is halted. 520 | */ 521 | #if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__) 522 | #define SYSTEM_HALT_HOOK() { \ 523 | /* System halt code here.*/ \ 524 | } 525 | #endif 526 | 527 | /** @} */ 528 | 529 | /*===========================================================================*/ 530 | /* Port-specific settings (override port settings defaulted in chcore.h). */ 531 | /*===========================================================================*/ 532 | 533 | #endif /* _CHCONF_H_ */ 534 | 535 | /** @} */ 536 | -------------------------------------------------------------------------------- /halconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 3 | 2011,2012 Giovanni Di Sirio. 4 | 5 | This file is part of ChibiOS/RT. 6 | 7 | ChibiOS/RT is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | ChibiOS/RT is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | /** 22 | * @file templates/halconf.h 23 | * @brief HAL configuration header. 24 | * @details HAL configuration file, this file allows to enable or disable the 25 | * various device drivers from your application. You may also use 26 | * this file in order to override the device drivers default settings. 27 | * 28 | * @addtogroup HAL_CONF 29 | * @{ 30 | */ 31 | 32 | #ifndef _HALCONF_H_ 33 | #define _HALCONF_H_ 34 | 35 | #include "mcuconf.h" 36 | 37 | /** 38 | * @brief Enables the TM subsystem. 39 | */ 40 | #if !defined(HAL_USE_TM) || defined(__DOXYGEN__) 41 | #define HAL_USE_TM TRUE 42 | #endif 43 | 44 | /** 45 | * @brief Enables the PAL subsystem. 46 | */ 47 | #if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) 48 | #define HAL_USE_PAL TRUE 49 | #endif 50 | 51 | /** 52 | * @brief Enables the ADC subsystem. 53 | */ 54 | #if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) 55 | #define HAL_USE_ADC TRUE 56 | #endif 57 | 58 | /** 59 | * @brief Enables the CAN subsystem. 60 | */ 61 | #if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) 62 | #define HAL_USE_CAN FALSE 63 | #endif 64 | 65 | /** 66 | * @brief Enables the EXT subsystem. 67 | */ 68 | #if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) 69 | #define HAL_USE_EXT FALSE 70 | #endif 71 | 72 | /** 73 | * @brief Enables the GPT subsystem. 74 | */ 75 | #if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) 76 | #define HAL_USE_GPT FALSE 77 | #endif 78 | 79 | /** 80 | * @brief Enables the I2C subsystem. 81 | */ 82 | #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) 83 | #define HAL_USE_I2C FALSE 84 | #endif 85 | 86 | /** 87 | * @brief Enables the ICU subsystem. 88 | */ 89 | #if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) 90 | #define HAL_USE_ICU TRUE 91 | #endif 92 | 93 | /** 94 | * @brief Enables the MAC subsystem. 95 | */ 96 | #if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) 97 | #define HAL_USE_MAC FALSE 98 | #endif 99 | 100 | /** 101 | * @brief Enables the MMC_SPI subsystem. 102 | */ 103 | #if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) 104 | #define HAL_USE_MMC_SPI FALSE 105 | #endif 106 | 107 | /** 108 | * @brief Enables the PWM subsystem. 109 | */ 110 | #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) 111 | #define HAL_USE_PWM TRUE 112 | #endif 113 | 114 | /** 115 | * @brief Enables the RTC subsystem. 116 | */ 117 | #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) 118 | #define HAL_USE_RTC FALSE 119 | #endif 120 | 121 | /** 122 | * @brief Enables the SDC subsystem. 123 | */ 124 | #if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) 125 | #define HAL_USE_SDC FALSE 126 | #endif 127 | 128 | /** 129 | * @brief Enables the SERIAL subsystem. 130 | */ 131 | #if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) 132 | #define HAL_USE_SERIAL FALSE 133 | #endif 134 | 135 | /** 136 | * @brief Enables the SERIAL over USB subsystem. 137 | */ 138 | #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 139 | #define HAL_USE_SERIAL_USB TRUE 140 | #endif 141 | 142 | /** 143 | * @brief Enables the SPI subsystem. 144 | */ 145 | #if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) 146 | #define HAL_USE_SPI FALSE 147 | #endif 148 | 149 | /** 150 | * @brief Enables the UART subsystem. 151 | */ 152 | #if !defined(HAL_USE_UART) || defined(__DOXYGEN__) 153 | #define HAL_USE_UART FALSE 154 | #endif 155 | 156 | /** 157 | * @brief Enables the USB subsystem. 158 | */ 159 | #if !defined(HAL_USE_USB) || defined(__DOXYGEN__) 160 | #define HAL_USE_USB TRUE 161 | #endif 162 | 163 | /*===========================================================================*/ 164 | /* ADC driver related settings. */ 165 | /*===========================================================================*/ 166 | 167 | /** 168 | * @brief Enables synchronous APIs. 169 | * @note Disabling this option saves both code and data space. 170 | */ 171 | #if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) 172 | #define ADC_USE_WAIT TRUE 173 | #endif 174 | 175 | /** 176 | * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. 177 | * @note Disabling this option saves both code and data space. 178 | */ 179 | #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) 180 | #define ADC_USE_MUTUAL_EXCLUSION TRUE 181 | #endif 182 | 183 | /*===========================================================================*/ 184 | /* CAN driver related settings. */ 185 | /*===========================================================================*/ 186 | 187 | /** 188 | * @brief Sleep mode related APIs inclusion switch. 189 | */ 190 | #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) 191 | #define CAN_USE_SLEEP_MODE TRUE 192 | #endif 193 | 194 | /*===========================================================================*/ 195 | /* I2C driver related settings. */ 196 | /*===========================================================================*/ 197 | 198 | /** 199 | * @brief Enables the mutual exclusion APIs on the I2C bus. 200 | */ 201 | #if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) 202 | #define I2C_USE_MUTUAL_EXCLUSION TRUE 203 | #endif 204 | 205 | /*===========================================================================*/ 206 | /* MAC driver related settings. */ 207 | /*===========================================================================*/ 208 | 209 | /** 210 | * @brief Enables an event sources for incoming packets. 211 | */ 212 | #if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) 213 | #define MAC_USE_EVENTS TRUE 214 | #endif 215 | 216 | /*===========================================================================*/ 217 | /* MMC_SPI driver related settings. */ 218 | /*===========================================================================*/ 219 | 220 | /** 221 | * @brief Block size for MMC transfers. 222 | */ 223 | #if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__) 224 | #define MMC_SECTOR_SIZE 512 225 | #endif 226 | 227 | /** 228 | * @brief Delays insertions. 229 | * @details If enabled this options inserts delays into the MMC waiting 230 | * routines releasing some extra CPU time for the threads with 231 | * lower priority, this may slow down the driver a bit however. 232 | * This option is recommended also if the SPI driver does not 233 | * use a DMA channel and heavily loads the CPU. 234 | */ 235 | #if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) 236 | #define MMC_NICE_WAITING TRUE 237 | #endif 238 | 239 | /** 240 | * @brief Number of positive insertion queries before generating the 241 | * insertion event. 242 | */ 243 | #if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__) 244 | #define MMC_POLLING_INTERVAL 10 245 | #endif 246 | 247 | /** 248 | * @brief Interval, in milliseconds, between insertion queries. 249 | */ 250 | #if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__) 251 | #define MMC_POLLING_DELAY 10 252 | #endif 253 | 254 | /** 255 | * @brief Uses the SPI polled API for small data transfers. 256 | * @details Polled transfers usually improve performance because it 257 | * saves two context switches and interrupt servicing. Note 258 | * that this option has no effect on large transfers which 259 | * are always performed using DMAs/IRQs. 260 | */ 261 | #if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__) 262 | #define MMC_USE_SPI_POLLING TRUE 263 | #endif 264 | 265 | /*===========================================================================*/ 266 | /* SDC driver related settings. */ 267 | /*===========================================================================*/ 268 | 269 | /** 270 | * @brief Number of initialization attempts before rejecting the card. 271 | * @note Attempts are performed at 10mS intervals. 272 | */ 273 | #if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) 274 | #define SDC_INIT_RETRY 100 275 | #endif 276 | 277 | /** 278 | * @brief Include support for MMC cards. 279 | * @note MMC support is not yet implemented so this option must be kept 280 | * at @p FALSE. 281 | */ 282 | #if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) 283 | #define SDC_MMC_SUPPORT FALSE 284 | #endif 285 | 286 | /** 287 | * @brief Delays insertions. 288 | * @details If enabled this options inserts delays into the MMC waiting 289 | * routines releasing some extra CPU time for the threads with 290 | * lower priority, this may slow down the driver a bit however. 291 | */ 292 | #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) 293 | #define SDC_NICE_WAITING TRUE 294 | #endif 295 | 296 | /*===========================================================================*/ 297 | /* SERIAL driver related settings. */ 298 | /*===========================================================================*/ 299 | 300 | /** 301 | * @brief Default bit rate. 302 | * @details Configuration parameter, this is the baud rate selected for the 303 | * default configuration. 304 | */ 305 | #if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) 306 | #define SERIAL_DEFAULT_BITRATE 38400 307 | #endif 308 | 309 | /** 310 | * @brief Serial buffers size. 311 | * @details Configuration parameter, you can change the depth of the queue 312 | * buffers depending on the requirements of your application. 313 | * @note The default is 64 bytes for both the transmission and receive 314 | * buffers. 315 | */ 316 | #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) 317 | #define SERIAL_BUFFERS_SIZE 16 318 | #endif 319 | 320 | /*===========================================================================*/ 321 | /* SPI driver related settings. */ 322 | /*===========================================================================*/ 323 | 324 | /** 325 | * @brief Enables synchronous APIs. 326 | * @note Disabling this option saves both code and data space. 327 | */ 328 | #if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) 329 | #define SPI_USE_WAIT TRUE 330 | #endif 331 | 332 | /** 333 | * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. 334 | * @note Disabling this option saves both code and data space. 335 | */ 336 | #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) 337 | #define SPI_USE_MUTUAL_EXCLUSION TRUE 338 | #endif 339 | 340 | #endif /* _HALCONF_H_ */ 341 | 342 | /** @} */ 343 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 3 | 2011,2012 Giovanni Di Sirio. 4 | 5 | This file is part of ChibiOS/RT. 6 | 7 | ChibiOS/RT is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | ChibiOS/RT is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "ch.h" 26 | #include "hal.h" 27 | 28 | #include "shell.h" 29 | #include "chprintf.h" 30 | 31 | #include "myPWM.h" 32 | #include "myADC.h" 33 | #include "myUSB.h" 34 | #include "myMisc.h" 35 | 36 | 37 | 38 | 39 | /* 40 | * assert Shell Commands to functions 41 | */ 42 | 43 | static const ShellCommand commands[] = { 44 | {"mem", cmd_mem}, 45 | {"threads", cmd_threads}, 46 | {"toggle", cmd_toggle}, 47 | {"t", cmd_toggle}, 48 | {"blinkspeed", cmd_blinkspeed}, 49 | {"bs", cmd_blinkspeed}, 50 | {"cycle", cmd_cycle}, 51 | {"c", cmd_cycle}, 52 | {"ramp", cmd_ramp}, 53 | {"r", cmd_ramp}, 54 | {"measure", cmd_measure}, 55 | {"m", cmd_measure}, 56 | {"measureAnalog", cmd_measureA}, 57 | {"ma", cmd_measureA}, 58 | {"vref", cmd_Vref}, 59 | {"v", cmd_Vref}, 60 | {"temperature", cmd_Temperature}, 61 | {"te", cmd_Temperature}, 62 | {"measureDirect", cmd_measureDirect}, 63 | {"md", cmd_measureDirect}, 64 | {"measureContinuous", cmd_measureCont}, 65 | {"mc", cmd_measureCont}, 66 | {"readContinuousData", cmd_measureRead}, 67 | {"rd", cmd_measureRead}, 68 | {"stopContinuous", cmd_measureStop}, 69 | {"sc", cmd_measureStop}, 70 | {NULL, NULL} 71 | }; 72 | 73 | 74 | /* 75 | * Shell configuration 76 | */ 77 | 78 | #define SHELL_WA_SIZE THD_WA_SIZE(2048) 79 | 80 | static const ShellConfig shell_cfg1 = { 81 | (BaseSequentialStream *)&SDU1, 82 | commands 83 | }; 84 | 85 | 86 | /* 87 | * Application entry point. 88 | */ 89 | int main(void) { 90 | /* 91 | * Shell thread 92 | */ 93 | Thread *shelltp = NULL; 94 | 95 | /* 96 | * System initializations. 97 | * - HAL initialization, this also initializes the configured device drivers 98 | * and performs the board-specific initializations. 99 | * - Kernel initialization, the main() function becomes a thread and the 100 | * RTOS is active. 101 | */ 102 | halInit(); 103 | chSysInit(); 104 | 105 | /* 106 | * Activate custom stuff 107 | */ 108 | mypwmInit(); 109 | myADCinit(); 110 | 111 | /* 112 | * Creates the blinker thread. 113 | */ 114 | startBlinker(); 115 | 116 | /* 117 | * Activates the USB driver and then the USB bus pull-up on D+. 118 | */ 119 | myUSBinit(); 120 | 121 | 122 | /* 123 | * Main loop, does nothing except spawn a shell when the old one was terminated 124 | */ 125 | while (TRUE) { 126 | if (!shelltp && isUsbActive()) 127 | { 128 | shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO); 129 | } 130 | else if (chThdTerminated(shelltp)) { 131 | chThdRelease(shelltp); /* Recovers memory of the previous shell. */ 132 | shelltp = NULL; /* Triggers spawning of a new shell. */ 133 | } 134 | chThdSleepMilliseconds(1000); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /mcuconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 3 | 2011,2012 Giovanni Di Sirio. 4 | 5 | This file is part of ChibiOS/RT. 6 | 7 | ChibiOS/RT is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | ChibiOS/RT is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | /* 22 | * STM32F4xx drivers configuration. 23 | * The following settings override the default settings present in 24 | * the various device driver implementation headers. 25 | * Note that the settings for each driver only have effect if the whole 26 | * driver is enabled in halconf.h. 27 | * 28 | * IRQ priorities: 29 | * 15...0 Lowest...Highest. 30 | * 31 | * DMA priorities: 32 | * 0...3 Lowest...Highest. 33 | */ 34 | 35 | /* 36 | * HAL driver system settings. 37 | */ 38 | #define STM32_NO_INIT FALSE 39 | #define STM32_HSI_ENABLED TRUE 40 | #define STM32_LSI_ENABLED TRUE 41 | #define STM32_HSE_ENABLED TRUE 42 | #define STM32_LSE_ENABLED FALSE 43 | #define STM32_CLOCK48_REQUIRED TRUE 44 | #define STM32_SW STM32_SW_PLL 45 | #define STM32_PLLSRC STM32_PLLSRC_HSE 46 | #define STM32_PLLM_VALUE 8 47 | #define STM32_PLLN_VALUE 336 48 | #define STM32_PLLP_VALUE 2 49 | #define STM32_PLLQ_VALUE 7 50 | #define STM32_HPRE STM32_HPRE_DIV1 51 | #define STM32_PPRE1 STM32_PPRE1_DIV4 52 | #define STM32_PPRE2 STM32_PPRE2_DIV2 53 | #define STM32_RTCSEL STM32_RTCSEL_LSI 54 | #define STM32_RTCPRE_VALUE 8 55 | #define STM32_MCO1SEL STM32_MCO1SEL_HSI 56 | #define STM32_MCO1PRE STM32_MCO1PRE_DIV1 57 | #define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK 58 | #define STM32_MCO2PRE STM32_MCO2PRE_DIV5 59 | #define STM32_I2SSRC STM32_I2SSRC_CKIN 60 | #define STM32_PLLI2SN_VALUE 192 61 | #define STM32_PLLI2SR_VALUE 5 62 | #define STM32_VOS STM32_VOS_HIGH 63 | #define STM32_PVD_ENABLE FALSE 64 | #define STM32_PLS STM32_PLS_LEV0 65 | 66 | /* 67 | * ADC driver system settings. 68 | */ 69 | #define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV4 70 | #define STM32_ADC_USE_ADC1 TRUE 71 | #define STM32_ADC_USE_ADC2 FALSE 72 | #define STM32_ADC_USE_ADC3 FALSE 73 | #define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) 74 | #define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) 75 | #define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) 76 | #define STM32_ADC_ADC1_DMA_PRIORITY 2 77 | #define STM32_ADC_ADC2_DMA_PRIORITY 2 78 | #define STM32_ADC_ADC3_DMA_PRIORITY 2 79 | #define STM32_ADC_IRQ_PRIORITY 5 80 | #define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 81 | #define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5 82 | #define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5 83 | 84 | /* 85 | * CAN driver system settings. 86 | */ 87 | #define STM32_CAN_USE_CAN1 TRUE 88 | #define STM32_CAN_CAN1_IRQ_PRIORITY 11 89 | 90 | /* 91 | * EXT driver system settings. 92 | */ 93 | #define STM32_EXT_EXTI0_IRQ_PRIORITY 6 94 | #define STM32_EXT_EXTI1_IRQ_PRIORITY 6 95 | #define STM32_EXT_EXTI2_IRQ_PRIORITY 6 96 | #define STM32_EXT_EXTI3_IRQ_PRIORITY 6 97 | #define STM32_EXT_EXTI4_IRQ_PRIORITY 6 98 | #define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6 99 | #define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6 100 | #define STM32_EXT_EXTI16_IRQ_PRIORITY 6 101 | #define STM32_EXT_EXTI17_IRQ_PRIORITY 15 102 | #define STM32_EXT_EXTI18_IRQ_PRIORITY 6 103 | #define STM32_EXT_EXTI19_IRQ_PRIORITY 6 104 | #define STM32_EXT_EXTI20_IRQ_PRIORITY 6 105 | #define STM32_EXT_EXTI21_IRQ_PRIORITY 15 106 | #define STM32_EXT_EXTI22_IRQ_PRIORITY 15 107 | 108 | /* 109 | * GPT driver system settings. 110 | */ 111 | #define STM32_GPT_USE_TIM1 TRUE 112 | #define STM32_GPT_USE_TIM2 TRUE 113 | #define STM32_GPT_USE_TIM3 TRUE 114 | #define STM32_GPT_USE_TIM4 TRUE 115 | #define STM32_GPT_USE_TIM5 TRUE 116 | #define STM32_GPT_USE_TIM8 TRUE 117 | #define STM32_GPT_TIM1_IRQ_PRIORITY 7 118 | #define STM32_GPT_TIM2_IRQ_PRIORITY 7 119 | #define STM32_GPT_TIM3_IRQ_PRIORITY 7 120 | #define STM32_GPT_TIM4_IRQ_PRIORITY 7 121 | #define STM32_GPT_TIM5_IRQ_PRIORITY 7 122 | #define STM32_GPT_TIM8_IRQ_PRIORITY 7 123 | 124 | /* 125 | * ICU driver system settings. 126 | */ 127 | #define STM32_ICU_USE_TIM1 FALSE 128 | #define STM32_ICU_USE_TIM2 FALSE 129 | #define STM32_ICU_USE_TIM3 TRUE 130 | #define STM32_ICU_USE_TIM4 FALSE 131 | #define STM32_ICU_USE_TIM5 FALSE 132 | #define STM32_ICU_USE_TIM8 FALSE 133 | #define STM32_ICU_TIM1_IRQ_PRIORITY 7 134 | #define STM32_ICU_TIM2_IRQ_PRIORITY 7 135 | #define STM32_ICU_TIM3_IRQ_PRIORITY 7 136 | #define STM32_ICU_TIM4_IRQ_PRIORITY 7 137 | #define STM32_ICU_TIM5_IRQ_PRIORITY 7 138 | #define STM32_ICU_TIM8_IRQ_PRIORITY 7 139 | 140 | /* 141 | * PWM driver system settings. 142 | */ 143 | #define STM32_PWM_USE_ADVANCED FALSE 144 | #define STM32_PWM_USE_TIM1 FALSE 145 | #define STM32_PWM_USE_TIM2 TRUE 146 | #define STM32_PWM_USE_TIM3 FALSE 147 | #define STM32_PWM_USE_TIM4 FALSE 148 | #define STM32_PWM_USE_TIM5 FALSE 149 | #define STM32_PWM_USE_TIM8 FALSE 150 | #define STM32_PWM_TIM1_IRQ_PRIORITY 7 151 | #define STM32_PWM_TIM2_IRQ_PRIORITY 7 152 | #define STM32_PWM_TIM3_IRQ_PRIORITY 7 153 | #define STM32_PWM_TIM4_IRQ_PRIORITY 7 154 | #define STM32_PWM_TIM5_IRQ_PRIORITY 7 155 | #define STM32_PWM_TIM8_IRQ_PRIORITY 7 156 | 157 | /* 158 | * SERIAL driver system settings. 159 | */ 160 | #define STM32_SERIAL_USE_USART1 FALSE 161 | #define STM32_SERIAL_USE_USART2 TRUE 162 | #define STM32_SERIAL_USE_USART3 FALSE 163 | #define STM32_SERIAL_USE_UART4 FALSE 164 | #define STM32_SERIAL_USE_UART5 FALSE 165 | #define STM32_SERIAL_USE_USART6 FALSE 166 | #define STM32_SERIAL_USART1_PRIORITY 12 167 | #define STM32_SERIAL_USART2_PRIORITY 12 168 | #define STM32_SERIAL_USART3_PRIORITY 12 169 | #define STM32_SERIAL_UART4_PRIORITY 12 170 | #define STM32_SERIAL_UART5_PRIORITY 12 171 | #define STM32_SERIAL_USART6_PRIORITY 12 172 | 173 | /* 174 | * SPI driver system settings. 175 | */ 176 | #define STM32_SPI_USE_SPI1 TRUE 177 | #define STM32_SPI_USE_SPI2 TRUE 178 | #define STM32_SPI_USE_SPI3 TRUE 179 | #define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) 180 | #define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) 181 | #define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 182 | #define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 183 | #define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) 184 | #define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) 185 | #define STM32_SPI_SPI1_DMA_PRIORITY 1 186 | #define STM32_SPI_SPI2_DMA_PRIORITY 1 187 | #define STM32_SPI_SPI3_DMA_PRIORITY 1 188 | #define STM32_SPI_SPI1_IRQ_PRIORITY 10 189 | #define STM32_SPI_SPI2_IRQ_PRIORITY 10 190 | #define STM32_SPI_SPI3_IRQ_PRIORITY 10 191 | #define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt() 192 | 193 | /* 194 | * UART driver system settings. 195 | */ 196 | #define STM32_UART_USE_USART1 FALSE 197 | #define STM32_UART_USE_USART2 TRUE 198 | #define STM32_UART_USE_USART3 FALSE 199 | #define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) 200 | #define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) 201 | #define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 202 | #define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) 203 | #define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) 204 | #define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 205 | #define STM32_UART_USART1_IRQ_PRIORITY 12 206 | #define STM32_UART_USART2_IRQ_PRIORITY 12 207 | #define STM32_UART_USART3_IRQ_PRIORITY 12 208 | #define STM32_UART_USART1_DMA_PRIORITY 0 209 | #define STM32_UART_USART2_DMA_PRIORITY 0 210 | #define STM32_UART_USART3_DMA_PRIORITY 0 211 | #define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt() 212 | 213 | /* 214 | * I2C driver system settings. 215 | */ 216 | #define STM32_I2C_USE_I2C1 FALSE 217 | #define STM32_I2C_USE_I2C2 FALSE 218 | #define STM32_I2C_USE_I2C3 FALSE 219 | #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) 220 | #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) 221 | #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 222 | #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) 223 | #define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 224 | #define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 225 | #define STM32_I2C_I2C1_IRQ_PRIORITY 6 226 | #define STM32_I2C_I2C2_IRQ_PRIORITY 6 227 | #define STM32_I2C_I2C3_IRQ_PRIORITY 6 228 | #define STM32_I2C_I2C1_DMA_PRIORITY 1 229 | #define STM32_I2C_I2C2_DMA_PRIORITY 1 230 | #define STM32_I2C_I2C3_DMA_PRIORITY 1 231 | #define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt() 232 | #define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt() 233 | #define STM32_I2C_I2C3_DMA_ERROR_HOOK() chSysHalt() 234 | 235 | -------------------------------------------------------------------------------- /myADC.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ch.h" 4 | #include "hal.h" 5 | #include "chprintf.h" 6 | 7 | #include "myADC.h" 8 | 9 | 10 | 11 | /* 12 | * Global lock for the ADC. 13 | * I should probably use proper locking mechanisms provided by chibios! 14 | */ 15 | int running=0; 16 | 17 | 18 | /* 19 | * Defines for single scan conversion 20 | */ 21 | #define ADC_GRP1_NUM_CHANNELS 1 22 | #define ADC_GRP1_BUF_DEPTH 2048*2*4 23 | 24 | /* 25 | * Buffer for single conversion 26 | */ 27 | static adcsample_t samples1[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH]; 28 | 29 | /* 30 | * Defines for continuous scan conversions 31 | */ 32 | #define ADC_GRP2_NUM_CHANNELS 10 33 | #define ADC_GRP2_BUF_DEPTH 1024 34 | static adcsample_t samples2[ADC_GRP2_NUM_CHANNELS * ADC_GRP2_BUF_DEPTH]; 35 | 36 | 37 | /* 38 | * Internal Reference Voltage, according to ST this is 1.21V typical 39 | * with -40°C0 ) { 111 | chprintf(chp, "Usage: measure\r\n"); 112 | return; 113 | } 114 | 115 | adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH); 116 | //prints the first measured value 117 | chprintf(chp, "Measured: %d ", samples1[0]*16); 118 | sum=0; 119 | for (i=0;i0 ) { 139 | chprintf(chp, "Usage: measure\r\n"); 140 | return; 141 | } 142 | adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH); 143 | chprintf(chp, "Measured: "); 144 | for (i=0;i0 ) { 163 | chprintf(chp, "Usage: temp\r\n"); 164 | return; 165 | } 166 | if(!running){ 167 | chprintf(chp, "No Background conversion running\r\n"); 168 | return; 169 | } 170 | //Get the last used pointer 171 | int myp1 = (p1-1+BUFFLEN)%BUFFLEN; 172 | //Convert to Voltage and then to °C 173 | thisTemp = (((int64_t)temp[myp1])*VREFINT*400/VREFMeasured-30400)+2500; 174 | chprintf(chp, "Temperatur: %d.%2U°C\r\n", thisTemp/100,thisTemp%100); 175 | //temp[p1]; 176 | } 177 | 178 | /* 179 | * prints and sets the measured value for VREFint 180 | */ 181 | void cmd_Vref(BaseSequentialStream *chp, int argc, char *argv[]) { 182 | 183 | (void)argv; 184 | if (argc >1 ) { 185 | chprintf(chp, "Usage: vref [newValue]\r\n"); 186 | return; 187 | } 188 | chprintf(chp, "VREFmeasured: %U\r\n", VREFMeasured); 189 | chprintf(chp, "VREFInt: %U.%2UV\r\n", VREFINT/100,VREFINT%100); 190 | if(argc==1){ 191 | VREFMeasured = atoi(argv[0]); 192 | } 193 | } 194 | 195 | /* 196 | * averages ADC_GRP1_BUF_DEPTH samples and converts to analog voltage 197 | */ 198 | void cmd_measureA(BaseSequentialStream *chp, int argc, char *argv[]) { 199 | 200 | (void)argv; 201 | uint32_t sum=0; 202 | unsigned int i; 203 | if(running){ 204 | chprintf(chp, "Continuous measurement already running\r\n"); 205 | return; 206 | } 207 | if (argc >0 ) { 208 | chprintf(chp, "Usage: measure\r\n"); 209 | return; 210 | } 211 | //for(i=0;i<160;i++) 212 | adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH); 213 | sum=0; 214 | for (i=0;i>22; //This is the inlined version of the above 227 | 228 | //Using VREFMeasured === VREFINT 229 | //sum = ((uint64_t)sum)/(ADC_GRP1_BUF_DEPTH/16)*VREFINT/VREFMeasured; 230 | sum = ((uint64_t)sum)*VREFINT/(ADC_GRP1_BUF_DEPTH/16*VREFMeasured/100); 231 | 232 | //prints the averaged value with 4 digits precision 233 | chprintf(chp, "Measured: %U.%04UV\r\n", sum/10000, sum%10000); 234 | } 235 | 236 | 237 | /* 238 | * This callback is called everytime the buffer is filled or half-filled 239 | * A second ring buffer is used to store the averaged data. 240 | * I should use a third buffer to store a timestamp when the buffer was filled. 241 | * I hope I understood how the Conversion ring buffer works... 242 | */ 243 | 244 | static void adccallback(ADCDriver *adcp, adcsample_t *buffer, size_t n) { 245 | 246 | (void)adcp; 247 | (void)n; 248 | 249 | unsigned int i,j; 250 | uint32_t sum=0; 251 | uint32_t vrefSum=0; 252 | uint32_t tempSum=0; 253 | if(n != ADC_GRP2_BUF_DEPTH/2) overflow++; 254 | for(i=0;i>2; 267 | ++p1; 268 | p1 = p1%BUFFLEN; 269 | if(p1==p2) ++overflow; 270 | } 271 | 272 | 273 | static const ADCConversionGroup adcgrpcfg2 = { 274 | TRUE, //circular buffer mode 275 | ADC_GRP2_NUM_CHANNELS, //Number of the analog channels 276 | adccallback, //Callback function 277 | adcerrorcallback, //Error callback 278 | 0, /* CR1 */ 279 | ADC_CR2_SWSTART, /* CR2 */ 280 | ADC_SMPR1_SMP_AN12(ADC_SAMPLE_480) | ADC_SMPR1_SMP_AN11(ADC_SAMPLE_480) | 281 | ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_480) | ADC_SMPR1_SMP_VREF(ADC_SAMPLE_480), //sample times ch10-18 282 | 0, //sample times ch0-9 283 | ADC_SQR1_NUM_CH(ADC_GRP2_NUM_CHANNELS), //SQR1: Conversion group sequence 13...16 + sequence length 284 | // ADC_SQR2_SQ8_N(ADC_CHANNEL_IN11) | ADC_SQR2_SQ7_N(ADC_CHANNEL_IN11), //SQR2: Conversion group sequence 7...12 285 | ADC_SQR2_SQ10_N(ADC_CHANNEL_SENSOR) | ADC_SQR2_SQ9_N(ADC_CHANNEL_VREFINT) | 286 | ADC_SQR2_SQ8_N(ADC_CHANNEL_IN11) | ADC_SQR2_SQ7_N(ADC_CHANNEL_IN11) , 287 | ADC_SQR3_SQ6_N(ADC_CHANNEL_IN11) | ADC_SQR3_SQ5_N(ADC_CHANNEL_IN11) | 288 | ADC_SQR3_SQ4_N(ADC_CHANNEL_IN11) | ADC_SQR3_SQ3_N(ADC_CHANNEL_IN11) | 289 | ADC_SQR3_SQ2_N(ADC_CHANNEL_IN11) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11) //SQR3: Conversion group sequence 1...6 290 | }; 291 | 292 | /* 293 | * Start a continuous conversion 294 | */ 295 | void cmd_measureCont(BaseSequentialStream *chp, int argc, char *argv[]) { 296 | 297 | (void)chp; 298 | (void)argc; 299 | (void)argv; 300 | if(running){ 301 | chprintf(chp, "Continuous measurement already running\r\n"); 302 | }else { 303 | running=1; 304 | adcStartConversion(&ADCD1, &adcgrpcfg2, samples2, ADC_GRP2_BUF_DEPTH); 305 | } 306 | } 307 | 308 | /* 309 | * Stop a continuous conversion 310 | */ 311 | void cmd_measureStop(BaseSequentialStream *chp, int argc, char *argv[]) { 312 | 313 | (void)chp; 314 | (void)argc; 315 | (void)argv; 316 | if(running){ 317 | adcStopConversion(&ADCD1); 318 | running=0; 319 | } 320 | } 321 | 322 | /* 323 | * print the remainder of the ring buffer of a continuous conversion 324 | */ 325 | void cmd_measureRead(BaseSequentialStream *chp, int argc, char *argv[]) { 326 | 327 | (void)chp; 328 | (void)argc; 329 | (void)argv; 330 | while(p1!=p2){ 331 | chprintf(chp, "%U:%U-%U-%U ", p2, data[p2], vref[p2], temp[p2]); 332 | if (data[p2]==0){ 333 | chprintf(chp, "\r\n Error!\r\n ", p2, data[p2]); 334 | } 335 | p2 = (p2+1)%BUFFLEN; 336 | } 337 | chprintf(chp, "\r\n"); 338 | if(overflow){ 339 | chprintf(chp, "Overflow: %U \r\n", overflow); 340 | overflow=0; 341 | } 342 | } 343 | 344 | void myADCinit(void){ 345 | palSetGroupMode(GPIOC, PAL_PORT_BIT(1), 346 | 0, PAL_MODE_INPUT_ANALOG); 347 | adcStart(&ADCD1, NULL); 348 | //enable temperature sensor and Vref 349 | adcSTM32EnableTSVREFE(); 350 | } 351 | -------------------------------------------------------------------------------- /myADC.h: -------------------------------------------------------------------------------- 1 | #ifndef MYADC_H_INCLUDED 2 | #define MYADC_H_INCLUDED 3 | 4 | void cmd_measure(BaseSequentialStream *chp, int argc, char *argv[]); 5 | void cmd_measureA(BaseSequentialStream *chp, int argc, char *argv[]); 6 | void cmd_measureDirect(BaseSequentialStream *chp, int argc, char *argv[]); 7 | void cmd_Vref(BaseSequentialStream *chp, int argc, char *argv[]); 8 | void cmd_Temperature(BaseSequentialStream *chp, int argc, char *argv[]); 9 | 10 | void cmd_measureCont(BaseSequentialStream *chp, int argc, char *argv[]); 11 | void cmd_measureRead(BaseSequentialStream *chp, int argc, char *argv[]); 12 | void cmd_measureStop(BaseSequentialStream *chp, int argc, char *argv[]); 13 | 14 | void myADCinit(void); 15 | 16 | 17 | #endif // MYADC_H_INCLUDED 18 | -------------------------------------------------------------------------------- /myMisc.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include "ch.h" 5 | #include "hal.h" 6 | 7 | #include "chprintf.h" 8 | 9 | #include "myMisc.h" 10 | 11 | 12 | /*===========================================================================*/ 13 | /* Generic code. */ 14 | /*===========================================================================*/ 15 | 16 | 17 | void cmd_mem(BaseSequentialStream *chp, int argc, char *argv[]) { 18 | size_t n, size; 19 | 20 | (void)argv; 21 | if (argc > 0) { 22 | chprintf(chp, "Usage: mem\r\n"); 23 | return; 24 | } 25 | n = chHeapStatus(NULL, &size); 26 | chprintf(chp, "core free memory : %u bytes\r\n", chCoreStatus()); 27 | chprintf(chp, "heap fragments : %u\r\n", n); 28 | chprintf(chp, "heap free total : %u bytes\r\n", size); 29 | } 30 | 31 | void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) { 32 | static const char *states[] = {THD_STATE_NAMES}; 33 | Thread *tp; 34 | 35 | (void)argv; 36 | if (argc > 0) { 37 | chprintf(chp, "Usage: threads\r\n"); 38 | return; 39 | } 40 | chprintf(chp, " addr stack prio refs state time\r\n"); 41 | tp = chRegFirstThread(); 42 | do { 43 | chprintf(chp, "%.8lx %.8lx %4lu %4lu %9s %lu\r\n", 44 | (uint32_t)tp, (uint32_t)tp->p_ctx.r13, 45 | (uint32_t)tp->p_prio, (uint32_t)(tp->p_refs - 1), 46 | states[tp->p_state], (uint32_t)tp->p_time); 47 | tp = chRegNextThread(tp); 48 | } while (tp != NULL); 49 | } 50 | 51 | void cmd_toggle(BaseSequentialStream *chp, int argc, char *argv[]) { 52 | 53 | (void)argv; 54 | if (argc != 1) { 55 | chprintf(chp, "Usage: toggle #led\r\n"); 56 | return; 57 | } 58 | if(argv[0][0]=='1'){ 59 | palTogglePad(GPIOD, GPIOD_LED3); 60 | } else if(argv[0][0]=='2'){ 61 | palTogglePad(GPIOD, GPIOD_LED4); 62 | } else if(argv[0][0]=='3'){ 63 | palTogglePad(GPIOD, GPIOD_LED5); 64 | } else if(argv[0][0]=='4'){ 65 | palTogglePad(GPIOD, GPIOD_LED6); 66 | } 67 | } 68 | 69 | int blinkspeed = 500; 70 | void cmd_blinkspeed(BaseSequentialStream *chp, int argc, char *argv[]) { 71 | 72 | (void)argv; 73 | int speed = 500; 74 | if (argc != 1) { 75 | chprintf(chp, "Usage: blinkspeed speed [ms]\r\n"); 76 | return; 77 | } 78 | speed = atoi(argv[0]); 79 | if(speed>5000) speed = 5000; 80 | if(speed<5) speed = 5; 81 | blinkspeed = speed; 82 | } 83 | 84 | /* 85 | * Red LED blinker thread, times are in milliseconds. 86 | */ 87 | static WORKING_AREA(waThread1, 128); 88 | static msg_t Thread1(void *arg) { 89 | 90 | (void)arg; 91 | chRegSetThreadName("blinker"); 92 | while (TRUE) { 93 | palClearPad(GPIOD, GPIOD_LED6); 94 | chThdSleepMilliseconds(blinkspeed); 95 | palSetPad(GPIOD, GPIOD_LED6); 96 | chThdSleepMilliseconds(blinkspeed); 97 | 98 | } 99 | return 0; 100 | } 101 | 102 | void startBlinker(void){ 103 | chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); 104 | } 105 | -------------------------------------------------------------------------------- /myMisc.h: -------------------------------------------------------------------------------- 1 | #ifndef MYMISC_H_INCLUDED 2 | #define MYMISC_H_INCLUDED 3 | 4 | 5 | void cmd_mem(BaseSequentialStream *chp, int argc, char *argv[]); 6 | void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]); 7 | void cmd_toggle(BaseSequentialStream *chp, int argc, char *argv[]); 8 | void cmd_blinkspeed(BaseSequentialStream *chp, int argc, char *argv[]); 9 | 10 | void startBlinker(void); 11 | 12 | 13 | #endif // MYMISC_H_INCLUDED 14 | -------------------------------------------------------------------------------- /myPWM.c: -------------------------------------------------------------------------------- 1 | #include "ch.h" 2 | #include "hal.h" 3 | #include "chprintf.h" 4 | #include 5 | 6 | #include "myPWM.h" 7 | 8 | 9 | /* 10 | * this PWM callback function gets called at the end of a period 11 | * usually it resets all used channels (to either high or low) 12 | */ 13 | 14 | static void pwmpcb(PWMDriver *pwmp) { 15 | 16 | (void)pwmp; 17 | palSetPad(GPIOD, GPIOD_LED4); 18 | palSetPad(GPIOD, GPIOD_LED5); 19 | } 20 | 21 | /* 22 | * PWM callback for channel 1 at the given duty cycle 23 | */ 24 | static void pwmc1cb(PWMDriver *pwmp) { 25 | 26 | (void)pwmp; 27 | palClearPad(GPIOD, GPIOD_LED4); 28 | } 29 | 30 | /* 31 | * PWM callback for channel 2 at the given duty cycle 32 | */ 33 | static void pwmc2cb(PWMDriver *pwmp) { 34 | 35 | (void)pwmp; 36 | palClearPad(GPIOD, GPIOD_LED5); 37 | } 38 | 39 | /* 40 | * PWM configuration 41 | * 2 of the 4 channels are used 42 | */ 43 | static PWMConfig pwmcfg = { 44 | 1000000, /* 1MHz PWM clock frequency. */ 45 | 10000, /* Initial PWM period 1/100S. */ 46 | pwmpcb, /* callback gets triggered after each period */ 47 | { 48 | {PWM_OUTPUT_ACTIVE_HIGH, pwmc1cb}, /* channel 1 callback at given duty cycle */ 49 | {PWM_OUTPUT_ACTIVE_HIGH, pwmc2cb}, /* channel 2 callback at given duty cycle */ 50 | {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 callback unused */ 51 | {PWM_OUTPUT_DISABLED, NULL} /* channel 1 callback unused */ 52 | }, 53 | 0, 54 | }; 55 | 56 | /* 57 | * console callable function that sets a given duty cycle for channel 1 58 | * (the argument is in tics, so it makes sense to have it between 0 and 10000) 59 | */ 60 | void cmd_cycle(BaseSequentialStream *chp, int argc, char *argv[]) { 61 | 62 | (void)argv; 63 | int cycle = 500; 64 | if (argc != 1) { 65 | chprintf(chp, "Usage: cycle duty\r\n"); 66 | return; 67 | } 68 | cycle = atoi(argv[0]); 69 | chprintf(chp, "cycle: %d\r\n", cycle); 70 | //pwmEnableChannel(&PWMD2, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, atoi(argv[0]))); 71 | pwmEnableChannel(&PWMD2, 0, atoi(argv[0])); 72 | } 73 | 74 | 75 | /* 76 | * console callable function that ramps channel zero with a given ramp 77 | * use it for instance with: 78 | * ch> ramp 0 10000 1000 1000 79 | * that creates a ramp that increases from 0 to 100% duty in 10 steps&secs 80 | */ 81 | void cmd_ramp(BaseSequentialStream *chp, int argc, char *argv[]) { 82 | 83 | (void)argv; 84 | int from, to, step,i, delay = 100; 85 | if (argc < 3 || argc >4) { 86 | chprintf(chp, "Usage: ramp from to step [delay]\r\n"); 87 | return; 88 | } 89 | if(argc == 4){ 90 | delay = atoi(argv[3]); 91 | } 92 | from = atoi(argv[0]); 93 | to = atoi(argv[1]); 94 | step = atoi(argv[2]); 95 | for(i=from;iusbp->state == USB_ACTIVE; 162 | } 163 | 164 | 165 | void myUSBinit(void){ 166 | usbDisconnectBus(serusbcfg.usbp); 167 | chThdSleepMilliseconds(1000); 168 | sduObjectInit(&SDU1); 169 | sduStart(&SDU1, &serusbcfg); // => usbStart(config->usbp, &config->usb_config); 170 | usbConnectBus(serusbcfg.usbp); 171 | 172 | /* 173 | * Shell manager initialization. 174 | */ 175 | shellInit(); 176 | } 177 | -------------------------------------------------------------------------------- /myUSB.h: -------------------------------------------------------------------------------- 1 | #ifndef MYUSB_H_INCLUDED 2 | #define MYUSB_H_INCLUDED 3 | extern SerialUSBDriver SDU1; 4 | 5 | void myUSBinit(void); 6 | int isUsbActive(void); 7 | 8 | #endif // MYUSB_H_INCLUDED 9 | -------------------------------------------------------------------------------- /usbdescriptor.h: -------------------------------------------------------------------------------- 1 | #ifndef USBDESCRIPTOR_H_INCLUDED 2 | #define USBDESCRIPTOR_H_INCLUDED 3 | 4 | #include "usb_cdc.h" 5 | /* 6 | * USB Device Descriptor. 7 | */ 8 | static const uint8_t vcom_device_descriptor_data[18] = { 9 | USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */ 10 | 0x02, /* bDeviceClass (CDC). */ 11 | 0x00, /* bDeviceSubClass. */ 12 | 0x00, /* bDeviceProtocol. */ 13 | 0x40, /* bMaxPacketSize. */ 14 | 0x0483, /* idVendor (ST). */ 15 | 0x5740, /* idProduct. */ 16 | 0x0200, /* bcdDevice. */ 17 | 1, /* iManufacturer. */ 18 | 2, /* iProduct. */ 19 | 3, /* iSerialNumber. */ 20 | 1) /* bNumConfigurations. */ 21 | }; 22 | 23 | /* 24 | * Device Descriptor wrapper. 25 | */ 26 | static const USBDescriptor vcom_device_descriptor = { 27 | sizeof vcom_device_descriptor_data, 28 | vcom_device_descriptor_data 29 | }; 30 | 31 | /* Configuration Descriptor tree for a CDC.*/ 32 | static const uint8_t vcom_configuration_descriptor_data[67] = { 33 | /* Configuration Descriptor.*/ 34 | USB_DESC_CONFIGURATION(67, /* wTotalLength. */ 35 | 0x02, /* bNumInterfaces. */ 36 | 0x01, /* bConfigurationValue. */ 37 | 0, /* iConfiguration. */ 38 | 0xC0, /* bmAttributes (self powered). */ 39 | 50), /* bMaxPower (100mA). */ 40 | /* Interface Descriptor.*/ 41 | USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */ 42 | 0x00, /* bAlternateSetting. */ 43 | 0x01, /* bNumEndpoints. */ 44 | 0x02, /* bInterfaceClass (Communications 45 | Interface Class, CDC section 46 | 4.2). */ 47 | 0x02, /* bInterfaceSubClass (Abstract 48 | Control Model, CDC section 4.3). */ 49 | 0x01, /* bInterfaceProtocol (AT commands, 50 | CDC section 4.4). */ 51 | 0), /* iInterface. */ 52 | /* Header Functional Descriptor (CDC section 5.2.3).*/ 53 | USB_DESC_BYTE (5), /* bLength. */ 54 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */ 55 | USB_DESC_BYTE (0x00), /* bDescriptorSubtype (Header 56 | Functional Descriptor. */ 57 | USB_DESC_BCD (0x0110), /* bcdCDC. */ 58 | /* Call Management Functional Descriptor. */ 59 | USB_DESC_BYTE (5), /* bFunctionLength. */ 60 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */ 61 | USB_DESC_BYTE (0x01), /* bDescriptorSubtype (Call Management 62 | Functional Descriptor). */ 63 | USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */ 64 | USB_DESC_BYTE (0x01), /* bDataInterface. */ 65 | /* ACM Functional Descriptor.*/ 66 | USB_DESC_BYTE (4), /* bFunctionLength. */ 67 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */ 68 | USB_DESC_BYTE (0x02), /* bDescriptorSubtype (Abstract 69 | Control Management Descriptor). */ 70 | USB_DESC_BYTE (0x02), /* bmCapabilities. */ 71 | /* Union Functional Descriptor.*/ 72 | USB_DESC_BYTE (5), /* bFunctionLength. */ 73 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */ 74 | USB_DESC_BYTE (0x06), /* bDescriptorSubtype (Union 75 | Functional Descriptor). */ 76 | USB_DESC_BYTE (0x00), /* bMasterInterface (Communication 77 | Class Interface). */ 78 | USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class 79 | Interface). */ 80 | /* Endpoint 2 Descriptor.*/ 81 | USB_DESC_ENDPOINT (USB_CDC_INTERRUPT_REQUEST_EP|0x80, 82 | 0x03, /* bmAttributes (Interrupt). */ 83 | 0x0008, /* wMaxPacketSize. */ 84 | 0xFF), /* bInterval. */ 85 | /* Interface Descriptor.*/ 86 | USB_DESC_INTERFACE (0x01, /* bInterfaceNumber. */ 87 | 0x00, /* bAlternateSetting. */ 88 | 0x02, /* bNumEndpoints. */ 89 | 0x0A, /* bInterfaceClass (Data Class 90 | Interface, CDC section 4.5). */ 91 | 0x00, /* bInterfaceSubClass (CDC section 92 | 4.6). */ 93 | 0x00, /* bInterfaceProtocol (CDC section 94 | 4.7). */ 95 | 0x00), /* iInterface. */ 96 | /* Endpoint 3 Descriptor.*/ 97 | USB_DESC_ENDPOINT (USB_CDC_DATA_AVAILABLE_EP, /* bEndpointAddress.*/ 98 | 0x02, /* bmAttributes (Bulk). */ 99 | 0x0040, /* wMaxPacketSize. */ 100 | 0x00), /* bInterval. */ 101 | /* Endpoint 1 Descriptor.*/ 102 | USB_DESC_ENDPOINT (USB_CDC_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/ 103 | 0x02, /* bmAttributes (Bulk). */ 104 | 0x0040, /* wMaxPacketSize. */ 105 | 0x00) /* bInterval. */ 106 | }; 107 | 108 | /* 109 | * Configuration Descriptor wrapper. 110 | */ 111 | static const USBDescriptor vcom_configuration_descriptor = { 112 | sizeof vcom_configuration_descriptor_data, 113 | vcom_configuration_descriptor_data 114 | }; 115 | 116 | /* 117 | * U.S. English language identifier. 118 | */ 119 | static const uint8_t vcom_string0[] = { 120 | USB_DESC_BYTE(4), /* bLength. */ 121 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ 122 | USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */ 123 | }; 124 | 125 | /* 126 | * Vendor string. 127 | */ 128 | static const uint8_t vcom_string1[] = { 129 | USB_DESC_BYTE(38), /* bLength. */ 130 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ 131 | 'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0, 132 | 'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0, 133 | 'c', 0, 's', 0 134 | }; 135 | 136 | /* 137 | * Device Description string. 138 | */ 139 | static const uint8_t vcom_string2[] = { 140 | USB_DESC_BYTE(56), /* bLength. */ 141 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ 142 | 'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0, 143 | 'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0, 144 | 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0, 145 | 'o', 0, 'r', 0, 't', 0 146 | }; 147 | 148 | /* 149 | * Serial Number string. 150 | */ 151 | static const uint8_t vcom_string3[] = { 152 | USB_DESC_BYTE(8), /* bLength. */ 153 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ 154 | '0' + CH_KERNEL_MAJOR, 0, 155 | '0' + CH_KERNEL_MINOR, 0, 156 | '0' + CH_KERNEL_PATCH, 0 157 | }; 158 | 159 | /* 160 | * Strings wrappers array. 161 | */ 162 | static const USBDescriptor vcom_strings[] = { 163 | {sizeof vcom_string0, vcom_string0}, 164 | {sizeof vcom_string1, vcom_string1}, 165 | {sizeof vcom_string2, vcom_string2}, 166 | {sizeof vcom_string3, vcom_string3} 167 | }; 168 | 169 | 170 | 171 | #endif // USBDESCRIPTOR_H_INCLUDED 172 | --------------------------------------------------------------------------------