Skip to content
This repository
Browse code

Merge branch 'wip-family-support'

Merge the long-lived (too long; future changes like these will need to
proceed more incrementally) development branch of libmaple, containing
experimental STM32F2 and STM32F1 value line support, into master.

This required many changes to the structure of the library. The most
important structural reorganizations occurred in:

- 954f9e5: moves public headers to include directories
- 3efa313: uses "series" instead of "family"
- c0d60e3: adds board files to the build system, to make it easier to
  add new boards
- 096d86c: adds build logic for targeting different STM32 series
  (e.g. STM32F1, STM32F2)

This last commit in particular (096d86c) is the basis for the
repartitioning of libmaple into portable sections, which work on all
supported MCUs, and nonportable sections, which are segregated into
separate directories and contain all series-specific code. Moving
existing STM32F1-only code into libmaple/stm32f1 and wirish/stm32f1,
along with adding equivalents under .../stm32f2 directories, was the
principal project of this branch.

Important API changes occur in several places. Existing code is still
expected to work on STM32F1 targets, but there have been many
deprecations. A detailed changelog explaining the situation needs to
be prepared.

F2 and F1 value line support is not complete; the merge is proceeding
prematurely in this respect. We've been getting more libmaple patches
from the community lately, and I'm worried that the merge conflicts
with the old tree structure will become painful to manage.

Conflicts:
	Makefile

Resolved Makefile conflicts manually; this required propagating
-Xlinker usage into support/make/target-config.mk.

Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
  • Loading branch information...
commit ccc23369719f8909fe61a8423fdf382582414702 2 parents 7451d1d + 12aecf5
Marti Bolivar authored June 26, 2012

Showing 268 changed files with 17,303 additions and 5,417 deletions. Show diff stats Hide diff stats

  1. 3  .gitignore
  2. 112  Makefile
  3. 1  README
  4. 0  {support → contrib}/openocd/debug_0.3.cfg
  5. 0  {support → contrib}/openocd/debug_0.4.cfg
  6. 0  {support → contrib}/openocd/flash_0.3.cfg
  7. 0  {support → contrib}/openocd/flash_0.4.cfg
  8. 0  {support/scripts → contrib/openocd}/openocd-wrapper.sh
  9. 2  examples/blinky.cpp
  10. 12  examples/debug-dtrrts.cpp
  11. 2  examples/freertos-blinky.cpp
  12. 6  examples/fsmc-stress-test.cpp
  13. 145  examples/i2c-mcp4725-dac.cpp
  14. 2  examples/mini-exti-test.cpp
  15. 2  examples/qa-slave-shield.cpp
  16. 30  examples/serial-echo.cpp
  17. 2  examples/spi_master.cpp
  18. 6  examples/test-bkp.cpp
  19. 4  examples/test-dac.cpp
  20. 4  examples/test-fsmc.cpp
  21. 2  examples/test-print.cpp
  22. 4  examples/test-ring-buffer-insertion.cpp
  23. 2  examples/test-serial-flush.cpp
  24. 6  examples/test-serialusb.cpp
  25. 2  examples/test-servo.cpp
  26. 2  examples/test-session.cpp
  27. 2  examples/test-spi-roundtrip.cpp
  28. 4  examples/test-systick.cpp
  29. 710  examples/test-timers.cpp
  30. 220  examples/test-usart-dma.cpp
  31. 2  examples/vga-leaf.cpp
  32. 4  examples/vga-scope.cpp
  33. 78  libmaple/adc.c
  34. 28  libmaple/dac.c
  35. 168  libmaple/dac.h
  36. 30  libmaple/delay.h
  37. 363  libmaple/dma.c
  38. 453  libmaple/dma.h
  39. 61  libmaple/dma_private.h
  40. 63  libmaple/exti.c
  41. 34  libmaple/exti_private.h
  42. 22  libmaple/flash.c
  43. 157  libmaple/gpio.c
  44. 488  libmaple/i2c.c
  45. 79  libmaple/i2c_private.h
  46. 193  libmaple/{ → include/libmaple}/adc.h
  47. 22  libmaple/{ → include/libmaple}/bitband.h
  48. 14  libmaple/{ → include/libmaple}/bkp.h
  49. 158  libmaple/include/libmaple/dac.h
  50. 65  libmaple/include/libmaple/delay.h
  51. 444  libmaple/include/libmaple/dma.h
  52. 114  libmaple/include/libmaple/dma_common.h
  53. 88  libmaple/{ → include/libmaple}/exti.h
  54. 106  libmaple/include/libmaple/flash.h
  55. 108  libmaple/{ → include/libmaple}/fsmc.h
  56. 121  libmaple/include/libmaple/gpio.h
  57. 393  libmaple/{ → include/libmaple}/i2c.h
  58. 95  libmaple/include/libmaple/i2c_common.h
  59. 15  libmaple/{ → include/libmaple}/iwdg.h
  60. 21  libmaple/{ → include/libmaple}/libmaple.h
  61. 23  libmaple/{ → include/libmaple}/libmaple_types.h
  62. 155  libmaple/include/libmaple/nvic.h
  63. 56  libmaple/{ → include/libmaple}/pwr.h
  64. 175  libmaple/include/libmaple/rcc.h
  65. 11  libmaple/{ → include/libmaple}/ring_buffer.h
  66. 16  libmaple/{ → include/libmaple}/scb.h
  67. 169  libmaple/{ → include/libmaple}/spi.h
  68. 237  libmaple/include/libmaple/stm32.h
  69. 151  libmaple/include/libmaple/syscfg.h
  70. 16  libmaple/{ → include/libmaple}/systick.h
  71. 646  libmaple/{ → include/libmaple}/timer.h
  72. 259  libmaple/{ → include/libmaple}/usart.h
  73. 12  libmaple/{ → include/libmaple}/usb.h
  74. 10  libmaple/{usb → include/libmaple}/usb_cdcacm.h
  75. 16  libmaple/{ → include/libmaple}/util.h
  76. 4  libmaple/iwdg.c
  77. 34  libmaple/nvic.c
  78. 6  libmaple/pwr.c
  79. 269  libmaple/rcc.c
  80. 67  libmaple/rcc_private.h
  81. 54  libmaple/rules.mk
  82. 84  libmaple/spi.c
  83. 37  libmaple/spi_private.h
  84. 191  libmaple/stm32.h
  85. 45  libmaple/stm32_private.h
  86. 112  libmaple/stm32f1/adc.c
  87. 12  libmaple/{ → stm32f1}/bkp.c
  88. 412  libmaple/stm32f1/dma.c
  89. 32  libmaple/stm32f1/exti.c
  90. 20  libmaple/{ → stm32f1}/fsmc.c
  91. 166  libmaple/stm32f1/gpio.c
  92. 129  libmaple/stm32f1/i2c.c
  93. 254  libmaple/stm32f1/include/series/adc.h
  94. 71  libmaple/stm32f1/include/series/dac.h
  95. 565  libmaple/stm32f1/include/series/dma.h
  96. 46  libmaple/stm32f1/include/series/exti.h
  97. 85  libmaple/{ → stm32f1/include/series}/flash.h
  98. 456  libmaple/{ → stm32f1/include/series}/gpio.h
  99. 85  libmaple/stm32f1/include/series/i2c.h
  100. 182  libmaple/{ → stm32f1/include/series}/nvic.h
  101. 52  libmaple/stm32f1/include/series/pwr.h
  102. 489  libmaple/{ → stm32f1/include/series}/rcc.h
  103. 99  libmaple/stm32f1/include/series/spi.h
  104. 212  libmaple/stm32f1/include/series/stm32.h
  105. 128  libmaple/stm32f1/include/series/timer.h
  106. 76  libmaple/stm32f1/include/series/usart.h
  107. 28  libmaple/stm32f1/{isrs_performance.S → performance/isrs.S}
  108. 28  libmaple/stm32f1/{vector_table_performance.S → performance/vector_table.S}
  109. 164  libmaple/stm32f1/rcc.c
  110. 27  libmaple/stm32f1/rules.mk
  111. 84  libmaple/stm32f1/spi.c
  112. 124  libmaple/stm32f1/timer.c
  113. 170  libmaple/stm32f1/usart.c
  114. 270  libmaple/stm32f1/value/isrs.S
  115. 116  libmaple/stm32f1/value/vector_table.S
  116. 84  libmaple/stm32f2/adc.c
  117. 504  libmaple/stm32f2/dma.c
  118. 33  libmaple/stm32f2/exti.c
  119. 90  libmaple/stm32f2/fsmc.c
  120. 194  libmaple/stm32f2/gpio.c
  121. 331  libmaple/stm32f2/include/series/adc.h
  122. 94  libmaple/stm32f2/include/series/dac.h
  123. 810  libmaple/stm32f2/include/series/dma.h
  124. 46  libmaple/stm32f2/include/series/exti.h
  125. 202  libmaple/stm32f2/include/series/flash.h
  126. 264  libmaple/stm32f2/include/series/gpio.h
  127. 160  libmaple/stm32f2/include/series/nvic.h
  128. 73  libmaple/stm32f2/include/series/pwr.h
  129. 951  libmaple/stm32f2/include/series/rcc.h
  130. 88  libmaple/stm32f2/include/series/spi.h
  131. 77  libmaple/stm32f2/include/series/stm32.h
  132. 176  libmaple/stm32f2/include/series/timer.h
  133. 111  libmaple/stm32f2/include/series/usart.h
  134. 322  libmaple/stm32f2/isrs.S
  135. 175  libmaple/stm32f2/rcc.c
  136. 40  libmaple/stm32f2/rules.mk
  137. 88  libmaple/stm32f2/spi.c
  138. 78  libmaple/stm32f2/syscfg.c
  139. 148  libmaple/stm32f2/timer.c
  140. 204  libmaple/stm32f2/usart.c
  141. 135  libmaple/stm32f2/vector_table.S
  142. 6  libmaple/systick.c
  143. 476  libmaple/timer.c
  144. 235  libmaple/timer_private.h
  145. 144  libmaple/usart.c
  146. 41  libmaple/usart_private.c
  147. 53  libmaple/usart_private.h
  148. 69  libmaple/usb/README
  149. 45  libmaple/usb/rules.mk
  150. 12  libmaple/usb/{ → stm32f1}/usb.c
  151. 26  libmaple/usb/{ → stm32f1}/usb_cdcacm.c
  152. 2  libmaple/usb/{ → stm32f1}/usb_descriptors.h
  153. 1  libmaple/usb/{ → stm32f1}/usb_lib_globals.h
  154. 0  libmaple/usb/{ → stm32f1}/usb_reg_map.c
  155. 4  libmaple/usb/{ → stm32f1}/usb_reg_map.h
  156. 123  libmaple/util.c
  157. 2  libraries/FreeRTOS/MapleFreeRTOS.h
  158. 2  libraries/LiquidCrystal/LiquidCrystal.cpp
  159. 4  libraries/LiquidCrystal/LiquidCrystal.h
  160. 8  libraries/Servo/Servo.cpp
  161. 10  libraries/Servo/Servo.h
  162. 1  libraries/Wire/Wire.cpp
  163. 4  libraries/Wire/Wire.h
  164. 2  main.cpp.example
  165. 0  notes/{dma.txt → dma-stm32f1.txt}
  166. 63  notes/stm32.txt
  167. 18  support/doxygen/Doxyfile
  168. 38  support/doxygen/evil_mangler.awk
  169. 26  support/ld/flash.ld
  170. 31  support/ld/jtag.ld
  171. 24  support/ld/maple/flash.ld
  172. 24  support/ld/maple/jtag.ld
  173. 22  support/ld/maple/ram.ld
  174. 18  support/ld/maple_RET6/flash.ld
  175. 18  support/ld/maple_RET6/jtag.ld
  176. 17  support/ld/maple_RET6/ram.ld
  177. 23  support/ld/maple_mini/flash.ld
  178. 24  support/ld/maple_mini/jtag.ld
  179. 22  support/ld/maple_mini/ram.ld
  180. 22  support/ld/maple_native/flash.ld
  181. 22  support/ld/maple_native/jtag.ld
  182. 20  support/ld/maple_native/ram.ld
  183. 1  support/ld/olimex_stm32_h103
  184. 25  support/ld/ram.ld
  185. 3  support/ld/stm32/mem/maple_native/maple_native_heap.inc
  186. 7  support/ld/stm32/mem/maple_native/mem-flash.inc
  187. 7  support/ld/stm32/mem/maple_native/mem-jtag.inc
  188. 7  support/ld/stm32/mem/maple_native/mem-ram.inc
  189. 5  support/ld/stm32/mem/sram_112k_flash_1024k/mem-jtag.inc
  190. 5  support/ld/stm32/mem/sram_112k_flash_1024k/mem-ram.inc
  191. 5  support/ld/stm32/mem/sram_20k_flash_128k/mem-flash.inc
  192. 5  support/ld/stm32/mem/sram_20k_flash_128k/mem-jtag.inc
  193. 5  support/ld/stm32/mem/sram_20k_flash_128k/mem-ram.inc
  194. 5  support/ld/stm32/mem/sram_64k_flash_512k/mem-flash.inc
  195. 5  support/ld/stm32/mem/sram_64k_flash_512k/mem-jtag.inc
  196. 5  support/ld/stm32/mem/sram_64k_flash_512k/mem-ram.inc
  197. 5  support/ld/stm32/mem/sram_8k_flash_128k/mem-flash.inc
  198. 5  support/ld/stm32/mem/sram_8k_flash_128k/mem-jtag.inc
  199. 5  support/ld/stm32/mem/sram_8k_flash_128k/mem-ram.inc
  200. 0  support/ld/stm32/{f1 → series/stm32f1}/performance/vector_symbols.inc
  201. 78  support/ld/stm32/series/stm32f1/value/vector_symbols.inc
  202. 98  support/ld/stm32/series/stm32f2/vector_symbols.inc
  203. 7  support/make/board-includes/VLDiscovery.mk
  204. 10  support/make/board-includes/maple.mk
  205. 7  support/make/board-includes/maple_RET6.mk
  206. 7  support/make/board-includes/maple_mini.mk
  207. 7  support/make/board-includes/maple_native.mk
  208. 7  support/make/board-includes/olimex_stm32_h103.mk
  209. 5  support/make/board-includes/st_stm3220g_eval.mk
  210. 1  support/make/build-rules.mk
  211. 1  support/make/build-templates.mk
  212. 97  support/make/target-config.mk
  213. 22  wirish/{comm → }/HardwareSPI.cpp
  214. 134  wirish/HardwareSerial.cpp
  215. 65  wirish/HardwareTimer.cpp
  216. 6  wirish/Print.cpp
  217. 178  wirish/boards.cpp
  218. 52  wirish/boards/{maple.cpp → VLDiscovery/board.cpp}
  219. 91  wirish/boards/VLDiscovery/include/board/board.h
  220. 143  wirish/boards/maple/board.cpp
  221. 29  wirish/boards/{maple.h → maple/include/board/board.h}
  222. 13  wirish/boards/{maple_RET6.cpp → maple_RET6/board.cpp}
  223. 12  wirish/boards/{maple_RET6.h → maple_RET6/include/board/board.h}
  224. 15  wirish/boards/{maple_mini.cpp → maple_mini/board.cpp}
  225. 7  wirish/boards/{maple_mini.h → maple_mini/include/board/board.h}
  226. 18  wirish/boards/{maple_native.cpp → maple_native/board.cpp}
  227. 7  wirish/boards/{maple_native.h → maple_native/include/board/board.h}
  228. 15  wirish/boards/{olimex_stm32_h103.cpp → olimex_stm32_h103/board.cpp}
  229. 4  wirish/boards/{olimex_stm32_h103.h → olimex_stm32_h103/include/board/board.h}
  230. 60  wirish/boards/st_stm3220g_eval/board.cpp
  231. 53  wirish/boards/st_stm3220g_eval/include/board/board.h
  232. 71  wirish/boards_private.h
  233. 119  wirish/comm/HardwareSerial.cpp
  234. 18  wirish/ext_interrupts.cpp
  235. 21  wirish/{comm → include/wirish}/HardwareSPI.h
  236. 40  wirish/{comm → include/wirish}/HardwareSerial.h
  237. 24  wirish/{ → include/wirish}/HardwareTimer.h
  238. 6  wirish/{ → include/wirish}/Print.h
  239. 7  wirish/{ → include/wirish}/WProgram.h
  240. 4  wirish/{ → include/wirish}/bit_constants.h
  241. 7  wirish/{ → include/wirish}/bits.h
  242. 102  wirish/{ → include/wirish}/boards.h
  243. 15  wirish/{ → include/wirish}/ext_interrupts.h
  244. 17  wirish/{ → include/wirish}/io.h
  245. 11  wirish/{ → include/wirish}/pwm.h
  246. 11  wirish/{ → include/wirish}/usb_serial.h
  247. 38  wirish/{ → include/wirish}/wirish.h
  248. 16  wirish/{ → include/wirish}/wirish_debug.h
  249. 8  wirish/{ → include/wirish}/wirish_math.h
  250. 12  wirish/{ → include/wirish}/wirish_time.h
  251. 14  wirish/{ → include/wirish}/wirish_types.h
  252. 21  wirish/pwm.cpp
  253. 58  wirish/rules.mk
  254. 89  wirish/stm32f1/boards_setup.cpp
  255. 83  wirish/stm32f1/util_hooks.c
  256. 41  wirish/stm32f1/wirish_debug.cpp
  257. 89  wirish/stm32f1/wirish_digital.cpp
  258. 120  wirish/stm32f2/boards_setup.cpp
  259. 45  wirish/stm32f2/util_hooks.c
  260. 60  wirish/stm32f2/wirish_debug.cpp
  261. 99  wirish/stm32f2/wirish_digital.cpp
  262. 35  {libmaple → wirish}/syscalls.c
  263. 18  wirish/usb_serial.cpp
  264. 17  wirish/wirish_analog.cpp
  265. 70  wirish/wirish_digital.cpp
  266. 2  wirish/wirish_math.cpp
  267. 61  wirish/wirish_shift.cpp
  268. 6  wirish/wirish_time.cpp
3  .gitignore
... ...
@@ -1,5 +1,6 @@
1 1
 build/
2  
-doxygen/
  2
+doxygen/xml/
  3
+doxygen/html/
3 4
 main.cpp
4 5
 libmaple.layout
5 6
 tags
112  Makefile
@@ -19,10 +19,7 @@ SUPPORT_PATH := $(SRCROOT)/support
19 19
 LDDIR := $(SUPPORT_PATH)/ld
20 20
 # Support files for this Makefile
21 21
 MAKEDIR := $(SUPPORT_PATH)/make
22  
-
23  
-# USB ID for DFU upload
24  
-VENDOR_ID  := 1EAF
25  
-PRODUCT_ID := 0003
  22
+BOARD_INCLUDE_DIR := $(MAKEDIR)/board-includes
26 23
 
27 24
 ##
28 25
 ## Target-specific configuration.  This determines some compiler and
@@ -41,40 +38,42 @@ include $(MAKEDIR)/target-config.mk
41 38
 ## Compilation flags
42 39
 ##
43 40
 
44  
-GLOBAL_FLAGS    := -D$(VECT_BASE_ADDR)					     \
45  
-		   -DBOARD_$(BOARD) -DMCU_$(MCU)			     \
46  
-		   -DERROR_LED_PORT=$(ERROR_LED_PORT)			     \
47  
-		   -DERROR_LED_PIN=$(ERROR_LED_PIN)			     \
48  
-		   -D$(DENSITY)
  41
+# FIXME: the following allows for deprecated include style, e.g.:
  42
+#     #include "libmaple.h"
  43
+# or
  44
+#     #include "wirish.h"
  45
+# It slows compilation noticeably; remove after 1 release.
  46
+TARGET_FLAGS    += -I$(LIBMAPLE_PATH)/include/libmaple                       \
  47
+                   -I$(WIRISH_PATH)/include/wirish
49 48
 GLOBAL_CFLAGS   := -Os -g3 -gdwarf-2  -mcpu=cortex-m3 -mthumb -march=armv7-m \
50 49
 		   -nostdlib -ffunction-sections -fdata-sections	     \
51  
-		   -Wl,--gc-sections $(GLOBAL_FLAGS)
52  
-GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions -Wall $(GLOBAL_FLAGS)
  50
+		   -Wl,--gc-sections $(TARGET_FLAGS)
  51
+GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions -Wall $(TARGET_FLAGS)
53 52
 GLOBAL_ASFLAGS  := -mcpu=cortex-m3 -march=armv7-m -mthumb		     \
54  
-		   -x assembler-with-cpp $(GLOBAL_FLAGS)
55  
-LDFLAGS  = -T$(LDDIR)/$(LDSCRIPT) -L$(LDDIR)    \
56  
-            -mcpu=cortex-m3 -mthumb -Xlinker -L $(LD_FAMILY_PATH)    \
57  
-            -Xlinker --gc-sections -Xlinker --print-gc-sections \
58  
-            -Xassembler --march=armv7-m -Wall
  53
+		   -x assembler-with-cpp $(TARGET_FLAGS)
  54
+LDFLAGS  = $(TARGET_LDFLAGS) -mcpu=cortex-m3 -mthumb \
  55
+           -Xlinker --gc-sections -Xlinker --print-gc-sections \
  56
+           -Xassembler --march=armv7-m -Wall
59 57
 ##
60 58
 ## Build rules and useful templates
61 59
 ##
62 60
 
63  
-include $(SUPPORT_PATH)/make/build-rules.mk
64  
-include $(SUPPORT_PATH)/make/build-templates.mk
  61
+include $(MAKEDIR)/build-rules.mk
  62
+include $(MAKEDIR)/build-templates.mk
65 63
 
66 64
 ##
67 65
 ## Set all submodules here
68 66
 ##
69 67
 
70 68
 LIBMAPLE_MODULES += $(SRCROOT)/libmaple
71  
-LIBMAPLE_MODULES += $(LIBMAPLE_MODULE_FAMILY) # family submodule in libmaple
  69
+LIBMAPLE_MODULES += $(SRCROOT)/libmaple/usb   # The USB module is kept separate
  70
+LIBMAPLE_MODULES += $(LIBMAPLE_MODULE_SERIES) # STM32 series submodule in libmaple
72 71
 LIBMAPLE_MODULES += $(SRCROOT)/wirish
  72
+
73 73
 # Official libraries:
74 74
 LIBMAPLE_MODULES += $(SRCROOT)/libraries/Servo
75 75
 LIBMAPLE_MODULES += $(SRCROOT)/libraries/LiquidCrystal
76 76
 LIBMAPLE_MODULES += $(SRCROOT)/libraries/Wire
77  
-
78 77
 # Experimental libraries:
79 78
 LIBMAPLE_MODULES += $(SRCROOT)/libraries/FreeRTOS
80 79
 
@@ -93,16 +92,18 @@ $(foreach m,$(LIBMAPLE_MODULES),$(eval $(call LIBMAPLE_MODULE_template,$(m))))
93 92
 # main target
94 93
 include $(SRCROOT)/build-targets.mk
95 94
 
96  
-.PHONY: install sketch clean help debug cscope tags ctags ram flash jtag doxygen mrproper
  95
+.PHONY: install sketch clean help cscope tags ctags ram flash jtag doxygen mrproper list-boards
97 96
 
98 97
 # Target upload commands
  98
+# USB ID for DFU upload -- FIXME: do something smarter with this
  99
+BOARD_USB_VENDOR_ID  := 1EAF
  100
+BOARD_USB_PRODUCT_ID := 0003
99 101
 UPLOAD_ram   := $(SUPPORT_PATH)/scripts/reset.py && \
100 102
                 sleep 1                  && \
101  
-                $(DFU) -a0 -d $(VENDOR_ID):$(PRODUCT_ID) -D $(BUILD_PATH)/$(BOARD).bin -R
  103
+                $(DFU) -a0 -d $(BOARD_USB_VENDOR_ID):$(BOARD_USB_PRODUCT_ID) -D $(BUILD_PATH)/$(BOARD).bin -R
102 104
 UPLOAD_flash := $(SUPPORT_PATH)/scripts/reset.py && \
103 105
                 sleep 1                  && \
104  
-                $(DFU) -a1 -d $(VENDOR_ID):$(PRODUCT_ID) -D $(BUILD_PATH)/$(BOARD).bin -R
105  
-UPLOAD_jtag  := $(OPENOCD_WRAPPER) flash
  106
+                $(DFU) -a1 -d $(BOARD_USB_VENDOR_ID):$(BOARD_USB_PRODUCT_ID) -D $(BUILD_PATH)/$(BOARD).bin -R
106 107
 
107 108
 # Conditionally upload to whatever the last build was
108 109
 install: INSTALL_TARGET = $(shell cat $(BUILD_PATH)/build-type 2>/dev/null)
@@ -127,38 +128,37 @@ mrproper: clean
127 128
 
128 129
 help:
129 130
 	@echo ""
130  
-	@echo "  libmaple Makefile help"
131  
-	@echo "  ----------------------"
132  
-	@echo "  "
133  
-	@echo "  Programming targets:"
134  
-	@echo "      sketch:   Compile for BOARD to MEMORY_TARGET (default)."
135  
-	@echo "      install:  Compile and upload code over USB, using Maple bootloader"
136  
-	@echo "  "
137  
-	@echo "  You *must* set BOARD if not compiling for Maple (e.g."
138  
-	@echo "  use BOARD=maple_mini for mini, etc.), and MEMORY_TARGET"
139  
-	@echo "  if not compiling to Flash."
140  
-	@echo "  "
141  
-	@echo "  Valid BOARDs:"
142  
-	@echo "      maple, maple_mini, maple_RET6, maple_native"
143  
-	@echo "  "
144  
-	@echo "  Valid MEMORY_TARGETs (default=flash):"
145  
-	@echo "      ram:    Compile sketch code to ram"
146  
-	@echo "      flash:  Compile sketch code to flash"
147  
-	@echo "      jtag:   Compile sketch code for jtag; overwrites bootloader"
148  
-	@echo "  "
149  
-	@echo "  Other targets:"
150  
-	@echo "      debug:  Start OpenOCD gdb server on port 3333, telnet on port 4444"
151  
-	@echo "      clean: Remove all build and object files"
152  
-	@echo "      help: Show this message"
153  
-	@echo "      doxygen: Build Doxygen HTML and XML documentation"
154  
-	@echo "      mrproper: Remove all generated files"
155  
-	@echo "  "
156  
-
157  
-debug:
158  
-	$(OPENOCD_WRAPPER) debug
  131
+	@echo "Basic usage (BOARD defaults to maple):"
  132
+	@echo "    $$ cp your-main.cpp main.cpp"
  133
+	@echo "    $$ make BOARD=your_board"
  134
+	@echo "    $$ make BOARD=your_board install"
  135
+	@echo ""
  136
+	@echo "(Multiple source files? Link with libmaple.a (\`$$ make library')"
  137
+	@echo "or hack build-targets.mk appropriately.)"
  138
+	@echo ""
  139
+	@echo "Important targets:"
  140
+	@echo "    sketch:   Compile for BOARD to MEMORY_TARGET (default)."
  141
+	@echo "    install:  Compile and upload over USB using Maple bootloader"
  142
+	@echo ""
  143
+	@echo "You *must* set BOARD if not compiling for Maple (e.g."
  144
+	@echo "use BOARD=maple_mini for mini, etc.), and MEMORY_TARGET"
  145
+	@echo "if not compiling to Flash. Run \`$$ make list-boards' for"
  146
+	@echo "a list of all boards."
  147
+	@echo ""
  148
+	@echo "Valid MEMORY_TARGETs (default=flash):"
  149
+	@echo "    ram:    Compile to RAM (doesn't touch Flash)"
  150
+	@echo "    flash:  Compile to Flash (for Maple bootloader)"
  151
+	@echo "    jtag:   Compile for JTAG/SWD upload (overwrites bootloader)"
  152
+	@echo ""
  153
+	@echo "Other targets:"
  154
+	@echo "    clean: Remove all build and object files"
  155
+	@echo "    doxygen: Build Doxygen HTML and XML documentation"
  156
+	@echo "    help: Show this message"
  157
+	@echo "    mrproper: Remove all generated files"
  158
+	@echo ""
159 159
 
160 160
 cscope:
161  
-	rm -rf *.cscope
  161
+	rm -rf cscope.*
162 162
 	find . -name '*.[hcS]' -o -name '*.cpp' | xargs cscope -b
163 163
 
164 164
 tags:
@@ -180,3 +180,7 @@ jtag:
180 180
 
181 181
 doxygen:
182 182
 	doxygen $(SUPPORT_PATH)/doxygen/Doxyfile
  183
+
  184
+# This output is kind of ugly, but I don't understand make very well.
  185
+list-boards:
  186
+	@echo " $(addsuffix "\\n",$(basename $(notdir $(wildcard $(BOARD_INCLUDE_DIR)/*.mk))))"
1  README
@@ -122,7 +122,6 @@ Repository Layout
122 122
     gdb/              GDB scripts.
123 123
     ld/               Linker scripts.
124 124
     make/             Additional scripts used by the top-level Makefile.
125  
-    openocd/          OpenOCD scripts for JTAG debugging.
126 125
     scripts/          Miscellany.
127 126
     doxygen/          Doxygen configuration.
128 127
     stm32loader.py    Script for uploading via the built-in USART bootloader.
0  support/openocd/debug_0.3.cfg → contrib/openocd/debug_0.3.cfg
File renamed without changes
0  support/openocd/debug_0.4.cfg → contrib/openocd/debug_0.4.cfg
File renamed without changes
0  support/openocd/flash_0.3.cfg → contrib/openocd/flash_0.3.cfg
File renamed without changes
0  support/openocd/flash_0.4.cfg → contrib/openocd/flash_0.4.cfg
File renamed without changes
0  support/scripts/openocd-wrapper.sh → contrib/openocd/openocd-wrapper.sh
File renamed without changes
2  examples/blinky.cpp
... ...
@@ -1,6 +1,6 @@
1 1
 // Blinks the built-in LED
2 2
 
3  
-#include "wirish.h"
  3
+#include <wirish/wirish.h>
4 4
 
5 5
 void setup() {
6 6
     pinMode(BOARD_LED_PIN, OUTPUT);
12  examples/debug-dtrrts.cpp
... ...
@@ -1,7 +1,7 @@
1 1
 // Test sketch for figuring out DTR/RTS behavior on different platforms.
2 2
 
3  
-#include "wirish.h"
4  
-#include "usb.h"
  3
+#include <wirish/wirish.h>
  4
+#include "usb_cdcacm.h"
5 5
 
6 6
 void setup() {
7 7
     /* Set up the LED to blink  */
@@ -10,7 +10,6 @@ void setup() {
10 10
     /* Send a message out USART2  */
11 11
     Serial2.begin(9600);
12 12
     Serial2.println("Debugging DTR/RTS...");
13  
-
14 13
 }
15 14
 
16 15
 void loop() {
@@ -18,9 +17,9 @@ void loop() {
18 17
     delay(100);
19 18
 
20 19
     Serial2.print("DTR: ");
21  
-    Serial2.print(usbGetDTR(), DEC);
  20
+    Serial2.print(usb_cdcacm_get_dtr(), DEC);
22 21
     Serial2.print("\tRTS: ");
23  
-    Serial2.println(usbGetRTS(), DEC);
  22
+    Serial2.println(usb_cdcacm_get_rts(), DEC);
24 23
 }
25 24
 
26 25
 // Force init to be called *first*, i.e. before static object allocation.
@@ -32,9 +31,8 @@ __attribute__((constructor)) void premain() {
32 31
 int main(void) {
33 32
     setup();
34 33
 
35  
-    while (1) {
  34
+    while (true) {
36 35
         loop();
37 36
     }
38 37
     return 0;
39 38
 }
40  
-
2  examples/freertos-blinky.cpp
... ...
@@ -1,4 +1,4 @@
1  
-#include "wirish.h"
  1
+#include <wirish/wirish.h>
2 2
 #include "libraries/FreeRTOS/MapleFreeRTOS.h"
3 3
 
4 4
 static void vLEDFlashTask(void *pvParameters) {
6  examples/fsmc-stress-test.cpp
@@ -12,9 +12,9 @@
12 12
 #include <stdio.h>
13 13
 #include <stddef.h>
14 14
 
15  
-#include "wirish.h"
16  
-#include "rcc.h"
17  
-#include "fsmc.h"
  15
+#include <wirish/wirish.h>
  16
+#include <libmaple/rcc.h>
  17
+#include <libmaple/fsmc.h>
18 18
 
19 19
 // -- SRAM config -------------------------------------------------------------
20 20
 
145  examples/i2c-mcp4725-dac.cpp
... ...
@@ -0,0 +1,145 @@
  1
+// i2c-mcp4725-dac.cpp
  2
+//
  3
+// Written by Andrew Meyer <ajm@leaflabs.com>
  4
+// Modified by Marti Bolivar <mbolivar@leaflabs.com>
  5
+//
  6
+// Simple program showing how to control an MCP4725 DAC using the
  7
+// libmaple I2C interface. There's an MCP4725 breakout board available
  8
+// on SparkFun:
  9
+//
  10
+// http://www.sparkfun.com/products/8736
  11
+//
  12
+// How to use:
  13
+//
  14
+// 1. Connect the DAC SDA and SCL pins to I2C2, with a pullup
  15
+//    resistor (1 KOhm should work) to VCC.
  16
+// 2. Load the sketch and connect to SerialUSB.
  17
+// 3. Press the button.
  18
+//
  19
+// The program then makes sure the DAC is connected properly (during
  20
+// setup()), then has the DAC output a sawtooth wave (with loop()).
  21
+
  22
+#include <wirish/wirish.h>
  23
+#include <libmaple/i2c.h>
  24
+
  25
+#define MCP_ADDR         0x60
  26
+#define MCP_WRITE_DAC    0b01000000
  27
+#define MCP_WRITE_EEPROM 0b01100000
  28
+#define MCP_PD_NORMAL    0b00000000
  29
+#define MCP_PD_1K        0b00000010
  30
+#define MCP_PD_100K      0b00000100
  31
+#define MCP_PD_500K      0b00000110
  32
+
  33
+static uint8 write_msg_data[3];
  34
+static i2c_msg write_msg;
  35
+
  36
+static uint8 read_msg_data[5];
  37
+static i2c_msg read_msg;
  38
+
  39
+/*
  40
+ * DAC control routines
  41
+ */
  42
+
  43
+void mcp_i2c_setup(void) {
  44
+    write_msg.addr = MCP_ADDR;
  45
+    write_msg.flags = 0; // write, 7 bit address
  46
+    write_msg.length = sizeof(write_msg_data);
  47
+    write_msg.xferred = 0;
  48
+    write_msg.data = write_msg_data;
  49
+
  50
+    read_msg.addr = MCP_ADDR;
  51
+    read_msg.flags = I2C_MSG_READ;
  52
+    read_msg.length = sizeof(read_msg_data);
  53
+    read_msg.xferred = 0;
  54
+    read_msg.data = read_msg_data;
  55
+}
  56
+
  57
+void mcp_write_val(uint16 val) {
  58
+    write_msg_data[0] = MCP_WRITE_DAC | MCP_PD_NORMAL;
  59
+    uint16 tmp = val >> 4;
  60
+    write_msg_data[1] = tmp;
  61
+    tmp = (val << 4) & 0x00FF;
  62
+    write_msg_data[2] = tmp;
  63
+
  64
+    i2c_master_xfer(I2C2, &write_msg, 1, 0);
  65
+}
  66
+
  67
+uint16 mcp_read_val() {
  68
+    uint16 tmp = 0;
  69
+
  70
+    i2c_master_xfer(I2C2, &read_msg, 1, 2);
  71
+
  72
+    /* We don't care about the status and EEPROM bytes (0, 3, and 4). */
  73
+    tmp = (read_msg_data[1] << 4);
  74
+    tmp += (read_msg_data[2] >> 4);
  75
+    return tmp;
  76
+}
  77
+
  78
+int mcp_test() {
  79
+    uint16 val;
  80
+    uint16 test_val = 0x0101;
  81
+
  82
+    SerialUSB.println("Testing the MCP4725...");
  83
+    /* Read the value of the register (should be 0x0800 if factory fresh) */
  84
+    val = mcp_read_val();
  85
+    SerialUSB.print("DAC Register = 0x");
  86
+    SerialUSB.println(val, HEX);
  87
+
  88
+    mcp_write_val(test_val);
  89
+    SerialUSB.print("Wrote 0x");
  90
+    SerialUSB.print(test_val, HEX);
  91
+    SerialUSB.println(" to the DAC");
  92
+
  93
+    val = mcp_read_val();
  94
+    SerialUSB.print("DAC Register = 0x");
  95
+    SerialUSB.println(val, HEX);
  96
+
  97
+    if (val != test_val) {
  98
+        SerialUSB.println("ERROR: MCP4725 not responding correctly");
  99
+        return 0;
  100
+    }
  101
+
  102
+    SerialUSB.println("MCP4725 seems to be working");
  103
+    return 1;
  104
+}
  105
+
  106
+/*
  107
+ * setup() and loop()
  108
+ */
  109
+
  110
+void setup() {
  111
+    pinMode(BOARD_BUTTON_PIN, INPUT);
  112
+    i2c_master_enable(I2C2, 0);
  113
+    mcp_i2c_setup();
  114
+
  115
+    waitForButtonPress();
  116
+    ASSERT(mcp_test());
  117
+
  118
+    SerialUSB.println("Starting sawtooth wave");
  119
+}
  120
+
  121
+void loop() {
  122
+    static uint16 dout = 0;
  123
+
  124
+    mcp_write_val(dout);
  125
+
  126
+    dout += 50;
  127
+    if (dout >= 32768) {
  128
+        dout = 0;
  129
+    }
  130
+}
  131
+
  132
+// -- init() and main() -------------------------------------------------------
  133
+
  134
+__attribute__((constructor)) void premain() {
  135
+    init();
  136
+}
  137
+
  138
+int main(void) {
  139
+    setup();
  140
+
  141
+    while (true) {
  142
+        loop();
  143
+    }
  144
+    return 0;
  145
+}
2  examples/mini-exti-test.cpp
@@ -10,7 +10,7 @@
10 10
 #include <stdio.h>
11 11
 #include <string.h>
12 12
 
13  
-#include "wirish.h"
  13
+#include <wirish/wirish.h>
14 14
 
15 15
 // test routines
16 16
 void run_exti_test(void);
2  examples/qa-slave-shield.cpp
... ...
@@ -1,6 +1,6 @@
1 1
 // Slave mode for Quality Assurance test
2 2
 
3  
-#include "wirish.h"
  3
+#include <wirish/wirish.h>
4 4
 
5 5
 #define INTER_TOGGLE_DELAY_NORMAL 5
6 6
 #define INTER_TOGGLE_DELAY_SLOW   80
30  examples/serial-echo.cpp
... ...
@@ -0,0 +1,30 @@
  1
+// Simple serial port "echo". Send back any received data.
  2
+
  3
+#include <wirish/wirish.h>
  4
+
  5
+// Note: you can change "Serial1" to any other serial port you have on
  6
+// your board.
  7
+
  8
+void setup() {
  9
+    Serial1.begin(115200);
  10
+}
  11
+
  12
+void loop() {
  13
+    while (Serial1.available()) {
  14
+        Serial1.write(Serial1.read());
  15
+    }
  16
+}
  17
+
  18
+// Force init() to be called before anything else.
  19
+__attribute__((constructor)) void premain() {
  20
+    init();
  21
+}
  22
+
  23
+int main(void) {
  24
+    setup();
  25
+
  26
+    while (true) {
  27
+        loop();
  28
+    }
  29
+    return 0;
  30
+}
2  examples/spi_master.cpp
@@ -33,7 +33,7 @@
33 33
  * Pin 10 is used as slave select.
34 34
  */
35 35
 
36  
-#include "wirish.h"
  36
+#include <wirish/wirish.h>
37 37
 
38 38
 #define NSS 10
39 39
 
6  examples/test-bkp.cpp
... ...
@@ -1,8 +1,8 @@
1 1
 #include <stdio.h>              // for snprintf()
2 2
 
3  
-#include "wirish.h"
4  
-#include "bkp.h"
5  
-#include "iwdg.h"
  3
+#include <wirish/wirish.h>
  4
+#include <libmaple/bkp.h>
  5
+#include <libmaple/iwdg.h>
6 6
 
7 7
 void print_bkp_contents();
8 8
 void write_to_bkp(uint16 val);
4  examples/test-dac.cpp
@@ -6,8 +6,8 @@
6 6
  * This file is released into the public domain.
7 7
  */
8 8
 
9  
-#include "wirish.h"
10  
-#include "dac.h"
  9
+#include <wirish/wirish.h>
  10
+#include <libmaple/dac.h>
11 11
 
12 12
 uint16 count = 0;
13 13
 
4  examples/test-fsmc.cpp
... ...
@@ -1,7 +1,7 @@
1 1
 #include <stddef.h>             // for ptrdiff_t
2 2
 
3  
-#include "wirish.h"
4  
-#include "fsmc.h"
  3
+#include <wirish/wirish.h>
  4
+#include <libmaple/fsmc.h>
5 5
 
6 6
 #ifndef BOARD_maple_native
7 7
 #error "Sorry, this example only works on Maple Native."
2  examples/test-print.cpp
@@ -8,7 +8,7 @@
8 8
  * This file is released into the public domain.
9 9
  */
10 10
 
11  
-#include "wirish.h"
  11
+#include <wirish/wirish.h>
12 12
 #undef min
13 13
 #undef max
14 14
 
4  examples/test-ring-buffer-insertion.cpp
@@ -12,9 +12,9 @@
12 12
  * This file is released into the public domain.
13 13
  */
14 14
 
15  
-#include "wirish.h"
  15
+#include <wirish/wirish.h>
16 16
 
17  
-#include "ring_buffer.h"
  17
+#include <libmaple/ring_buffer.h>
18 18
 
19 19
 #define BUF_SIZE 64
20 20
 ring_buffer ring_buf;
2  examples/test-serial-flush.cpp
@@ -2,7 +2,7 @@
2 2
  * Tests the "flush" Serial function.
3 3
  */
4 4
 
5  
-#include "wirish.h"
  5
+#include <wirish/wirish.h>
6 6
 
7 7
 void setup() {
8 8
     Serial1.begin(9600);
6  examples/test-serialusb.cpp
... ...
@@ -1,7 +1,7 @@
1 1
 // Tests SerialUSB functionality.
2 2
 
3  
-#include "wirish.h"
4  
-#include "usb.h"
  3
+#include <wirish/wirish.h>
  4
+#include "usb_cdcacm.h"
5 5
 
6 6
 #define QUICKPRINT  0
7 7
 #define BIGSTUFF    1
@@ -37,7 +37,7 @@ void loop() {
37 37
     switch (state) {
38 38
         case QUICKPRINT:
39 39
             for (int i = 0; i < 30; i++) {
40  
-                usbSendBytes(&c1, 1);
  40
+                usb_cdcacm_putc((char)c1, 1);
41 41
                 SerialUSB.print('.');
42 42
                 SerialUSB.print('|');
43 43
             }
2  examples/test-servo.cpp
@@ -29,7 +29,7 @@
29 29
 
30 30
 #include <stdio.h>
31 31
 
32  
-#include "wirish.h"
  32
+#include <wirish/wirish.h>
33 33
 
34 34
 #include "libraries/Servo/Servo.h"
35 35
 
2  examples/test-session.cpp
@@ -4,7 +4,7 @@
4 4
 // Useful for testing Maple features and troubleshooting.
5 5
 // Communicates over SerialUSB.
6 6
 
7  
-#include "wirish.h"
  7
+#include <wirish/wirish.h>
8 8
 
9 9
 // ASCII escape character
10 10
 #define ESC       ((uint8)27)
2  examples/test-spi-roundtrip.cpp
@@ -17,7 +17,7 @@
17 17
  * Author: Marti Bolivar <mbolivar@leaflabs.com>
18 18
  */
19 19
 
20  
-#include "wirish.h"
  20
+#include <wirish/wirish.h>
21 21
 
22 22
 HardwareSPI alice(2);
23 23
 
4  examples/test-systick.cpp
... ...
@@ -1,7 +1,7 @@
1 1
 // Tests the SysTick enable/disable functions
2 2
 
3  
-#include "wirish.h"
4  
-#include "systick.h"
  3
+#include <wirish/wirish.h>
  4
+#include <libmaple/systick.h>
5 5
 
6 6
 void setup() {
7 7
     pinMode(BOARD_LED_PIN, OUTPUT);
710  examples/test-timers.cpp
... ...
@@ -1,288 +1,528 @@
1  
-// Program to test the timer.h implementation's essential functionality.
2  
-
3  
-#include "wirish.h"
4  
-#include "timer.h"
5  
-
6  
-void handler1(void);
7  
-void handler2(void);
8  
-void handler3(void);
9  
-void handler4(void);
10  
-
11  
-void handler3b(void);
12  
-void handler4b(void);
13  
-
14  
-int t;
15  
-
16  
-int count1 = 0;
17  
-int count2 = 0;
18  
-int count3 = 0;
19  
-int count4 = 0;
20  
-uint16 rate1 = 1000;
21  
-uint16 rate2 = 2000;
22  
-uint16 rate3 = 4000;
23  
-uint16 rate4 = 8000;
24  
-uint16 val1 = 10000;
25  
-uint16 val2 = 10000;
26  
-uint16 val3 = 10000;
27  
-uint16 val4 = 10000;
28  
-
29  
-// FIXME [0.1.0] high density timer test (especially basic timers + DAC)
30  
-timer_dev *timers[] = {TIMER1, TIMER2, TIMER3, TIMER4};
31  
-voidFuncPtr handlers[] = {handler1, handler2, handler3, handler4};
32  
-
33  
-void initTimer(timer_dev *dev);
34  
-void setTimerPeriod(timer_dev *dev, uint32 period_us);
35  
-void testSetTimerPeriod(uint32 period);
36  
-void testTimerChannels(timer_dev *dev);
37  
-int timerNumber(timer_dev *dev);
  1
+//
  2
+// This is a mostly Wirish-free timer test. Wirish usage is minimized
  3
+// because this is a test of the C timer interface in
  4
+// <libmaple/timer.h>, so it's good if it can be made to work even
  5
+// when most or all of Wirish is missing. Because of that, you may
  6
+// need to customize the following output configuration:
  7
+//
  8
+// Output is printed:
  9
+// - on COMM_USART,
  10
+// - via TX pin on port COMM_USART_PORT, bit COMM_USART_TX_BIT
  11
+// - via RX pin on port COMM_USART_PORT, bit COMM_USART_RX_BIT
  12
+// - at COMM_USART_BAUD baud.
  13
+#define COMM_USART USART6
  14
+#define COMM_USART_BAUD 115200
  15
+#define COMM_USART_PORT GPIOG
  16
+#define COMM_USART_TX_BIT 14
  17
+#define COMM_USART_RX_BIT 9
  18
+// Other optional configuration below.
  19
+
  20
+#include <libmaple/libmaple.h>
  21
+#include <libmaple/gpio.h>
  22
+#include <libmaple/usart.h>
  23
+#include <libmaple/systick.h>
  24
+#include <libmaple/timer.h>
  25
+#include <wirish/boards.h>
  26
+
  27
+//
  28
+// Configuration
  29
+//
  30
+
  31
+// More output if true
  32
+static bool verbose = true;
  33
+
  34
+// Timers to test
  35
+// FIXME use feature test macros for smaller MCUs
  36
+static timer_dev *timers[] = {
  37
+    // Available on all currently supported MCUs
  38
+    TIMER1, TIMER2, TIMER3, TIMER4,
  39
+    // Available on F1 (HD and up), F2
  40
+    TIMER5, TIMER6, TIMER7, TIMER8,
  41
+    // Available on F1 (XL), F2
  42
+    TIMER9, TIMER10, TIMER11, TIMER12, TIMER13, TIMER14,
  43
+};
  44
+
  45
+//
  46
+// Test routines
  47
+//
  48
+
  49
+typedef void (*timer_test_t)(timer_dev *);
  50
+
  51
+static void runTest(const char description[], timer_test_t test);
  52
+static void runTests(void);
  53
+
  54
+static void testGetAndSetCount(timer_dev*);
  55
+static void testPauseAndResume(timer_dev*);
  56
+static void testTimerChannels(timer_dev*);
  57
+
  58
+//
  59
+// Helpers
  60
+//
  61
+
  62
+static void initTimer(timer_dev *dev);
  63
+static int timerNumber(timer_dev *dev);
  64
+// Hack: a systick-based delay, useful until delay_us() is fixed
  65
+static void _delay(uint32 msec);
  66
+// Wirish-less USART initialization routine
  67
+static void init_usart(usart_dev *dev, gpio_dev *gdev, uint8 tx, uint8 rx);
  68
+// Return whether or not the timer has capture/compare channel `ch'.
  69
+// TODO: does something like this belong in the standard timer library?
  70
+static bool timer_has_cc_ch(timer_dev *dev, int ch);
  71
+
  72
+// Printing routines and variants for verbose mode
  73
+static void putstr(const char str[]);
  74
+static void println(void);
  75
+static void putstrln(const char str[]);
  76
+static void putudec(uint32 val);
  77
+static void puttimn(timer_dev *dev);
  78
+static void v_putstr(const char str[]);
  79
+static void v_println();
  80
+static void v_putstrln(const char str[]);
  81
+static void v_putudec(uint32 val);
  82
+static void v_puttimn(timer_dev *dev);
  83
+// Used to visually separate output from different tests
  84
+static void printBanner(void);
  85
+
  86
+//
  87
+// Handler state
  88
+//
  89
+
  90
+static int count1 = 0;
  91
+static int count2 = 0;
  92
+static int count3 = 0;
  93
+static int count4 = 0;
  94
+static int timer_num; // Current timer we're considering
  95
+
  96
+//
  97
+// Timer capture/compare interrupt handlers
  98
+//
  99
+// These are shared between timers. The global variable timer_num
  100
+// controls which timer they affect.
  101
+//
  102
+
  103
+static void handler1(void);
  104
+static void handler2(void);
  105
+static void handler3(void);
  106
+static void handler4(void);
  107
+static voidFuncPtr handlers[] = {handler1, handler2, handler3, handler4};
  108
+
  109
+//
  110
+// setup() and loop()
  111
+//
38 112
 
39 113
 void setup() {
40  
-    // Set up the LED to blink
41  
-    pinMode(BOARD_LED_PIN, OUTPUT);
42  
-
43  
-    // Setup the button as input
44  
-    pinMode(BOARD_BUTTON_PIN, INPUT);
45  
-
46  
-    // Send a message out Serial2
47  
-    Serial2.begin(115200);
48  
-    Serial2.println("*** Initializing timers...");
  114
+    init_usart(COMM_USART, COMM_USART_PORT,
  115
+               COMM_USART_TX_BIT, COMM_USART_RX_BIT);
  116
+    _delay(5);
  117
+    println();
  118
+    printBanner();
  119
+    putstr("Initializing timers...\r\n");
49 120
     timer_foreach(initTimer);
50  
-    Serial2.println("*** Done. Beginning timer test.");
  121
+    putstr("Done. Running tests.\r\n");
  122
+    runTests();
  123
+    printBanner();
  124
+    putstr("Done testing timers.\r\n");
51 125
 }
52 126
 
53 127
 void loop() {
54  
-    Serial2.println("-----------------------------------------------------");
55  
-
56  
-    Serial2.println("Testing timer_get_count()/timer_set_count()");
57  
-    Serial2.print("TIMER1 count = ");
58  
-    Serial2.println(timer_get_count(TIMER1));
59  
-    Serial2.println("timer_set_count(TIMER1, 1234)");
60  
-    timer_set_count(TIMER1, 1234);
61  
-    Serial2.print("timer_get_count(TIMER1) = ");
62  
-    Serial2.println(timer_get_count(TIMER1));
63  
-
64  
-    Serial2.println("-----------------------------------------------------");
65  
-    Serial2.println("Testing pause/resume; button roughly controls TIMER4");
66  
-    // when BUT is held down, TIMER4 is in the "pause" state and the
67  
-    // timer doesn't increment, so the final counts should reflect the
68  
-    // ratio of time that BUT was held down.
69  
-    count3 = 0;
70  
-    count4 = 0;
71  
-    timer_set_mode(TIMER3, TIMER_CH1, TIMER_OUTPUT_COMPARE);
72  
-    timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE);
73  
-    timer_pause(TIMER3);
74  
-    timer_pause(TIMER4);
75  
-    timer_set_count(TIMER3, 0);
76  
-    timer_set_count(TIMER4, 0);
77  
-    timer_set_reload(TIMER3, 30000);
78  
-    timer_set_reload(TIMER4, 30000);
79  
-    timer_set_compare(TIMER3, 1, 1000);
80  
-    timer_set_compare(TIMER4, 1, 1000);
81  
-    timer_attach_interrupt(TIMER3, TIMER_CC1_INTERRUPT, handler3b);
82  
-    timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b);
83  
-    timer_resume(TIMER3);
84  
-    timer_resume(TIMER4);
85  
-
86  
-    Serial2.println("Testing for ~4 seconds...");
87  
-    for(int i = 0; i < 4000; i++) {
88  
-        if (isButtonPressed()) {
89  
-            timer_pause(TIMER4);
90  
-        } else {
91  
-            timer_resume(TIMER4);
92  
-        }
93  
-        delay(1);
94  
-    }
  128
+}
95 129
 
96  
-    timer_set_mode(TIMER3, TIMER_CH1, TIMER_DISABLED);
97  
-    timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED);
98  
-
99  
-    Serial2.print("TIMER3 count: ");
100  
-    Serial2.println(timer_get_count(TIMER3));
101  
-    Serial2.print("TIMER4 count: ");
102  
-    Serial2.println(timer_get_count(TIMER4));
103  
-
104  
-    Serial2.println("-----------------------------------------------------");
105  
-    Serial2.println("Testing setTimerPeriod()");
106  
-    testSetTimerPeriod(10);
107  
-    testSetTimerPeriod(30000);
108  
-    testSetTimerPeriod(300000);
109  
-    testSetTimerPeriod(30000);
110  
-
111  
-    Serial2.println("Sanity check (with hand-coded reload and prescaler for "
112  
-                    "72 MHz timers):");
113  
-    timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE);
114  
-    timer_set_prescaler(TIMER4, 33);
115  
-    timer_set_reload(TIMER4, 65454);
116  
-    timer_pause(TIMER4);
117  
-    timer_set_count(TIMER4, 0);
118  
-    timer_set_compare(TIMER4, TIMER_CH1, 1);
119  
-    timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b);
120  
-    Serial2.println("Period 30000ms, wait 2 seconds...");
121  
-    count4 = 0;
122  
-    timer_resume(TIMER4);
123  
-    delay(2000);
124  
-    timer_pause(TIMER4);
125  
-    timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED);
126  
-    Serial2.print("TIMER4 count: ");
127  
-    Serial2.println(count4);
128  
-    Serial2.println("  (Should be around 2sec/30000ms ~ 67)");
129  
-
130  
-    // Test all the individual timer channels
131  
-    timer_foreach(testTimerChannels);
  130
+//
  131
+// Test routine implementations
  132
+//
  133
+
  134
+static void runTests(void) {
  135
+    runTest("timer_get_count()/timer_set_count()", testGetAndSetCount);
  136
+    runTest("timer_pause()/timer_resume()", testPauseAndResume);
  137
+    runTest("capture/compare channels and interrupts",
  138
+            testTimerChannels);
132 139
 }
133 140
 
134  
-void initTimer(timer_dev *dev) {
135  
-    switch (dev->type) {
136  
-    case TIMER_ADVANCED:
137  
-    case TIMER_GENERAL:
138  
-        Serial2.print("Initializing timer ");
139  
-        Serial2.println(timerNumber(dev));
140  
-        for (int c = 1; c <= 4; c++) {
141  
-            timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE);
142  
-        }
143  
-        Serial2.println("Done.");
144  
-        break;
145  
-    case TIMER_BASIC:
146  
-        break;
  141
+static void runTest(const char description[], timer_test_t test) {
  142
+    printBanner();
  143
+    putstr("Testing ");
  144
+    putstr(description);
  145
+    putstrln(".");
  146
+    timer_foreach(test);
  147
+}
  148
+
  149
+static void testGetAndSetCount(timer_dev *dev) {
  150
+    unsigned before, after;
  151
+    unsigned val_to_set = 1234;
  152
+
  153
+    timer_pause(dev);
  154
+    before = timer_get_count(dev);
  155
+    timer_set_count(dev, val_to_set);
  156
+    after = timer_get_count(dev);
  157
+    timer_resume(dev);
  158
+
  159
+    if (after != val_to_set) {
  160
+        puttimn(dev);
  161
+        putstr(": ");
  162
+        putstr("*** FAIL: get/set count for ");
  163
+        puttimn(dev);
  164
+        putstr(".");
  165
+        putstr("Start count = ");
  166
+        putudec(before);
  167
+        putstr(". Count set to ");
  168
+        putudec(val_to_set);
  169
+        putstr(", and now count is = ");
  170
+        putudec(after);
  171
+        println();
  172
+    } else if (verbose) {
  173
+        puttimn(dev);
  174
+        putstr(": ");
  175
+        putstrln("[ok]");
147 176
     }
148 177
 }
149 178
 
150  
-void testSetTimerPeriod(uint32 period) {
151  
-    timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE);
152  
-    timer_set_compare(TIMER4, TIMER_CH1, 1);
153  
-    setTimerPeriod(TIMER4, period);
154  
-    timer_pause(TIMER4);
155  
-    timer_set_count(TIMER4, 0);
156  
-    timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b);
157  
-    Serial2.println("Period ");
158  
-    Serial2.print(period);
159  
-    Serial2.print(" ms. Waiting 2 seconds...");
160  
-    count4 = 0;
161  
-    timer_resume(TIMER4);
162  
-    delay(2000);
163  
-    timer_pause(TIMER4);
164  
-    timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED);
165  
-    Serial2.print("TIMER4 count: ");
166  
-    Serial2.println(timer_get_count(TIMER4));
167  
-    Serial2.print("  (Should be around 2 sec / ");
168  
-    Serial2.print(period);
169  
-    Serial2.print(" ms = ");
170  
-    Serial2.print(double(2) / period * 1000);
171  
-    Serial2.println(", modulo delays due to interrupts)");
  179
+// This hack works on all currently supported STM32 series, but you
  180
+// may need to do something smarter in the future. The assertions
  181
+// ensure that our assumptions hold for your target.
  182
+static timer_dev *getDifferentTimerOnSameBusAs(timer_dev *dev) {
  183
+    rcc_clk_domain dev_domain = rcc_dev_clk(dev->clk_id);
  184
+    ASSERT(RCC_APB1 == dev_domain || RCC_APB2 == dev_domain);
  185
+    ASSERT(rcc_dev_clk(TIMER1->clk_id) == RCC_APB2);
  186
+    ASSERT(rcc_dev_clk(TIMER2->clk_id) == RCC_APB1);
  187
+    ASSERT(rcc_dev_clk(TIMER8->clk_id) == RCC_APB2);
  188
+    ASSERT(rcc_dev_clk(TIMER3->clk_id) == RCC_APB1);
  189
+
  190
+    if (dev->clk_id == RCC_TIMER1) {
  191
+        return TIMER8;
  192
+    }
  193
+    if (dev->clk_id == RCC_TIMER2) {
  194
+        return TIMER3;
  195
+    }
  196
+    return dev_domain == RCC_APB2 ? TIMER1 : TIMER2;
172 197
 }
173 198
 
174  
-int timerNumber(timer_dev *dev) {
175  
-    switch (dev->clk_id) {
176  
-    case RCC_TIMER1:
177  
-        return 1;
178  
-    case RCC_TIMER2:
179  
-        return 2;
180  
-    case RCC_TIMER3:
181  
-        return 3;
182  
-    case RCC_TIMER4:
183  
-        return 4;
184  
-#ifdef STM32_HIGH_DENSITY
185  
-    case RCC_TIMER5:
186  
-        return 5;
187  
-    case RCC_TIMER6:
188  
-        return 6;
189  
-    case RCC_TIMER7:
190  
-        return 7;
191  
-    case RCC_TIMER8:
192  
-        return 8;
193  
-#endif
194  
-    default:
195  
-        ASSERT(0);
196  
-        return 0;
  199
+// Rough test of pause and resume.
  200
+//
  201
+// Approximately half the time, dev is in the "pause" state and the
  202
+// timer doesn't increment, while another timer (`base_dev') on the
  203
+// same bus continues. dev and base_dev have identical start counts
  204
+// and prescalers.
  205
+//
  206
+// Since dev and base_dev share a bus (and thus a base clock), and we
  207
+// configure them to have the same prescaler and start count, the
  208
+// ratio of their end counts should be approximately 1 : 2. We check
  209
+// to make sure this is true, up to tolerance `epsilon'.
  210
+static void testPauseAndResume(timer_dev *dev) {
  211
+    timer_dev *base_dev = getDifferentTimerOnSameBusAs(dev);
  212
+    unsigned start_count = 0, reload = 65535;
  213
+    // This prescaler should be enough to ensure that we don't
  214
+    // overflow, while still giving us a reasonably large number of
  215
+    // timer ticks.
  216
+    uint16 prescaler = CYCLES_PER_MICROSECOND * 50;
  217
+    double epsilon = .02;
  218
+
  219
+    if (rcc_dev_clk(base_dev->clk_id) != rcc_dev_clk(dev->clk_id)) {
  220
+        putstrln("*** ERROR: cannot run test. Bus info is messed up.");
  221
+        return;
  222
+    }
  223
+
  224
+    // Pause and set up timers
  225
+    timer_pause(base_dev);
  226
+    timer_pause(dev);
  227
+    timer_set_count(base_dev, start_count);
  228
+    timer_set_count(dev, start_count);
  229
+    timer_set_reload(base_dev, reload);
  230
+    timer_set_reload(dev, reload);
  231
+    timer_set_prescaler(base_dev, prescaler);
  232
+    timer_set_prescaler(dev, prescaler);