소스 검색

Merge branch 'wip-family-support'

Marti Bolivar 5 년 전
부모
커밋
ccc2336971
100개의 변경된 파일6946개의 추가작업 그리고 3516개의 파일을 삭제
  1. 2 1
      .gitignore
  2. 58 54
      Makefile
  3. 0 1
      README
  4. 0 0
      contrib/openocd/debug_0.3.cfg
  5. 0 0
      contrib/openocd/debug_0.4.cfg
  6. 0 0
      contrib/openocd/flash_0.3.cfg
  7. 0 0
      contrib/openocd/flash_0.4.cfg
  8. 0 0
      contrib/openocd/openocd-wrapper.sh
  9. 1 1
      examples/blinky.cpp
  10. 5 7
      examples/debug-dtrrts.cpp
  11. 1 1
      examples/freertos-blinky.cpp
  12. 3 3
      examples/fsmc-stress-test.cpp
  13. 145 0
      examples/i2c-mcp4725-dac.cpp
  14. 1 1
      examples/mini-exti-test.cpp
  15. 1 1
      examples/qa-slave-shield.cpp
  16. 30 0
      examples/serial-echo.cpp
  17. 1 1
      examples/spi_master.cpp
  18. 3 3
      examples/test-bkp.cpp
  19. 2 2
      examples/test-dac.cpp
  20. 2 2
      examples/test-fsmc.cpp
  21. 1 1
      examples/test-print.cpp
  22. 2 2
      examples/test-ring-buffer-insertion.cpp
  23. 1 1
      examples/test-serial-flush.cpp
  24. 3 3
      examples/test-serialusb.cpp
  25. 1 1
      examples/test-servo.cpp
  26. 1 1
      examples/test-session.cpp
  27. 1 1
      examples/test-spi-roundtrip.cpp
  28. 2 2
      examples/test-systick.cpp
  29. 475 235
      examples/test-timers.cpp
  30. 154 66
      examples/test-usart-dma.cpp
  31. 1 1
      examples/vga-leaf.cpp
  32. 2 2
      examples/vga-scope.cpp
  33. 11 67
      libmaple/adc.c
  34. 11 17
      libmaple/dac.c
  35. 0 168
      libmaple/dac.h
  36. 0 30
      libmaple/delay.h
  37. 33 330
      libmaple/dma.c
  38. 0 453
      libmaple/dma.h
  39. 61 0
      libmaple/dma_private.h
  40. 38 25
      libmaple/exti.c
  41. 34 0
      libmaple/exti_private.h
  42. 8 14
      libmaple/flash.c
  43. 5 152
      libmaple/gpio.c
  44. 216 272
      libmaple/i2c.c
  45. 79 0
      libmaple/i2c_private.h
  46. 79 114
      libmaple/include/libmaple/adc.h
  47. 15 7
      libmaple/include/libmaple/bitband.h
  48. 7 7
      libmaple/include/libmaple/bkp.h
  49. 158 0
      libmaple/include/libmaple/dac.h
  50. 65 0
      libmaple/include/libmaple/delay.h
  51. 444 0
      libmaple/include/libmaple/dma.h
  52. 114 0
      libmaple/include/libmaple/dma_common.h
  53. 76 12
      libmaple/include/libmaple/exti.h
  54. 106 0
      libmaple/include/libmaple/flash.h
  55. 64 44
      libmaple/include/libmaple/fsmc.h
  56. 121 0
      libmaple/include/libmaple/gpio.h
  57. 229 164
      libmaple/include/libmaple/i2c.h
  58. 95 0
      libmaple/include/libmaple/i2c_common.h
  59. 7 8
      libmaple/include/libmaple/iwdg.h
  60. 14 7
      libmaple/include/libmaple/libmaple.h
  61. 19 4
      libmaple/include/libmaple/libmaple_types.h
  62. 155 0
      libmaple/include/libmaple/nvic.h
  63. 43 13
      libmaple/include/libmaple/pwr.h
  64. 175 0
      libmaple/include/libmaple/rcc.h
  65. 5 6
      libmaple/include/libmaple/ring_buffer.h
  66. 12 4
      libmaple/include/libmaple/scb.h
  67. 91 78
      libmaple/include/libmaple/spi.h
  68. 237 0
      libmaple/include/libmaple/stm32.h
  69. 151 0
      libmaple/include/libmaple/syscfg.h
  70. 7 9
      libmaple/include/libmaple/systick.h
  71. 372 274
      libmaple/include/libmaple/timer.h
  72. 209 50
      libmaple/include/libmaple/usart.h
  73. 6 6
      libmaple/include/libmaple/usb.h
  74. 5 5
      libmaple/include/libmaple/usb_cdcacm.h
  75. 8 8
      libmaple/include/libmaple/util.h
  76. 2 2
      libmaple/iwdg.c
  77. 19 15
      libmaple/nvic.c
  78. 3 3
      libmaple/pwr.c
  79. 116 153
      libmaple/rcc.c
  80. 67 0
      libmaple/rcc_private.h
  81. 23 31
      libmaple/rules.mk
  82. 4 80
      libmaple/spi.c
  83. 37 0
      libmaple/spi_private.h
  84. 0 191
      libmaple/stm32.h
  85. 45 0
      libmaple/stm32_private.h
  86. 112 0
      libmaple/stm32f1/adc.c
  87. 6 6
      libmaple/stm32f1/bkp.c
  88. 412 0
      libmaple/stm32f1/dma.c
  89. 32 0
      libmaple/stm32f1/exti.c
  90. 11 9
      libmaple/stm32f1/fsmc.c
  91. 166 0
      libmaple/stm32f1/gpio.c
  92. 129 0
      libmaple/stm32f1/i2c.c
  93. 254 0
      libmaple/stm32f1/include/series/adc.h
  94. 71 0
      libmaple/stm32f1/include/series/dac.h
  95. 565 0
      libmaple/stm32f1/include/series/dma.h
  96. 46 0
      libmaple/stm32f1/include/series/exti.h
  97. 46 39
      libmaple/stm32f1/include/series/flash.h
  98. 211 245
      libmaple/stm32f1/include/series/gpio.h
  99. 85 0
      libmaple/stm32f1/include/series/i2c.h
  100. 0 0
      libmaple/stm32f1/include/series/nvic.h

+ 2 - 1
.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

+ 58 - 54
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))))"

+ 0 - 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.

support/openocd/debug_0.3.cfg → contrib/openocd/debug_0.3.cfg 파일 보기


support/openocd/debug_0.4.cfg → contrib/openocd/debug_0.4.cfg 파일 보기


support/openocd/flash_0.3.cfg → contrib/openocd/flash_0.3.cfg 파일 보기


support/openocd/flash_0.4.cfg → contrib/openocd/flash_0.4.cfg 파일 보기


support/scripts/openocd-wrapper.sh → contrib/openocd/openocd-wrapper.sh 파일 보기


+ 1 - 1
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);

+ 5 - 7
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
-

+ 1 - 1
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) {

+ 3 - 3
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 - 0
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
+}

+ 1 - 1
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);

+ 1 - 1
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 - 0
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
+}

+ 1 - 1
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
 

+ 3 - 3
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);

+ 2 - 2
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
 

+ 2 - 2
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."

+ 1 - 1
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
 

+ 2 - 2
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;

+ 1 - 1
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);

+ 3 - 3
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
             }

+ 1 - 1
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
 

+ 1 - 1
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)

+ 1 - 1
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
 

+ 2 - 2
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);

+ 475 - 235
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);
233
+    timer_generate_update(base_dev);
234
+    timer_generate_update(dev);
235
+
236
+    // Resume the timers and run the test
237
+    ASSERT(timer_get_count(base_dev) == start_count);
238
+    ASSERT(timer_get_count(dev) == start_count);
239
+    timer_resume(base_dev);
240
+    timer_resume(dev);
241
+    _delay(1000);
242
+    timer_pause(dev);
243
+    _delay(1000);
244
+    timer_pause(base_dev);
245
+
246
+    // Check the results
247
+    unsigned dev_count = timer_get_count(dev);
248
+    unsigned base_count = timer_get_count(base_dev);
249
+    double count_ratio = ((double)dev_count / base_count);
250
+    bool fail = false;
251
+    if (count_ratio > 0.5 + epsilon || count_ratio < 0.5 - epsilon) {
252
+        fail = true;
253
+    }
254
+    if (fail || verbose) {
255
+        puttimn(dev);
256
+        putstr(" vs. ");
257
+        puttimn(base_dev);
258
+        putstr(": ");
259
+        if (fail) putstr("*** FAIL: ");
260
+        else putstr("[ok] ");
261
+        putstr("(dev = ");
262
+        putudec(dev_count);
263
+        putstr(") / (base = ");
264
+        putudec(base_count);
265
+        putstr(") = ");
266
+        // hack hack hack
267
+        putudec((int)count_ratio);
268
+        count_ratio -= (int)count_ratio;
269
+        putstr(".");
270
+        int cr_x_100 = (int)(count_ratio * 100);
271
+        int hundredths = cr_x_100 % 10;
272
+        cr_x_100 /= 10;
273
+        int tenths = cr_x_100 % 10;
274
+        putudec(tenths);
275
+        putudec(hundredths);
276
+        println();
197 277
     }
198 278
 }
199 279
 
200
-/* This function touches every channel of a given timer. The output
201
- * ratios should reflect the ratios of the rate variables.  It
202
- * demonstrates that, over time, the actual timing rates get blown
203
- * away by other system interrupts. */
204
-void testTimerChannels(timer_dev *dev) {
205
-    t = timerNumber(dev);
206
-    toggleLED();
207
-    delay(100);
208
-    Serial2.println("-----------------------------------------------------");
280
+// This function touches every capture/compare channel of a given
281
+// timer.  The channel counts should be equal within a timer
282
+// regardless of other interrupts on the system (note that this
283
+// doesn't really test timers with only a single capture/compare
284
+// channel; for that, you'll want to do visual inspection of timers
285
+// that share a bus, in verbose mode).
286
+static void testTimerChannels(timer_dev *dev) {
209 287
     switch (dev->type) {
210 288
     case TIMER_BASIC:
211
-        Serial2.print("NOT testing channels for basic timer ");
212
-        Serial2.println(t);
213
-        break;
289
+        v_putstr("Skipping basic timer ");
290
+        v_puttimn(dev);
291
+        v_println();
292
+        return;
214 293
     case TIMER_ADVANCED:
215 294
     case TIMER_GENERAL:
216
-        Serial2.print("Testing channels for timer ");
217
-        Serial2.println(t);
295
+        // Set up
296
+        v_puttimn(dev);
297
+        v_println();
298
+        v_putstr("\tchannels: ");
299
+
300
+        timer_num = timerNumber(dev);
218 301
         timer_pause(dev);
219
-        count1 = count2 = count3 = count4 = 0;
302
+        count1 = 0;
303
+        count2 = 0;
304
+        count3 = 0;
305
+        count4 = 0;
220 306
         timer_set_reload(dev, 0xFFFF);
221 307
         timer_set_prescaler(dev, 1);
222 308
         for (int c = 1; c <= 4; c++) {
223
-            timer_set_compare(dev, c, 65535);
224
-            timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE);
225
-            timer_attach_interrupt(dev, c, handlers[c - 1]);
309
+            if (timer_has_cc_ch(dev, c)) {
310
+                v_putudec(c);
311
+                v_putstr("\t");
312
+                timer_set_compare(dev, c, 0xFFFF);
313
+                timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE);
314
+                timer_attach_interrupt(dev, c, handlers[c - 1]);
315
+            }
226 316
         }
317
+        v_println();
318
+
319
+        // Run test
320
+        timer_generate_update(dev);
227 321
         timer_resume(dev);
228
-        delay(3000);
322
+        _delay(250);
323
+        timer_pause(dev);
324
+
325
+        // Print results
326
+        v_putstr("\tcounts:   ");
327
+        bool fail = false;
328
+        bool mismatched[4] = {false, false, false, false};
329
+        int counts[4];
330
+        counts[0] = count1;
331
+        counts[1] = count2;
332
+        counts[2] = count3;
333
+        counts[3] = count4;
334
+        bool first = true;
335
+        int first_count = -1;
336
+        for (int c = 1; c <= 4; c++) {
337
+            if (timer_has_cc_ch(dev, c)) {
338
+                if (first) {
339
+                    first_count = counts[c - 1];
340
+                    first = false;
341
+                }
342
+                if (!first && (counts[c - 1] != first_count)) {
343
+                    mismatched[c - 1] = true;
344
+                    fail = true;
345
+                }
346
+                v_putudec(counts[c - 1]);
347
+                v_putstr("\t");
348
+            }
349
+        }
350
+        v_println();
351
+        if (fail) {
352
+            for (int i = 0; i < 4; i++) {
353
+                if (mismatched[i]) {
354
+                    putstr("*** FAIL: mismatch on ");
355
+                    puttimn(dev);
356
+                    putstr(", channel ");
357
+                    putudec(i + 1);
358
+                    putstr(": expected ");
359
+                    putudec(first_count);
360
+                    putstr(", got ");
361
+                    putudec(counts[i]);
362
+                    println();
363
+                }
364
+            }
365
+        } else {
366
+            puttimn(dev);
367
+            putstrln(" [ok]");
368
+        }
369
+        v_println();
370
+
371
+        // Clean up
229 372
         for (int c = 1; c <= 4; c++) {
230
-            timer_set_mode(dev, c, TIMER_DISABLED);
373
+            if (timer_has_cc_ch(dev, c)) {
374
+                timer_set_mode(dev, c, TIMER_DISABLED);
375
+            }
231 376
         }
232
-        Serial2.print("Channel 1 count: "); Serial2.println(count1);
233
-        Serial2.print("Channel 2 count: "); Serial2.println(count2);
234
-        Serial2.print("Channel 3 count: "); Serial2.println(count3);
235
-        Serial2.print("Channel 4 count: "); Serial2.println(count4);
236 377
         break;
237 378
     }
238 379
 }
239 380
 
240
-// FIXME [0.1.0] move some incarnation of this into timer.h
241
-void setTimerPeriod(timer_dev *dev, uint32 period_us) {
242
-    if (!period_us) {
243
-        // FIXME handle this case
244
-        ASSERT(0);
245
-        return;
246
-    }
381
+//
382
+// Helper implementations
383
+//
247 384
 
248
-    uint32 cycles = period_us * CYCLES_PER_MICROSECOND;
249
-    uint16 pre = (uint16)((cycles >> 16) + 1);
250
-    timer_set_prescaler(dev, pre);
251
-    timer_set_reload(dev, cycles / pre - 1);
385
+static void _delay(uint32 msec) {
386
+    uint32 end = systick_uptime() + msec;
387
+    while (systick_uptime() < end)
388
+        ;
252 389
 }
253 390
 
254
-void handler1(void) {
255
-    val1 += rate1;
256
-    timer_set_compare(timers[t], TIMER_CH1, val1);
257
-    count1++;
391
+static void init_usart(usart_dev *dev, gpio_dev *gdev, uint8 tx, uint8 rx) {
392
+    usart_config_gpios_async(dev, gdev, rx, gdev, tx, 0);
393
+    usart_init(dev);
394
+    usart_set_baud_rate(dev, USART_USE_PCLK, COMM_USART_BAUD);
395
+    usart_enable(dev);
258 396
 }
259 397
 
260
-void handler2(void) {
261
-    val2 += rate2;
262
-    timer_set_compare(timers[t], TIMER_CH2, val2);
263
-    count2++;
398
+static bool timer_has_cc_ch(timer_dev *dev, int ch) {
399
+    ASSERT(1 <= ch && ch <= 4);
400
+    if (dev->type == TIMER_BASIC)
401
+        return false;
402
+    int tn = timerNumber(dev);
403
+    return  (// TIM1-5 and 8 have all four channels
404
+             (tn <= 5 || tn == 8) ||
405
+             // TIM9 and 12 only have channels 1 and 2
406
+             ((tn == 9 || tn == 12) && ch <= 2) ||
407
+             // All other general purpose timers only have channel 1
408
+             (ch == 1));
264 409
 }
265 410
 
266
-void handler3(void) {
267
-    val3 += rate3;
268
-    timer_set_compare(timers[t], TIMER_CH3, val3);
269
-    count3++;
411
+static void putstr(const char str[]) {
412
+    usart_putstr(COMM_USART, str);
270 413
 }
271 414
 
272
-void handler4(void) {
273
-    val4 += rate4;
274
-    timer_set_compare(timers[t], TIMER_CH4, val4);
275
-    count4++;
415
+static void println(void) {
416
+    putstr("\r\n");
276 417
 }
277 418
 
278
-void handler3b(void) {
419
+static void putstrln(const char str[]) {
420
+    putstr(str);
421
+    println();
422
+}
423
+
424
+static void putudec(uint32 val) {
425
+    usart_putudec(COMM_USART, val);
426
+}
427
+
428
+static void puttimn(timer_dev *dev) {
429
+    putstr("TIM");
430
+    putudec(timerNumber(dev));
431
+}
432
+
433
+static void v_putstr(const char str[]) {
434
+    if (verbose) putstr(str);
435
+}
436
+
437
+static void v_println() {
438
+    if (verbose) println();
439
+}
440
+
441
+__attribute__((unused)) /* (shut up, gcc) */
442
+static void v_putstrln(const char str[]) {
443
+    if (verbose) putstrln(str);
444
+}
445
+
446
+static void v_putudec(uint32 val) {
447
+    if (verbose) putudec(val);
448
+}
449
+
450
+static void v_puttimn(timer_dev *dev) {
451
+    if (verbose) puttimn(dev);
452
+}
453
+
454
+// Used to visually separate output from different tests
455
+static void printBanner(void) {
456
+    putstrln("-----------------------------------------------------");
457
+}
458
+
459
+static void initTimer(timer_dev *dev) {
460
+    v_puttimn(dev);
461
+    timer_init(dev);
462
+    switch (dev->type) {
463
+    case TIMER_ADVANCED:
464
+    case TIMER_GENERAL:
465
+        v_putstr(" channels ");
466
+        for (int c = 1; c <= 4; c++) {
467
+            if (timer_has_cc_ch(dev, c)) {
468
+                v_putudec(c);
469
+                v_putstr(" ");
470
+                timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE);
471
+            }
472
+        }
473
+        break;
474
+    case TIMER_BASIC:
475
+        break;
476
+    }
477
+    v_println();
478
+}
479
+
480
+static int timerNumber(timer_dev *dev) {
481
+    switch (dev->clk_id) {
482
+    case RCC_TIMER1: return 1;
483
+    case RCC_TIMER2: return 2;
484
+    case RCC_TIMER3: return 3;
485
+    case RCC_TIMER4: return 4;
486
+    case RCC_TIMER5: return 5;
487
+    case RCC_TIMER6: return 6;
488
+    case RCC_TIMER7: return 7;
489
+    case RCC_TIMER8: return 8;
490
+    case RCC_TIMER9: return 9;
491
+    case RCC_TIMER10: return 10;
492
+    case RCC_TIMER11: return 11;
493
+    case RCC_TIMER12: return 12;
494
+    case RCC_TIMER13: return 13;
495
+    case RCC_TIMER14: return 14;
496
+    default:
497
+        ASSERT(0);
498
+        return 0;
499
+    }
500
+}
501
+
502
+//
503
+// IRQ Handlers
504
+//
505
+
506
+static void handler1(void) {
507
+    count1++;
508
+}
509
+
510
+static void handler2(void) {
511
+    count2++;
512
+}
513
+
514
+static void handler3(void) {
279 515
     count3++;
280 516
 }
281 517
 
282
-void handler4b(void) {
518
+static void handler4(void) {
283 519
     count4++;
284 520
 }
285 521
 
522
+//
523
+// init() and main()
524
+//
525
+
286 526
 __attribute__((constructor)) void premain() {
287 527
     init();
288 528
 }

+ 154 - 66
examples/test-usart-dma.cpp 파일 보기

@@ -1,5 +1,5 @@
1 1
 /**
2
- * @file test-usart-dma.cpp
2
+ * @file examples/test-usart-dma.cpp
3 3
  * @author Marti Bolivar <mbolivar@leaflabs.com>
4 4
  *
5 5
  * Simple test of DMA used with a USART receiver.
@@ -12,100 +12,188 @@
12 12
  *
13 13
  * This example isn't very robust; don't use it in production.  In
14 14
  * particular, since the buffer keeps filling (DMA_CIRC_MODE is set),
15
- * if you keep typing after filling the buffer, you'll overwrite
16
- * earlier bytes; this may happen before those earlier bytes are done
17
- * printing.
15
+ * if you keep sending characters after filling the buffer, you'll
16
+ * overwrite earlier bytes; this may happen before those earlier bytes
17
+ * are done printing. (Typing quickly and seeing how it affects the
18
+ * output is a fun way to make sense of how the interrupts and the
19
+ * main thread of execution interleave.)
18 20
  *
19 21
  * This code is released into the public domain.
20 22
  */
21 23
 
22
-#include "dma.h"
23
-#include "usart.h"
24
-#include "gpio.h"
24
+#include <libmaple/dma.h>
25
+#include <libmaple/usart.h>
26
+#include <libmaple/gpio.h>
25 27
 
26
-#include "wirish.h"
28
+#include <wirish/wirish.h>
27 29
 
28
-#define BAUD 9600
30
+/*
31
+ * Configuration and state
32
+ */
29 33
 
30
-#define USART USART2
31
-#define USART_HWSER Serial2
34
+// Serial port and DMA configuration. You can change these to suit
35
+// your purposes.
36
+HardwareSerial *serial = &Serial2;
32 37
 #define USART_DMA_DEV DMA1
33
-#define USART_RX_DMA_CHANNEL DMA_CH6
34
-#define USART_TX BOARD_USART2_TX_PIN
35
-#define USART_RX BOARD_USART2_RX_PIN
38
+#if STM32_MCU_SERIES == STM32_SERIES_F1
39
+// On STM32F1 microcontrollers (like what's on Maple and Maple Mini),
40
+// dma tubes are channels.
41
+#define USART_RX_DMA_TUBE DMA_CH6
42
+#elif (STM32_MCU_SERIES == STM32_SERIES_F2 || \
43
+       STM32_MCU_SERIES == STM32_SERIES_F4)
44
+// On STM32F2 and STM32F4 microcontrollers (Maple 2 will have an F4),
45
+// dma tubes are streams.
46
+#define USART_RX_DMA_TUBE DMA_S5
47
+#else
48
+#error "unsupported stm32 series"
49
+#endif
50
+// The serial port will make a DMA request each time it receives data.
51
+// This is the dma_request_src we use to tell the DMA tube to handle
52
+// that DMA request.
53
+#define USART_DMA_REQ_SRC DMA_REQ_SRC_USART2_RX
54
+#define BAUD 9600
36 55
 
37
-#define BUF_SIZE 8
38
-uint8 rx_buf[BUF_SIZE];
56
+// This will store the DMA configuration for USART RX.
57
+dma_tube_config tube_config;
39 58
 
40
-dma_irq_cause irq_cause;
59
+// This will store received USART characters.
60
+#define BUF_SIZE 20
61
+char rx_buf[BUF_SIZE];
41 62
 
63
+// The interrupt handler, rx_dma_irq(), sets this to 1.
42 64
 volatile uint32 irq_fired = 0;
65
+// Used to store DMA interrupt status register (ISR) bits inside
66
+// rx_dma_irq(). This helps explain what's going on inside loop(); see
67
+// comments below.
68
+volatile uint32 isr = 0;
69
+
70
+/*
71
+ * Helper functions
72
+ */
73
+
74
+// This is our DMA interrupt handler.
75
+void rx_dma_irq(void) {
76
+    irq_fired = 1;
77
+    isr = dma_get_isr_bits(USART_DMA_DEV, USART_RX_DMA_TUBE);
78
+}
79
+
80
+// Configure the USART receiver for use with DMA:
81
+// 1. Turn it on.
82
+// 2. Set the "DMA request on RX" bit in USART_CR3 (USART_CR3_DMAR).
83
+void setup_usart(void) {
84
+    serial->begin(BAUD);
85
+    usart_dev *serial_dev = serial->c_dev();
86
+    serial_dev->regs->CR3 = USART_CR3_DMAR;
87
+}
88
+
89
+// Set up our dma_tube_config structure. (We could have done this
90
+// above, when we declared tube_config, but having this function makes
91
+// it easier to explain what's going on).
92
+void setup_tube_config(void) {
93
+    // We're receiving from the USART data register. serial->c_dev()
94
+    // returns a pointer to the libmaple usart_dev for that serial
95
+    // port, so this is a pointer to its data register.
96
+    tube_config.tube_src = &serial->c_dev()->regs->DR;
97
+    // We're only interested in the bottom 8 bits of that data register.
98
+    tube_config.tube_src_size = DMA_SIZE_8BITS;
99
+    // We're storing to rx_buf.
100
+    tube_config.tube_dst = rx_buf;
101
+    // rx_buf is a char array, and a "char" takes up 8 bits on STM32.
102
+    tube_config.tube_dst_size = DMA_SIZE_8BITS;
103
+    // Only fill BUF_SIZE - 1 characters, to leave a null byte at the end.
104
+    tube_config.tube_nr_xfers = BUF_SIZE - 1;
105
+    // Flags:
106
+    // - DMA_CFG_DST_INC so we start at the beginning of rx_buf and
107
+    //   fill towards the end.
108
+    // - DMA_CFG_CIRC so we go back to the beginning and start over when
109
+    //   rx_buf fills up.
110
+    // - DMA_CFG_CMPLT_IE to turn on interrupts on transfer completion.
111
+    tube_config.tube_flags = DMA_CFG_DST_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;
112
+    // Target data: none. It's important to set this to NULL if you
113
+    // don't have any special (microcontroller-specific) configuration
114
+    // in mind, which we don't.
115
+    tube_config.target_data = NULL;
116
+    // DMA request source.
117
+    tube_config.tube_req_src = USART_DMA_REQ_SRC;
118
+}
119
+
120
+// Configure the DMA controller to serve DMA requests from the USART.
121
+void setup_dma_xfer(void) {
122
+    // First, turn it on.
123
+    dma_init(USART_DMA_DEV);
124
+    // Next, configure it by calling dma_tube_cfg(), and check to make
125
+    // sure it succeeded. DMA tubes have many restrictions on their
126
+    // configuration, and there are configurations which work on some
127
+    // types of STM32 but not others. libmaple tries hard to make
128
+    // things just work, but checking the return status is important!
129
+    int status = dma_tube_cfg(USART_DMA_DEV, USART_RX_DMA_TUBE, &tube_config);
130
+    ASSERT(status == DMA_TUBE_CFG_SUCCESS);
131
+    // Now we'll perform any other configuration we want. For this
132
+    // example, we attach an interrupt handler.
133
+    dma_attach_interrupt(USART_DMA_DEV, USART_RX_DMA_TUBE, rx_dma_irq);
134
+    // Turn on the DMA tube. It will now begin serving requests.
135
+    dma_enable(USART_DMA_DEV, USART_RX_DMA_TUBE);
136
+}
43 137
 
44
-void init_usart(void);
45
-void init_dma_xfer(void);
46
-void rx_dma_irq(void);
138
+/*
139
+ * setup() and loop()
140
+ */
47 141
 
48 142
 void setup(void) {
49 143
     pinMode(BOARD_LED_PIN, OUTPUT);
50
-
51
-    init_dma_xfer();
52
-    init_usart();
144
+    setup_tube_config();
145
+    setup_dma_xfer();
146
+    setup_usart();
53 147
 }
54 148
 
55 149
 void loop(void) {
56 150
     toggleLED();
57 151
     delay(100);
58 152
 
59
-    dma_channel_reg_map *ch_regs = dma_channel_regs(USART_DMA_DEV,
60
-                                                    USART_RX_DMA_CHANNEL);
153
+    // See if the interrupt handler got called since the last time we
154
+    // checked.
61 155
     if (irq_fired) {
62
-        USART_HWSER.println("** IRQ **");
156
+        serial->println("** IRQ **");
157
+        // Notice how the interrupt status register (ISR) bits show
158
+        // transfer complete _and_ half-complete here, but the ISR
159
+        // bits we print next will be zero. That's because the
160
+        // variable "isr" gets set _inside_ rx_dma_irq(). After it
161
+        // exits, libmaple cleans up by clearing the tube's ISR
162
+        // bits. (If it didn't, and we forgot to, the interrupt would
163
+        // repeatedly fire forever.)
164
+        serial->print("ISR bits: 0x");
165
+        serial->println(isr, HEX);
63 166
         irq_fired = 0;
64 167
     }
65
-    USART_HWSER.print("[");
66
-    USART_HWSER.print(millis());
67
-    USART_HWSER.print("]\tISR bits: 0x");
68
-    uint8 isr_bits = dma_get_isr_bits(USART_DMA_DEV, USART_RX_DMA_CHANNEL);
69
-    USART_HWSER.print(isr_bits, HEX);
70
-    USART_HWSER.print("\tCCR: 0x");
71
-    USART_HWSER.print(ch_regs->CCR, HEX);
72
-    USART_HWSER.print("\tCNDTR: 0x");
73
-    USART_HWSER.print(ch_regs->CNDTR, HEX);
74
-    USART_HWSER.print("\tBuffer contents: ");
75
-     for (int i = 0; i < BUF_SIZE; i++) {
76
-        USART_HWSER.print('\'');
77
-        USART_HWSER.print(rx_buf[i]);
78
-        USART_HWSER.print('\'');
79
-        if (i < BUF_SIZE - 1) USART_HWSER.print(", ");
80
-    }
81
-    USART_HWSER.println();
168
+
169
+    // Print the ISR bits.
170
+    //
171
+    // Notice that the "transfer half-complete" ISR flag gets set when
172
+    // we reach the rx_buf half-way point. This is true even though we
173
+    // don't tell the DMA controller to interrupt us on a
174
+    // half-complete transfer. That is, the ISR bits get set at the
175
+    // right times no matter what; we just don't get interrupted
176
+    // unless we asked. (If an error or other problem occurs, the
177
+    // relevant ISR bits will get set in the same way).
178
+    serial->print("[");
179
+    serial->print(millis());
180
+    serial->print("]\tISR bits: 0x");
181
+    uint8 isr_bits = dma_get_isr_bits(USART_DMA_DEV, USART_RX_DMA_TUBE);
182
+    serial->print(isr_bits, HEX);
183
+
184
+    // Print the contents of rx_buf. If you keep typing after it fills
185
+    // up, the new characters will overwrite the old ones, thanks to
186
+    // DMA_CIRC_MODE.
187
+    serial->print("\tCharacter buffer contents: '");
188
+    serial->print(rx_buf);
189
+    serial->println("'");
82 190
     if (isr_bits == 0x7) {
83
-        USART_HWSER.println("** Clearing ISR bits.");
84
-        dma_clear_isr_bits(USART_DMA_DEV, USART_RX_DMA_CHANNEL);
191
+        serial->println("** Clearing ISR bits.");
192
+        dma_clear_isr_bits(USART_DMA_DEV, USART_RX_DMA_TUBE);
85 193
     }
86 194
 }
87 195
 
88
-/* Configure USART receiver for use with DMA */
89
-void init_usart(void) {
90
-    USART_HWSER.begin(BAUD);
91
-    USART->regs->CR3 = USART_CR3_DMAR;
92
-}
93
-
94
-/* Configure DMA transmission */
95
-void init_dma_xfer(void) {
96
-    dma_init(USART_DMA_DEV);
97
-    dma_setup_transfer(USART_DMA_DEV, USART_RX_DMA_CHANNEL,
98
-                       &USART->regs->DR, DMA_SIZE_8BITS,
99
-                       rx_buf,           DMA_SIZE_8BITS,
100
-                       (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_TRNS_CMPLT));
101
-    dma_set_num_transfers(USART_DMA_DEV, USART_RX_DMA_CHANNEL, BUF_SIZE);
102
-    dma_attach_interrupt(USART_DMA_DEV, USART_RX_DMA_CHANNEL, rx_dma_irq);
103
-    dma_enable(USART_DMA_DEV, USART_RX_DMA_CHANNEL);
104
-}
105
-
106
-void rx_dma_irq(void) {
107
-    irq_fired = true;
108
-}
196
+// ------- init() and main() --------------------------------------------------
109 197
 
110 198
 // Force init to be called *first*, i.e. before static object allocation.
111 199
 // Otherwise, statically allocated objects that need libmaple may fail.

+ 1 - 1
examples/vga-leaf.cpp 파일 보기

@@ -32,7 +32,7 @@
32 32
 
33 33
 // FIXME: generalize for Native and Mini
34 34
 
35
-#include "wirish.h"
35
+#include <wirish/wirish.h>
36 36
 
37 37
 // Pinouts -- you also must change the GPIO macros below if you change
38 38
 // these

+ 2 - 2
examples/vga-scope.cpp 파일 보기

@@ -35,8 +35,8 @@
35 35
   Marti Bolivar <mbolivar@leaflabs.com>
36 36
  */
37 37
 
38
-#include "wirish.h"
39
-#include "systick.h"
38
+#include <wirish/wirish.h>
39
+#include <libmaple/systick.h>
40 40
 
41 41
 // FIXME: generalize for Native and Mini
42 42
 

+ 11 - 67
libmaple/adc.c 파일 보기

@@ -25,44 +25,15 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file adc.c
29
- *
28
+ * @file libmaple/adc.c
29
+ * @author Marti Bolivar <mbolivar@leaflabs.com>,
30
+ *         Perry Hung <perry@leaflabs.com>
30 31
  * @brief Analog to digital converter routines
31
- *
32
- * IMPORTANT: maximum external impedance must be below 0.4kOhms for 1.5
33
- * sample conversion time.
34
- *
35
- * At 55.5 cycles/sample, the external input impedance < 50kOhms.
36
- *
37
- * See STM32 manual RM0008 for how to calculate this.
38 32
  */
39 33
 
40
-#include "libmaple.h"
41
-#include "rcc.h"
42
-#include "adc.h"
43
-
44
-static adc_dev adc1 = {
45
-    .regs   = ADC1_BASE,
46
-    .clk_id = RCC_ADC1
47
-};
48
-/** ADC1 device. */
49
-const adc_dev *ADC1 = &adc1;
50
-
51
-static adc_dev adc2 = {
52
-    .regs   = ADC2_BASE,
53
-    .clk_id = RCC_ADC2
54
-};
55
-/** ADC2 device. */
56
-const adc_dev *ADC2 = &adc2;
57
-
58
-#ifdef STM32_HIGH_DENSITY
59
-adc_dev adc3 = {
60
-    .regs   = ADC3_BASE,
61
-    .clk_id = RCC_ADC3
62
-};
63
-/** ADC3 device. */
64
-const adc_dev *ADC3 = &adc3;
65
-#endif
34
+#include <libmaple/adc.h>
35
+#include <libmaple/libmaple.h>
36
+#include <libmaple/rcc.h>
66 37
 
67 38
 /**
68 39
  * @brief Initialize an ADC peripheral.
@@ -91,20 +62,10 @@ void adc_set_extsel(const adc_dev *dev, adc_extsel_event event) {
91 62
 }
92 63
 
93 64
 /**
94
- * @brief Call a function on all ADC devices.
95
- * @param fn Function to call on each ADC device.
96
- */
97
-void adc_foreach(void (*fn)(const adc_dev*)) {
98
-    fn(ADC1);
99
-    fn(ADC2);
100
-#ifdef STM32_HIGH_DENSITY
101
-    fn(ADC3);
102
-#endif
103
-}
104
-
105
-/**
106
- * @brief Turn the given sample rate into values for ADC_SMPRx. Don't
107
- * call this during conversion.
65
+ * @brief Set the sample rate for all channels on an ADC device.
66
+ *
67
+ * Don't call this during conversion.
68
+ *
108 69
  * @param dev adc device
109 70
  * @param smp_rate sample rate to set
110 71
  * @see adc_smp_rate
@@ -127,25 +88,8 @@ void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate) {
127 88
 }
128 89
 
129 90
 /**
130
- * @brief Calibrate an ADC peripheral
131
- * @param dev adc device
132
- */
133
-void adc_calibrate(const adc_dev *dev) {
134
-    __io uint32 *rstcal_bit = bb_perip(&(dev->regs->CR2), 3);
135
-    __io uint32 *cal_bit = bb_perip(&(dev->regs->CR2), 2);
136
-
137
-    *rstcal_bit = 1;
138
-    while (*rstcal_bit)
139
-        ;
140
-
141
-    *cal_bit = 1;
142
-    while (*cal_bit)
143
-        ;
144
-}
145
-
146
-/**
147 91
  * @brief Perform a single synchronous software triggered conversion on a
148
- * channel.
92
+ *        channel.
149 93
  * @param dev ADC device to use for reading.
150 94
  * @param channel channel to convert
151 95
  * @return conversion result

+ 11 - 17
libmaple/dac.c 파일 보기

@@ -2,6 +2,7 @@
2 2
  * The MIT License
3 3
  *
4 4
  * Copyright (c) 2010 Bryan Newbold.
5
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
7 8
  * obtaining a copy of this software and associated documentation
@@ -25,25 +26,20 @@
25 26
  *****************************************************************************/
26 27
 
27 28
 /**
28
- * @file dac.c
29
+ * @file libmaple/dac.c
29 30
  * @brief Digital to analog converter support.
30 31
  */
31 32
 
32
-#include "libmaple.h"
33
-#include "gpio.h"
34
-#include "dac.h"
35
-
36
-#ifdef STM32_HIGH_DENSITY
37
-
38
-/**
39
- * @brief DAC peripheral routines.
40
- */
33
+#include <libmaple/dac.h>
34
+#include <libmaple/libmaple.h>
35
+#include <libmaple/gpio.h>
41 36
 
37
+#if STM32_HAVE_DAC
42 38
 dac_dev dac = {
43 39
     .regs = DAC_BASE,
44 40
 };
45
-/** DAC device. */
46 41
 const dac_dev *DAC = &dac;
42
+#endif
47 43
 
48 44
 /**
49 45
  * @brief Initialize the digital to analog converter
@@ -92,16 +88,16 @@ void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val) {
92 88
  */
93 89
 void dac_enable_channel(const dac_dev *dev, uint8 channel) {
94 90
     /*
95
-     * Setup ANALOG mode on PA4 and PA5. This mapping is consistent across
96
-     * all STM32 chips with a DAC. See RM0008 12.2.
91
+     * Setup ANALOG mode on PA4 and PA5. This mapping is consistent
92
+     * across all supported STM32s with a DAC.
97 93
      */
98 94
     switch (channel) {
99 95
     case 1:
100
-        gpio_set_mode(GPIOA, 4, GPIO_INPUT_ANALOG);
96
+        gpio_set_mode(GPIOA, 4, GPIO_MODE_ANALOG);
101 97
         dev->regs->CR |= DAC_CR_EN1;
102 98
         break;
103 99
     case 2:
104
-        gpio_set_mode(GPIOA, 5, GPIO_INPUT_ANALOG);
100
+        gpio_set_mode(GPIOA, 5, GPIO_MODE_ANALOG);
105 101
         dev->regs->CR |= DAC_CR_EN2;
106 102
         break;
107 103
     }
@@ -122,5 +118,3 @@ void dac_disable_channel(const dac_dev *dev, uint8 channel) {
122 118
         break;
123 119
     }
124 120
 }
125
-
126
-#endif  /* STM32_HIGH_DENSITY */

+ 0 - 168
libmaple/dac.h 파일 보기

@@ -1,168 +0,0 @@
1
-/******************************************************************************
2
- * The MIT License
3
- *
4
- * Copyright (c) 2010 Bryan Newbold.
5
- *
6
- * Permission is hereby granted, free of charge, to any person
7
- * obtaining a copy of this software and associated documentation
8
- * files (the "Software"), to deal in the Software without
9
- * restriction, including without limitation the rights to use, copy,
10
- * modify, merge, publish, distribute, sublicense, and/or sell copies
11
- * of the Software, and to permit persons to whom the Software is
12
- * furnished to do so, subject to the following conditions:
13
- *
14
- * The above copyright notice and this permission notice shall be
15
- * included in all copies or substantial portions of the Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- * SOFTWARE.
25
- *****************************************************************************/
26
-
27
-/**
28
- * @file dac.h
29
- * @brief Digital to analog converter support.
30
- */
31
-
32
-/* See notes/dac.txt for more info */
33
-
34
-#ifndef _DAC_H_
35
-#define _DAC_H_
36
-
37
-#include "rcc.h"
38
-
39
-#ifdef __cplusplus
40
-extern "C"{
41
-#endif
42
-
43
-/*
44
- * Register maps
45
- */
46
-
47
-/** DAC register map. */
48
-typedef struct dac_reg_map {
49
-    __io uint32 CR;      /**< Control register */
50
-    __io uint32 SWTRIGR; /**< Software trigger register */
51
-    __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data
52
-                              holding register */
53
-    __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data
54
-                              holding register */
55
-    __io uint32 DHR8R1;  /**< Channel 1 8-bit left-aligned data
56
-                              holding register */
57
-    __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data
58
-                              holding register */
59
-    __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data
60
-                              holding register */
61
-    __io uint32 DHR8R2;  /**< Channel 2 8-bit left-aligned data
62
-                              holding register */
63
-    __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data
64
-                              holding register */
65
-    __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data
66
-                              holding register */
67
-    __io uint32 DHR8RD;  /**< Dual DAC 8-bit right-aligned data holding
68
-                              register */
69
-    __io uint32 DOR1;    /**< Channel 1 data output register */
70
-    __io uint32 DOR2;    /**< Channel 2 data output register */
71
-} dac_reg_map;
72
-
73
-/** DAC register map base address */
74
-#define DAC_BASE                ((struct dac_reg_map*)0x40007400)
75
-
76
-/*
77
- * Devices
78
- */
79
-
80
-/** DAC device type. */
81
-typedef struct dac_dev {
82
-    dac_reg_map *regs; /**< Register map */
83
-} dac_dev;
84
-
85
-extern const dac_dev *DAC;
86
-
87
-/*
88
- * Register bit definitions
89
- */
90
-
91
-/* Control register */
92
-/* Channel 1 control */
93
-#define DAC_CR_EN1                   BIT(0) /* Enable */
94
-#define DAC_CR_BOFF1                 BIT(1) /* Output buffer disable */
95
-#define DAC_CR_TEN1                  BIT(2) /* Trigger enable */
96
-#define DAC_CR_TSEL1             (0x7 << 3) /* Trigger selection */
97
-#define DAC_CR_WAVE1             (0x3 << 6) /* Noise/triangle wave enable */
98
-#define DAC_CR_MAMP1             (0xF << 8) /* Mask/amplitude selector */
99
-#define DAC_CR_DMAEN1               BIT(12) /* DMA enable */
100
-/* Channel 2 control */
101
-#define DAC_CR_EN2                  BIT(16) /* Enable */
102
-#define DAC_CR_BOFF2                BIT(17) /* Output buffer disable */
103
-#define DAC_CR_TEN2                 BIT(18) /* Trigger enable */
104
-#define DAC_CR_TSEL2            (0x7 << 19) /* Trigger selection */
105
-#define DAC_CR_WAVE2            (0x3 << 22) /* Noise/triangle wave generation*/
106
-#define DAC_CR_MAMP2            (0xF << 24) /* Mask/amplitude selector */
107
-#define DAC_CR_DMAEN2               BIT(28) /* DMA enable */
108
-
109
-/* Software trigger register */
110
-#define DAC_SWTRIGR_SWTRIG1          BIT(0) /* Channel 1 software trigger */
111
-#define DAC_SWTRIGR_SWTRIG2          BIT(1) /* Channel 2 software trigger */
112
-
113
-/* Channel 1 12-bit right-aligned data holding register */
114
-#define DAC_DHR12R1_DACC1DHR     0x00000FFF
115
-
116
-/* Channel 1 12-bit left-aligned data holding register */
117
-#define DAC_DHR12L1_DACC1DHR     0x0000FFF0
118
-
119
-/* Channel 1 8-bit left-aligned data holding register */
120
-#define DAC_DHR8R1_DACC1DHR      0x000000FF
121
-
122
-/* Channel 2 12-bit right-aligned data holding register */
123
-#define DAC_DHR12R2_DACC2DHR     0x00000FFF
124
-
125
-/* Channel 2 12-bit left-aligned data holding register */
126
-#define DAC_DHR12L2_DACC2DHR     0x0000FFF0
127
-
128
-/* Channel 2 8-bit left-aligned data holding register */
129
-#define DAC_DHR8R2_DACC2DHR      0x000000FF
130
-
131
-/* Dual DAC 12-bit right-aligned data holding register */
132
-#define DAC_DHR12RD_DACC1DHR     0x00000FFF
133
-#define DAC_DHR12RD_DACC2DHR     0x0FFF0000
134
-
135
-/* Dual DAC 12-bit left-aligned data holding register */
136
-#define DAC_DHR12LD_DACC1DHR     0x0000FFF0
137
-#define DAC_DHR12LD_DACC2DHR     0xFFF00000
138
-
139
-/* Dual DAC 8-bit left-aligned data holding register */
140
-#define DAC_DHR8RD_DACC1DHR      0x000000FF
141
-#define DAC_DHR8RD_DACC2DHR      0x0000FF00
142
-
143
-/* Channel 1 data output register */
144
-#define DAC_DOR1_DACC1DOR        0x00000FFF
145
-
146
-/* Channel 1 data output register */
147
-#define DAC_DOR2_DACC2DOR        0x00000FFF
148
-
149
-/*
150
- * Convenience functions
151
- */
152
-
153
-/* We take the dev argument in these convenience functions for
154
- * future-proofing */
155
-
156
-#define DAC_CH1                         0x1
157
-#define DAC_CH2                         0x2
158
-void dac_init(const dac_dev *dev, uint32 flags);
159
-
160
-void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val);
161
-void dac_enable_channel(const dac_dev *dev, uint8 channel);
162
-void dac_disable_channel(const dac_dev *dev, uint8 channel);
163
-
164
-#ifdef __cplusplus
165
-} // extern "C"
166
-#endif
167
-
168
-#endif

+ 0 - 30
libmaple/delay.h 파일 보기

@@ -1,30 +0,0 @@
1
-/**
2
- * @file delay.h
3
- * @brief Delay implementation
4
- */
5
-
6
-#include "libmaple_types.h"
7
-#include "stm32.h"
8
-
9
-#ifndef _DELAY_H_
10
-#define _DELAY_H_
11
-
12
-/**
13
- * @brief Delay the given number of microseconds.
14
- *
15
- * @param us Number of microseconds to delay.
16
- */
17
-static inline void delay_us(uint32 us) {
18
-    us *= STM32_DELAY_US_MULT;
19
-
20
-    /* fudge for function call overhead  */
21
-    us--;
22
-    asm volatile("   mov r0, %[us]          \n\t"
23
-                 "1: subs r0, #1            \n\t"
24
-                 "   bhi 1b                 \n\t"
25
-                 :
26
-                 : [us] "r" (us)
27
-                 : "r0");
28
-}
29
-#endif
30
-

+ 33 - 330
libmaple/dma.c 파일 보기

@@ -2,6 +2,7 @@
2 2
  * The MIT License
3 3
  *
4 4
  * Copyright (c) 2010 Michael Hope.
5
+ * Copyright (c) 2012 LeafLabs, LLC.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
7 8
  * obtaining a copy of this software and associated documentation
@@ -25,47 +26,15 @@
25 26
  *****************************************************************************/
26 27
 
27 28
 /**
28
- * @file dma.c
29
+ * @file libmaple/dma.c
29 30
  * @author Marti Bolivar <mbolivar@leaflabs.com>;
30 31
  *         Original implementation by Michael Hope
31
- * @brief Direct Memory Access peripheral support
32
+ * @brief Portable DMA routines.
32 33
  */
33 34
 
34
-#include "dma.h"
35
-#include "bitband.h"
36
-#include "util.h"
37
-
38
-/*
39
- * Devices
40
- */
41
-
42
-static dma_dev dma1 = {
43
-    .regs     = DMA1_BASE,
44
-    .clk_id   = RCC_DMA1,
45
-    .handlers = {{ .handler = NULL, .irq_line = NVIC_DMA_CH1 },
46
-                 { .handler = NULL, .irq_line = NVIC_DMA_CH2 },
47
-                 { .handler = NULL, .irq_line = NVIC_DMA_CH3 },
48
-                 { .handler = NULL, .irq_line = NVIC_DMA_CH4 },
49
-                 { .handler = NULL, .irq_line = NVIC_DMA_CH5 },
50
-                 { .handler = NULL, .irq_line = NVIC_DMA_CH6 },
51
-                 { .handler = NULL, .irq_line = NVIC_DMA_CH7 }}
52
-};
53
-/** DMA1 device */
54
-dma_dev *DMA1 = &dma1;
55
-
56
-#ifdef STM32_HIGH_DENSITY
57
-static dma_dev dma2 = {
58
-    .regs     = DMA2_BASE,
59
-    .clk_id   = RCC_DMA2,
60
-    .handlers = {{ .handler = NULL, .irq_line = NVIC_DMA2_CH1   },
61
-                 { .handler = NULL, .irq_line = NVIC_DMA2_CH2   },
62
-                 { .handler = NULL, .irq_line = NVIC_DMA2_CH3   },
63
-                 { .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 },
64
-                 { .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 }} /* !@#$ */
65
-};
66
-/** DMA2 device */
67
-dma_dev *DMA2 = &dma2;
68
-#endif
35
+#include <libmaple/dma.h>
36
+#include "dma_private.h"
37
+#include "stm32_private.h"
69 38
 
70 39
 /*
71 40
  * Convenience routines
@@ -79,301 +48,35 @@ void dma_init(dma_dev *dev) {
79 48
     rcc_clk_enable(dev->clk_id);
80 49
 }
81 50
 
82
-/**
83
- * @brief Set up a DMA transfer.
84
- *
85
- * The channel will be disabled before being reconfigured.  The
86
- * transfer will have low priority by default.  You may choose another
87
- * priority before the transfer begins using dma_set_priority(), as
88
- * well as performing any other configuration you desire.  When the
89
- * channel is configured to your liking, enable it using dma_enable().
90
- *
91
- * @param dev DMA device.
92
- * @param channel DMA channel.
93
- * @param peripheral_address Base address of peripheral data register
94
- *                           involved in the transfer.
95
- * @param peripheral_size Peripheral data transfer size.
96
- * @param memory_address Base memory address involved in the transfer.
97
- * @param memory_size Memory data transfer size.
98
- * @param mode Logical OR of dma_mode_flags
99
- * @sideeffect Disables the given DMA channel.
100
- * @see dma_xfer_size
101
- * @see dma_mode_flags
102
- * @see dma_set_num_transfers()
103
- * @see dma_set_priority()
104
- * @see dma_attach_interrupt()
105
- * @see dma_enable()
106
- */
107
-void dma_setup_transfer(dma_dev       *dev,
108
-                        dma_channel    channel,
109
-                        __io void     *peripheral_address,
110
-                        dma_xfer_size  peripheral_size,
111
-                        __io void     *memory_address,
112
-                        dma_xfer_size  memory_size,
113
-                        uint32         mode) {
114
-    dma_channel_reg_map *channel_regs = dma_channel_regs(dev, channel);
115
-
116
-    dma_disable(dev, channel);  /* can't write to CMAR/CPAR otherwise */
117
-    channel_regs->CCR = (memory_size << 10) | (peripheral_size << 8) | mode;
118
-    channel_regs->CMAR = (uint32)memory_address;
119
-    channel_regs->CPAR = (uint32)peripheral_address;
120
-}
121
-
122
-/**
123
- * @brief Set the number of data to be transferred on a DMA channel.
124
- *
125
- * You may not call this function while the channel is enabled.
126
- *
127
- * @param dev DMA device
128
- * @param channel Channel through which the transfer occurs.
129
- * @param num_transfers
130
- */
131
-void dma_set_num_transfers(dma_dev *dev,
132
-                           dma_channel channel,
133
-                           uint16 num_transfers) {
134
-    dma_channel_reg_map *channel_regs;
135
-
136
-    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
137
-
138
-    channel_regs = dma_channel_regs(dev, channel);
139
-    channel_regs->CNDTR = num_transfers;
140
-}
141
-
142
-/**
143
- * @brief Set the priority of a DMA transfer.
144
- *
145
- * You may not call this function while the channel is enabled.
146
- *
147
- * @param dev DMA device
148
- * @param channel DMA channel
149
- * @param priority priority to set.
150
- */
151
-void dma_set_priority(dma_dev *dev,
152
-                      dma_channel channel,
153
-                      dma_priority priority) {
154
-    dma_channel_reg_map *channel_regs;
155
-    uint32 ccr;
156
-
157
-    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
158
-
159
-    channel_regs = dma_channel_regs(dev, channel);
160
-    ccr = channel_regs->CCR;
161
-    ccr &= ~DMA_CCR_PL;
162
-    ccr |= priority;
163
-    channel_regs->CCR = ccr;
164
-}
165
-
166
-/**
167
- * @brief Attach an interrupt to a DMA transfer.
168
- *
169
- * Interrupts are enabled using appropriate mode flags in
170
- * dma_setup_transfer().
171
- *
172
- * @param dev DMA device
173
- * @param channel Channel to attach handler to
174
- * @param handler Interrupt handler to call when channel interrupt fires.
175
- * @see dma_setup_transfer()
176
- * @see dma_get_irq_cause()
177
- * @see dma_detach_interrupt()
178
- */
179
-void dma_attach_interrupt(dma_dev *dev,
180
-                          dma_channel channel,
181
-                          void (*handler)(void)) {
182
-    dev->handlers[channel - 1].handler = handler;
183
-    nvic_irq_enable(dev->handlers[channel - 1].irq_line);
184
-}
185
-
186
-/**
187
- * @brief Detach a DMA transfer interrupt handler.
188
- *
189
- * After calling this function, the given channel's interrupts will be
190
- * disabled.
191
- *
192
- * @param dev DMA device
193
- * @param channel Channel whose handler to detach
194
- * @sideeffect Clears interrupt enable bits in the channel's CCR register.
195
- * @see dma_attach_interrupt()
196
- */
197
-void dma_detach_interrupt(dma_dev *dev, dma_channel channel) {
198
-    /* Don't use nvic_irq_disable()! Think about DMA2 channels 4 and 5. */
199
-    dma_channel_regs(dev, channel)->CCR &= ~0xF;
200
-    dev->handlers[channel - 1].handler = NULL;
201
-}
202
-
203
-/**
204
- * @brief Discover the reason why a DMA interrupt was called.
205
- *
206
- * You may only call this function within an attached interrupt
207
- * handler for the given channel.
208
- *
209
- * This function resets the internal DMA register state which encodes
210
- * the cause of the interrupt; consequently, it can only be called
211
- * once per interrupt handler invocation.
212
- *
213
- * @param dev DMA device
214
- * @param channel Channel whose interrupt is being handled.
215
- * @return Reason why the interrupt fired.
216
- * @sideeffect Clears channel status flags in dev->regs->ISR.
217
- * @see dma_attach_interrupt()
218
- * @see dma_irq_cause
219
- */
220
-dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) {
221
-    uint8 status_bits = dma_get_isr_bits(dev, channel);
222
-
223
-    /* If the channel global interrupt flag is cleared, then
224
-     * something's very wrong. */
225
-    ASSERT(status_bits & BIT(0));
226
-
227
-    dma_clear_isr_bits(dev, channel);
228
-
229
-    /* ISR flags get set even if the corresponding interrupt enable
230
-     * bits in the channel's configuration register are cleared, so we
231
-     * can't use a switch here.
232
-     *
233
-     * Don't change the order of these if statements. */
234
-    if (status_bits & BIT(3)) {
235
-        return DMA_TRANSFER_ERROR;
236
-    } else if (status_bits & BIT(1)) {
237
-        return DMA_TRANSFER_COMPLETE;
238
-    } else if (status_bits & BIT(2)) {
239
-        return DMA_TRANSFER_HALF_COMPLETE;
240
-    } else if (status_bits & BIT(0)) {
241
-        /* Shouldn't happen (unless someone messed up an IFCR write). */
242
-        throb();
243
-    }
244
-#if DEBUG_LEVEL < DEBUG_ALL
245
-    else {
246
-        /* We shouldn't have been called, but the debug level is too
247
-         * low for the above ASSERT() to have had any effect.  In
248
-         * order to fail fast, mimic the DMA controller's behavior
249
-         * when an error occurs. */
250
-        dma_disable(dev, channel);
251
-    }
252
-#endif
253
-    return DMA_TRANSFER_ERROR;
254
-}
255
-
256
-/**
257
- * @brief Enable a DMA channel.
258
- * @param dev DMA device
259
- * @param channel Channel to enable
260
- */
261
-void dma_enable(dma_dev *dev, dma_channel channel) {
262
-    dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel);
263
-    bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 1);
264
-}
265
-
266
-/**
267
- * @brief Disable a DMA channel.
268
- * @param dev DMA device
269
- * @param channel Channel to disable
270
- */
271
-void dma_disable(dma_dev *dev, dma_channel channel) {
272
-    dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel);
273
-    bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 0);
274
-}
275
-
276
-/**
277
- * @brief Set the base memory address where data will be read from or
278
- *        written to.
279
- *
280
- * You must not call this function while the channel is enabled.
281
- *
282
- * If the DMA memory size is 16 bits, the address is automatically
283
- * aligned to a half-word.  If the DMA memory size is 32 bits, the
284
- * address is aligned to a word.
285
- *
286
- * @param dev DMA Device
287
- * @param channel Channel whose base memory address to set.
288
- * @param addr Memory base address to use.
289
- */
290
-void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *addr) {
291
-    dma_channel_reg_map *chan_regs;
292
-
293
-    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
294
-
295
-    chan_regs = dma_channel_regs(dev, channel);
296
-    chan_regs->CMAR = (uint32)addr;
297
-}
298
-
299
-/**
300
- * @brief Set the base peripheral address where data will be read from
301
- *        or written to.
302
- *
303
- * You must not call this function while the channel is enabled.
304
- *
305
- * If the DMA peripheral size is 16 bits, the address is automatically
306
- * aligned to a half-word.  If the DMA peripheral size is 32 bits, the
307
- * address is aligned to a word.
308
- *
309
- * @param dev DMA Device
310
- * @param channel Channel whose peripheral data register base address to set.
311
- * @param addr Peripheral memory base address to use.
312
- */
313
-void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *addr) {
314
-    dma_channel_reg_map *chan_regs;
315
-
316
-    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
317
-
318
-    chan_regs = dma_channel_regs(dev, channel);
319
-    chan_regs->CPAR = (uint32)addr;
320
-}
321
-
322 51
 /*
323
- * IRQ handlers
52
+ * Private API
324 53
  */
325 54
 
326
-static inline void dispatch_handler(dma_dev *dev, dma_channel channel) {
327
-    void (*handler)(void) = dev->handlers[channel - 1].handler;
328
-    if (handler) {
329
-        handler();
330
-        dma_clear_isr_bits(dev, channel); /* in case handler doesn't */
55
+enum dma_atype _dma_addr_type(__io void *addr) {
56
+    switch (stm32_block_purpose((void*)addr)) {
57
+    /* Notice we're treating the code block as memory here.  That's
58
+     * correct for addresses in Flash and in [0x0, 0x7FFFFFF]
59
+     * (provided that those addresses are aliased to Flash, SRAM, or
60
+     * FSMC, depending on BOOT[01] and possibly SYSCFG_MEMRMP). It's
61
+     * not correct for other addresses in the code block, but those
62
+     * will (hopefully) just fail-fast with transfer or bus errors. If
63
+     * lots of people get confused, it might be worth being more
64
+     * careful here. */
65
+    case STM32_BLOCK_CODE:      /* Fall through */
66
+    case STM32_BLOCK_SRAM:      /* ... */
67
+    case STM32_BLOCK_FSMC_1_2:  /* ... */
68
+    case STM32_BLOCK_FSMC_3_4:
69
+        return DMA_ATYPE_MEM;
70
+    case STM32_BLOCK_PERIPH:
71
+        return DMA_ATYPE_PER;
72
+    case STM32_BLOCK_FSMC_REG:        /* Fall through */
73
+        /* Is this right? I can't think of a reason to DMA into or out
74
+         * of the FSMC registers. [mbolivar]  */
75
+    case STM32_BLOCK_UNUSED:          /* ... */
76
+    case STM32_BLOCK_CORTEX_INTERNAL: /* ... */
77
+        return DMA_ATYPE_OTHER;
78
+    default:
79
+        ASSERT(0);              /* Can't happen */
80
+        return DMA_ATYPE_OTHER;
331 81
     }
332 82
 }
333
-
334
-void __irq_dma1_channel1(void) {
335
-    dispatch_handler(DMA1, DMA_CH1);
336
-}
337
-
338
-void __irq_dma1_channel2(void) {
339
-    dispatch_handler(DMA1, DMA_CH2);
340
-}
341
-
342
-void __irq_dma1_channel3(void) {
343
-    dispatch_handler(DMA1, DMA_CH3);
344
-}
345
-
346
-void __irq_dma1_channel4(void) {
347
-    dispatch_handler(DMA1, DMA_CH4);
348
-}
349
-
350
-void __irq_dma1_channel5(void) {
351
-    dispatch_handler(DMA1, DMA_CH5);
352
-}
353
-
354
-void __irq_dma1_channel6(void) {
355
-    dispatch_handler(DMA1, DMA_CH6);
356
-}
357
-
358
-void __irq_dma1_channel7(void) {
359
-    dispatch_handler(DMA1, DMA_CH7);
360
-}
361
-
362
-#ifdef STM32_HIGH_DENSITY
363
-void __irq_dma2_channel1(void) {
364
-    dispatch_handler(DMA2, DMA_CH1);
365
-}
366
-
367
-void __irq_dma2_channel2(void) {
368
-    dispatch_handler(DMA2, DMA_CH2);
369
-}
370
-
371
-void __irq_dma2_channel3(void) {
372
-    dispatch_handler(DMA2, DMA_CH3);
373
-}
374
-
375
-void __irq_dma2_channel4_5(void) {
376
-    dispatch_handler(DMA2, DMA_CH4);
377
-    dispatch_handler(DMA2, DMA_CH5);
378
-}
379
-#endif

+ 0 - 453
libmaple/dma.h 파일 보기

@@ -1,453 +0,0 @@
1
-/******************************************************************************
2
- * The MIT License
3
- *
4
- * Copyright (c) 2010 Michael Hope.
5
- *
6
- * Permission is hereby granted, free of charge, to any person
7
- * obtaining a copy of this software and associated documentation
8
- * files (the "Software"), to deal in the Software without
9
- * restriction, including without limitation the rights to use, copy,
10
- * modify, merge, publish, distribute, sublicense, and/or sell copies
11
- * of the Software, and to permit persons to whom the Software is
12
- * furnished to do so, subject to the following conditions:
13
- *
14
- * The above copyright notice and this permission notice shall be
15
- * included in all copies or substantial portions of the Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- * SOFTWARE.
25
- *****************************************************************************/
26
-
27
-/**
28
- * @file dma.h
29
- *
30
- * @author Marti Bolivar <mbolivar@leaflabs.com>;
31
- *         Original implementation by Michael Hope
32
- *
33
- * @brief Direct Memory Access peripheral support
34
- */
35
-
36
-/*
37
- * See /notes/dma.txt for more information.
38
- */
39
-
40
-#ifndef _DMA_H_
41
-#define _DMA_H_
42
-
43
-#include "libmaple_types.h"
44
-#include "rcc.h"
45
-#include "nvic.h"
46
-
47
-#ifdef __cplusplus
48
-extern "C"{
49
-#endif
50
-
51
-/*
52
- * Register maps
53
- */
54
-
55
-/**
56
- * @brief DMA register map type.
57
- *
58
- * Note that DMA controller 2 (register map base pointer DMA2_BASE)
59
- * only supports channels 1--5.
60
- */
61
-typedef struct dma_reg_map {
62
-    __io uint32 ISR;            /**< Interrupt status register */
63
-    __io uint32 IFCR;           /**< Interrupt flag clear register */
64
-    __io uint32 CCR1;           /**< Channel 1 configuration register */
65
-    __io uint32 CNDTR1;         /**< Channel 1 number of data register */
66
-    __io uint32 CPAR1;          /**< Channel 1 peripheral address register */
67
-    __io uint32 CMAR1;          /**< Channel 1 memory address register */
68
-    const uint32 RESERVED1;     /**< Reserved. */
69
-    __io uint32 CCR2;           /**< Channel 2 configuration register */
70
-    __io uint32 CNDTR2;         /**< Channel 2 number of data register */
71
-    __io uint32 CPAR2;          /**< Channel 2 peripheral address register */
72
-    __io uint32 CMAR2;          /**< Channel 2 memory address register */
73
-    const uint32 RESERVED2;     /**< Reserved. */
74
-    __io uint32 CCR3;           /**< Channel 3 configuration register */
75
-    __io uint32 CNDTR3;         /**< Channel 3 number of data register */
76
-    __io uint32 CPAR3;          /**< Channel 3 peripheral address register */
77
-    __io uint32 CMAR3;          /**< Channel 3 memory address register */
78
-    const uint32 RESERVED3;     /**< Reserved. */
79
-    __io uint32 CCR4;           /**< Channel 4 configuration register */
80
-    __io uint32 CNDTR4;         /**< Channel 4 number of data register */
81
-    __io uint32 CPAR4;          /**< Channel 4 peripheral address register */
82
-    __io uint32 CMAR4;          /**< Channel 4 memory address register */
83
-    const uint32 RESERVED4;     /**< Reserved. */
84
-    __io uint32 CCR5;           /**< Channel 5 configuration register */
85
-    __io uint32 CNDTR5;         /**< Channel 5 number of data register */
86
-    __io uint32 CPAR5;          /**< Channel 5 peripheral address register */
87
-    __io uint32 CMAR5;          /**< Channel 5 memory address register */
88
-    const uint32 RESERVED5;     /**< Reserved. */
89
-    __io uint32 CCR6;           /**< Channel 6 configuration register */
90
-    __io uint32 CNDTR6;         /**< Channel 6 number of data register */
91
-    __io uint32 CPAR6;          /**< Channel 6 peripheral address register */
92
-    __io uint32 CMAR6;          /**< Channel 6 memory address register */
93
-    const uint32 RESERVED6;     /**< Reserved. */
94
-    __io uint32 CCR7;           /**< Channel 7 configuration register */
95
-    __io uint32 CNDTR7;         /**< Channel 7 number of data register */
96
-    __io uint32 CPAR7;          /**< Channel 7 peripheral address register */
97
-    __io uint32 CMAR7;          /**< Channel 7 memory address register */
98
-    const uint32 RESERVED7;     /**< Reserved. */
99
-} dma_reg_map;
100
-
101
-/** DMA controller 1 register map base pointer */
102
-#define DMA1_BASE                       ((struct dma_reg_map*)0x40020000)
103
-
104
-#ifdef STM32_HIGH_DENSITY
105
-/** DMA controller 2 register map base pointer */
106
-#define DMA2_BASE                       ((struct dma_reg_map*)0x40020400)
107
-#endif
108
-
109
-/*
110
- * Register bit definitions
111
- */
112
-
113
-/* Interrupt status register */
114
-
115
-#define DMA_ISR_TEIF7_BIT               27
116
-#define DMA_ISR_HTIF7_BIT               26
117
-#define DMA_ISR_TCIF7_BIT               25
118
-#define DMA_ISR_GIF7_BIT                24
119
-#define DMA_ISR_TEIF6_BIT               23
120
-#define DMA_ISR_HTIF6_BIT               22
121
-#define DMA_ISR_TCIF6_BIT               21
122
-#define DMA_ISR_GIF6_BIT                20
123
-#define DMA_ISR_TEIF5_BIT               19
124
-#define DMA_ISR_HTIF5_BIT               18
125
-#define DMA_ISR_TCIF5_BIT               17
126
-#define DMA_ISR_GIF5_BIT                16
127
-#define DMA_ISR_TEIF4_BIT               15
128
-#define DMA_ISR_HTIF4_BIT               14
129
-#define DMA_ISR_TCIF4_BIT               13
130
-#define DMA_ISR_GIF4_BIT                12
131
-#define DMA_ISR_TEIF3_BIT               11
132
-#define DMA_ISR_HTIF3_BIT               10
133
-#define DMA_ISR_TCIF3_BIT               9
134
-#define DMA_ISR_GIF3_BIT                8
135
-#define DMA_ISR_TEIF2_BIT               7
136
-#define DMA_ISR_HTIF2_BIT               6
137
-#define DMA_ISR_TCIF2_BIT               5
138
-#define DMA_ISR_GIF2_BIT                4
139
-#define DMA_ISR_TEIF1_BIT               3
140
-#define DMA_ISR_HTIF1_BIT               2
141
-#define DMA_ISR_TCIF1_BIT               1
142
-#define DMA_ISR_GIF1_BIT                0
143
-
144
-#define DMA_ISR_TEIF7                   BIT(DMA_ISR_TEIF7_BIT)
145
-#define DMA_ISR_HTIF7                   BIT(DMA_ISR_HTIF7_BIT)
146
-#define DMA_ISR_TCIF7                   BIT(DMA_ISR_TCIF7_BIT)
147
-#define DMA_ISR_GIF7                    BIT(DMA_ISR_GIF7_BIT)
148
-#define DMA_ISR_TEIF6                   BIT(DMA_ISR_TEIF6_BIT)
149
-#define DMA_ISR_HTIF6                   BIT(DMA_ISR_HTIF6_BIT)
150
-#define DMA_ISR_TCIF6                   BIT(DMA_ISR_TCIF6_BIT)
151
-#define DMA_ISR_GIF6                    BIT(DMA_ISR_GIF6_BIT)
152
-#define DMA_ISR_TEIF5                   BIT(DMA_ISR_TEIF5_BIT)
153
-#define DMA_ISR_HTIF5                   BIT(DMA_ISR_HTIF5_BIT)
154
-#define DMA_ISR_TCIF5                   BIT(DMA_ISR_TCIF5_BIT)
155
-#define DMA_ISR_GIF5                    BIT(DMA_ISR_GIF5_BIT)
156
-#define DMA_ISR_TEIF4                   BIT(DMA_ISR_TEIF4_BIT)
157
-#define DMA_ISR_HTIF4                   BIT(DMA_ISR_HTIF4_BIT)
158
-#define DMA_ISR_TCIF4                   BIT(DMA_ISR_TCIF4_BIT)
159
-#define DMA_ISR_GIF4                    BIT(DMA_ISR_GIF4_BIT)
160
-#define DMA_ISR_TEIF3                   BIT(DMA_ISR_TEIF3_BIT)
161
-#define DMA_ISR_HTIF3                   BIT(DMA_ISR_HTIF3_BIT)
162
-#define DMA_ISR_TCIF3                   BIT(DMA_ISR_TCIF3_BIT)
163
-#define DMA_ISR_GIF3                    BIT(DMA_ISR_GIF3_BIT)
164
-#define DMA_ISR_TEIF2                   BIT(DMA_ISR_TEIF2_BIT)
165
-#define DMA_ISR_HTIF2                   BIT(DMA_ISR_HTIF2_BIT)
166
-#define DMA_ISR_TCIF2                   BIT(DMA_ISR_TCIF2_BIT)
167
-#define DMA_ISR_GIF2                    BIT(DMA_ISR_GIF2_BIT)
168
-#define DMA_ISR_TEIF1                   BIT(DMA_ISR_TEIF1_BIT)
169
-#define DMA_ISR_HTIF1                   BIT(DMA_ISR_HTIF1_BIT)
170
-#define DMA_ISR_TCIF1                   BIT(DMA_ISR_TCIF1_BIT)
171
-#define DMA_ISR_GIF1                    BIT(DMA_ISR_GIF1_BIT)
172
-
173
-/* Interrupt flag clear register */
174
-
175
-#define DMA_IFCR_CTEIF7_BIT             27
176
-#define DMA_IFCR_CHTIF7_BIT             26
177
-#define DMA_IFCR_CTCIF7_BIT             25
178
-#define DMA_IFCR_CGIF7_BIT              24
179
-#define DMA_IFCR_CTEIF6_BIT             23
180
-#define DMA_IFCR_CHTIF6_BIT             22
181
-#define DMA_IFCR_CTCIF6_BIT             21
182
-#define DMA_IFCR_CGIF6_BIT              20
183
-#define DMA_IFCR_CTEIF5_BIT             19
184
-#define DMA_IFCR_CHTIF5_BIT             18
185
-#define DMA_IFCR_CTCIF5_BIT             17
186
-#define DMA_IFCR_CGIF5_BIT              16
187
-#define DMA_IFCR_CTEIF4_BIT             15
188
-#define DMA_IFCR_CHTIF4_BIT             14
189
-#define DMA_IFCR_CTCIF4_BIT             13
190
-#define DMA_IFCR_CGIF4_BIT              12
191
-#define DMA_IFCR_CTEIF3_BIT             11
192
-#define DMA_IFCR_CHTIF3_BIT             10
193
-#define DMA_IFCR_CTCIF3_BIT             9
194
-#define DMA_IFCR_CGIF3_BIT              8
195
-#define DMA_IFCR_CTEIF2_BIT             7
196
-#define DMA_IFCR_CHTIF2_BIT             6
197
-#define DMA_IFCR_CTCIF2_BIT             5
198
-#define DMA_IFCR_CGIF2_BIT              4
199
-#define DMA_IFCR_CTEIF1_BIT             3
200
-#define DMA_IFCR_CHTIF1_BIT             2
201
-#define DMA_IFCR_CTCIF1_BIT             1
202
-#define DMA_IFCR_CGIF1_BIT              0
203
-
204
-#define DMA_IFCR_CTEIF7                 BIT(DMA_IFCR_CTEIF7_BIT)
205
-#define DMA_IFCR_CHTIF7                 BIT(DMA_IFCR_CHTIF7_BIT)
206
-#define DMA_IFCR_CTCIF7                 BIT(DMA_IFCR_CTCIF7_BIT)
207
-#define DMA_IFCR_CGIF7                  BIT(DMA_IFCR_CGIF7_BIT)
208
-#define DMA_IFCR_CTEIF6                 BIT(DMA_IFCR_CTEIF6_BIT)
209
-#define DMA_IFCR_CHTIF6                 BIT(DMA_IFCR_CHTIF6_BIT)
210
-#define DMA_IFCR_CTCIF6                 BIT(DMA_IFCR_CTCIF6_BIT)
211
-#define DMA_IFCR_CGIF6                  BIT(DMA_IFCR_CGIF6_BIT)
212
-#define DMA_IFCR_CTEIF5                 BIT(DMA_IFCR_CTEIF5_BIT)
213
-#define DMA_IFCR_CHTIF5                 BIT(DMA_IFCR_CHTIF5_BIT)
214
-#define DMA_IFCR_CTCIF5                 BIT(DMA_IFCR_CTCIF5_BIT)
215
-#define DMA_IFCR_CGIF5                  BIT(DMA_IFCR_CGIF5_BIT)
216
-#define DMA_IFCR_CTEIF4                 BIT(DMA_IFCR_CTEIF4_BIT)
217
-#define DMA_IFCR_CHTIF4                 BIT(DMA_IFCR_CHTIF4_BIT)
218
-#define DMA_IFCR_CTCIF4                 BIT(DMA_IFCR_CTCIF4_BIT)
219
-#define DMA_IFCR_CGIF4                  BIT(DMA_IFCR_CGIF4_BIT)
220
-#define DMA_IFCR_CTEIF3                 BIT(DMA_IFCR_CTEIF3_BIT)
221
-#define DMA_IFCR_CHTIF3                 BIT(DMA_IFCR_CHTIF3_BIT)
222
-#define DMA_IFCR_CTCIF3                 BIT(DMA_IFCR_CTCIF3_BIT)
223
-#define DMA_IFCR_CGIF3                  BIT(DMA_IFCR_CGIF3_BIT)
224
-#define DMA_IFCR_CTEIF2                 BIT(DMA_IFCR_CTEIF2_BIT)
225
-#define DMA_IFCR_CHTIF2                 BIT(DMA_IFCR_CHTIF2_BIT)
226
-#define DMA_IFCR_CTCIF2                 BIT(DMA_IFCR_CTCIF2_BIT)
227
-#define DMA_IFCR_CGIF2                  BIT(DMA_IFCR_CGIF2_BIT)
228
-#define DMA_IFCR_CTEIF1                 BIT(DMA_IFCR_CTEIF1_BIT)
229
-#define DMA_IFCR_CHTIF1                 BIT(DMA_IFCR_CHTIF1_BIT)
230
-#define DMA_IFCR_CTCIF1                 BIT(DMA_IFCR_CTCIF1_BIT)
231
-#define DMA_IFCR_CGIF1                  BIT(DMA_IFCR_CGIF1_BIT)
232
-
233
-/* Channel configuration register */
234
-
235
-#define DMA_CCR_MEM2MEM_BIT             14
236
-#define DMA_CCR_MINC_BIT                7
237
-#define DMA_CCR_PINC_BIT                6
238
-#define DMA_CCR_CIRC_BIT                5
239
-#define DMA_CCR_DIR_BIT                 4
240
-#define DMA_CCR_TEIE_BIT                3
241
-#define DMA_CCR_HTIE_BIT                2
242
-#define DMA_CCR_TCIE_BIT                1
243
-#define DMA_CCR_EN_BIT                  0
244
-
245
-#define DMA_CCR_MEM2MEM                 BIT(DMA_CCR_MEM2MEM_BIT)
246
-#define DMA_CCR_PL                      (0x3 << 12)
247
-#define DMA_CCR_PL_LOW                  (0x0 << 12)
248
-#define DMA_CCR_PL_MEDIUM               (0x1 << 12)
249
-#define DMA_CCR_PL_HIGH                 (0x2 << 12)
250
-#define DMA_CCR_PL_VERY_HIGH            (0x3 << 12)
251
-#define DMA_CCR_MSIZE                   (0x3 << 10)
252
-#define DMA_CCR_MSIZE_8BITS             (0x0 << 10)
253
-#define DMA_CCR_MSIZE_16BITS            (0x1 << 10)
254
-#define DMA_CCR_MSIZE_32BITS            (0x2 << 10)
255
-#define DMA_CCR_PSIZE                   (0x3 << 8)
256
-#define DMA_CCR_PSIZE_8BITS             (0x0 << 8)
257
-#define DMA_CCR_PSIZE_16BITS            (0x1 << 8)
258
-#define DMA_CCR_PSIZE_32BITS            (0x2 << 8)
259
-#define DMA_CCR_MINC                    BIT(DMA_CCR_MINC_BIT)
260
-#define DMA_CCR_PINC                    BIT(DMA_CCR_PINC_BIT)
261
-#define DMA_CCR_CIRC                    BIT(DMA_CCR_CIRC_BIT)
262
-#define DMA_CCR_DIR                     BIT(DMA_CCR_DIR_BIT)
263
-#define DMA_CCR_TEIE                    BIT(DMA_CCR_TEIE_BIT)
264
-#define DMA_CCR_HTIE                    BIT(DMA_CCR_HTIE_BIT)
265
-#define DMA_CCR_TCIE                    BIT(DMA_CCR_TCIE_BIT)
266
-#define DMA_CCR_EN                      BIT(DMA_CCR_EN_BIT)
267
-
268
-/*
269
- * Devices
270
- */
271
-
272
-/** Encapsulates state related to a DMA channel interrupt. */
273
-typedef struct dma_handler_config {
274
-    void (*handler)(void);      /**< User-specified channel interrupt
275
-                                     handler */
276
-    nvic_irq_num irq_line;      /**< Channel's NVIC interrupt number */
277
-} dma_handler_config;
278
-
279
-/** DMA device type */
280
-typedef struct dma_dev {
281
-    dma_reg_map *regs;             /**< Register map */
282
-    rcc_clk_id clk_id;             /**< Clock ID */
283
-    dma_handler_config handlers[]; /**<
284
-                                    * @brief IRQ handlers and NVIC numbers.
285
-                                    *
286
-                                    * @see dma_attach_interrupt()
287
-                                    * @see dma_detach_interrupt()
288
-                                    */
289
-} dma_dev;
290
-
291
-extern dma_dev *DMA1;
292
-#ifdef STM32_HIGH_DENSITY
293
-extern dma_dev *DMA2;
294
-#endif
295
-
296
-/*
297
- * Convenience functions
298
- */
299
-
300
-void dma_init(dma_dev *dev);
301
-
302
-/** Flags for DMA transfer configuration. */
303
-typedef enum dma_mode_flags {
304
-    DMA_MEM_2_MEM  = 1 << 14, /**< Memory to memory mode */
305
-    DMA_MINC_MODE  = 1 << 7,  /**< Auto-increment memory address */
306
-    DMA_PINC_MODE  = 1 << 6,  /**< Auto-increment peripheral address */
307
-    DMA_CIRC_MODE  = 1 << 5,  /**< Circular mode */
308
-    DMA_FROM_MEM   = 1 << 4,  /**< Read from memory to peripheral */
309
-    DMA_TRNS_ERR   = 1 << 3,  /**< Interrupt on transfer error */
310
-    DMA_HALF_TRNS  = 1 << 2,  /**< Interrupt on half-transfer */
311
-    DMA_TRNS_CMPLT = 1 << 1   /**< Interrupt on transfer completion */
312
-} dma_mode_flags;
313
-
314
-/** Source and destination transfer sizes. */
315
-typedef enum dma_xfer_size {
316
-    DMA_SIZE_8BITS  = 0,        /**< 8-bit transfers */
317
-    DMA_SIZE_16BITS = 1,        /**< 16-bit transfers */
318
-    DMA_SIZE_32BITS = 2         /**< 32-bit transfers */
319
-} dma_xfer_size;
320
-
321
-/** DMA channel */
322
-typedef enum dma_channel {
323
-    DMA_CH1 = 1,                /**< Channel 1 */
324
-    DMA_CH2 = 2,                /**< Channel 2 */
325
-    DMA_CH3 = 3,                /**< Channel 3 */
326
-    DMA_CH4 = 4,                /**< Channel 4 */
327
-    DMA_CH5 = 5,                /**< Channel 5 */
328
-    DMA_CH6 = 6,                /**< Channel 6 */
329
-    DMA_CH7 = 7,                /**< Channel 7 */
330
-} dma_channel;
331
-
332
-void dma_setup_transfer(dma_dev       *dev,
333
-                        dma_channel    channel,
334
-                        __io void     *peripheral_address,
335
-                        dma_xfer_size  peripheral_size,
336
-                        __io void     *memory_address,
337
-                        dma_xfer_size  memory_size,
338
-                        uint32         mode);
339
-
340
-void dma_set_num_transfers(dma_dev *dev,
341
-                           dma_channel channel,
342
-                           uint16 num_transfers);
343
-
344
-/** DMA transfer priority. */
345
-typedef enum dma_priority {
346
-    DMA_PRIORITY_LOW       = DMA_CCR_PL_LOW,      /**< Low priority */
347
-    DMA_PRIORITY_MEDIUM    = DMA_CCR_PL_MEDIUM,   /**< Medium priority */
348
-    DMA_PRIORITY_HIGH      = DMA_CCR_PL_HIGH,     /**< High priority */
349
-    DMA_PRIORITY_VERY_HIGH = DMA_CCR_PL_VERY_HIGH /**< Very high priority */
350
-} dma_priority;
351
-
352
-void dma_set_priority(dma_dev *dev,
353
-                      dma_channel channel,
354
-                      dma_priority priority);
355
-
356
-void dma_attach_interrupt(dma_dev *dev,
357
-                          dma_channel channel,
358
-                          void (*handler)(void));
359
-void dma_detach_interrupt(dma_dev *dev, dma_channel channel);
360
-
361
-/**
362
- * Encodes the reason why a DMA interrupt was called.
363
- * @see dma_get_irq_cause()
364
- */
365
-typedef enum dma_irq_cause {
366
-    DMA_TRANSFER_COMPLETE,      /**< Transfer is complete. */
367
-    DMA_TRANSFER_HALF_COMPLETE, /**< Transfer is half complete. */
368
-    DMA_TRANSFER_ERROR,         /**< Error occurred during transfer. */
369
-} dma_irq_cause;
370
-
371
-dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel);
372
-
373
-void dma_enable(dma_dev *dev, dma_channel channel);
374
-void dma_disable(dma_dev *dev, dma_channel channel);
375
-
376
-void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *address);
377
-void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *address);
378
-
379
-/**
380
- * @brief DMA channel register map type.
381
- *
382
- * Provides access to an individual channel's registers.
383
- */
384
-typedef struct dma_channel_reg_map {
385
-    __io uint32 CCR;           /**< Channel configuration register */
386
-    __io uint32 CNDTR;         /**< Channel number of data register */
387
-    __io uint32 CPAR;          /**< Channel peripheral address register */
388
-    __io uint32 CMAR;          /**< Channel memory address register */
389
-} dma_channel_reg_map;
390
-
391
-#define DMA_CHANNEL_NREGS 5
392
-
393
-/**
394
- * @brief Obtain a pointer to an individual DMA channel's registers.
395
- *
396
- * For example, dma_channel_regs(DMA1, DMA_CH1)->CCR is DMA1_BASE->CCR1.
397
- *
398
- * @param dev DMA device
399
- * @param channel DMA channel whose channel register map to obtain.
400
- */
401
-static inline dma_channel_reg_map* dma_channel_regs(dma_dev *dev,
402
-                                                    dma_channel channel) {
403
-    __io uint32 *ccr1 = &dev->regs->CCR1;
404
-    return (dma_channel_reg_map*)(ccr1 + DMA_CHANNEL_NREGS * (channel - 1));
405
-}
406
-
407
-/**
408
- * @brief Check if a DMA channel is enabled
409
- * @param dev DMA device
410
- * @param channel Channel whose enabled bit to check.
411
- */
412
-static inline uint8 dma_is_channel_enabled(dma_dev *dev, dma_channel channel) {
413
-    return (uint8)(dma_channel_regs(dev, channel)->CCR & DMA_CCR_EN);
414
-}
415
-
416
-/**
417
- * @brief Get the ISR status bits for a DMA channel.
418
- *
419
- * The bits are returned right-aligned, in the following order:
420
- * transfer error flag, half-transfer flag, transfer complete flag,
421
- * global interrupt flag.
422
- *
423
- * If you're attempting to figure out why a DMA interrupt fired; you
424
- * may find dma_get_irq_cause() more convenient.
425
- *
426
- * @param dev DMA device
427
- * @param channel Channel whose ISR bits to return.
428
- * @see dma_get_irq_cause().
429
- */
430
-static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_channel channel) {
431
-    uint8 shift = (channel - 1) * 4;
432
-    return (dev->regs->ISR >> shift) & 0xF;
433
-}
434
-
435
-/**
436
- * @brief Clear the ISR status bits for a given DMA channel.
437
- *
438
- * If you're attempting to clean up after yourself in a DMA interrupt,
439
- * you may find dma_get_irq_cause() more convenient.
440
- *
441
- * @param dev DMA device
442
- * @param channel Channel whose ISR bits to clear.
443
- * @see dma_get_irq_cause()
444
- */
445
-static inline void dma_clear_isr_bits(dma_dev *dev, dma_channel channel) {
446
-    dev->regs->IFCR = BIT(4 * (channel - 1));
447
-}
448
-
449
-#ifdef __cplusplus
450
-} // extern "C"
451
-#endif
452
-
453
-#endif

+ 61 - 0
libmaple/dma_private.h 파일 보기

@@ -0,0 +1,61 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+*****************************************************************************/
26
+
27
+#ifndef _LIBMAPLE_DMA_PRIVATE_H_
28
+#define _LIBMAPLE_DMA_PRIVATE_H_
29
+
30
+#include <libmaple/dma.h>
31
+#include <libmaple/libmaple_types.h>
32
+
33
+/*
34
+ * IRQ handling
35
+ */
36
+
37
+/* Wrap this in an ifdef to shut up GCC. (We provide DMA_GET_HANDLER
38
+ * in the series support files, which need dma_irq_handler().) */
39
+#ifdef DMA_GET_HANDLER
40
+static __always_inline void dma_irq_handler(dma_dev *dev, dma_tube tube) {
41
+    void (*handler)(void) = DMA_GET_HANDLER(dev, tube);
42
+    if (handler) {
43
+        handler();
44
+        dma_clear_isr_bits(dev, tube); /* in case handler doesn't */
45
+    }
46
+}
47
+#endif
48
+
49
+/*
50
+ * Conveniences for dealing with tube sources/destinations
51
+ */
52
+
53
+enum dma_atype {
54
+    DMA_ATYPE_MEM,
55
+    DMA_ATYPE_PER,
56
+    DMA_ATYPE_OTHER,
57
+};
58
+
59
+enum dma_atype _dma_addr_type(__io void *addr);
60
+
61
+#endif

+ 38 - 25
libmaple/exti.c 파일 보기

@@ -2,6 +2,7 @@
2 2
  * The MIT License
3 3
  *
4 4
  * Copyright (c) 2010 Perry Hung.
5
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
7 8
  * obtaining a copy of this software and associated documentation
@@ -25,14 +26,14 @@
25 26
  *****************************************************************************/
26 27
 
27 28
 /**
28
- * @file exti.c
29
+ * @file libmaple/exti.c
29 30
  * @brief External interrupt control routines
30 31
  */
31 32
 
32
-#include "exti.h"
33
-#include "libmaple.h"
34
-#include "nvic.h"
35
-#include "bitband.h"
33
+#include <libmaple/exti.h>
34
+#include <libmaple/libmaple.h>
35
+#include <libmaple/nvic.h>
36
+#include <libmaple/bitband.h>
36 37
 
37 38
 static inline void dispatch_single_exti(uint32 exti_num);
38 39
 static inline void dispatch_extis(uint32 start, uint32 stop);
@@ -66,7 +67,7 @@ static exti_channel exti_channels[] = {
66 67
 };
67 68
 
68 69
 /*
69
- * Convenience routines
70
+ * Portable routines
70 71
  */
71 72
 
72 73
 /**
@@ -80,13 +81,13 @@ static exti_channel exti_channels[] = {
80 81
  * @param handler Function handler to execute when interrupt is triggered.
81 82
  * @param mode    Type of transition to trigger on, one of:
82 83
  *                EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING.
83
- * @see afio_exti_num
84
- * @see afio_exti_port
84
+ * @see exti_num
85
+ * @see exti_cfg
85 86
  * @see voidFuncPtr
86 87
  * @see exti_trigger_mode
87 88
  */
88
-void exti_attach_interrupt(afio_exti_num num,
89
-                           afio_exti_port port,
89
+void exti_attach_interrupt(exti_num num,
90
+                           exti_cfg port,
90 91
                            voidFuncPtr handler,
91 92
                            exti_trigger_mode mode) {
92 93
     ASSERT(handler);
@@ -108,8 +109,8 @@ void exti_attach_interrupt(afio_exti_num num,
108 109
         break;
109 110
     }
110 111
 
111
-    /* Map num to port */
112
-    afio_exti_select(num, port);
112
+    /* Use the chip-specific exti_select() to map num to port */
113
+    exti_select(num, port);
113 114
 
114 115
     /* Unmask external interrupt request */
115 116
     bb_peri_set_bit(&EXTI_BASE->IMR, num, 1);
@@ -120,10 +121,10 @@ void exti_attach_interrupt(afio_exti_num num,
120 121
 
121 122
 /**
122 123
  * @brief Unregister an external interrupt handler
123
- * @param num Number of the external interrupt line to disable.
124
- * @see afio_exti_num
124
+ * @param num External interrupt line to disable.
125
+ * @see exti_num
125 126
  */
126
-void exti_detach_interrupt(afio_exti_num num) {
127
+void exti_detach_interrupt(exti_num num) {
127 128
     /* First, mask the interrupt request */
128 129
     bb_peri_set_bit(&EXTI_BASE->IMR, num, 0);
129 130
 
@@ -136,27 +137,39 @@ void exti_detach_interrupt(afio_exti_num num) {
136 137
 }
137 138
 
138 139
 /*
140
+ * Private routines
141
+ */
142
+
143
+void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port) {
144
+    uint32 shift = 4 * (num % 4);
145
+    uint32 cr = *exti_cr;
146
+    cr &= ~(0xF << shift);
147
+    cr |= port << shift;
148
+    *exti_cr = cr;
149
+}
150
+
151
+/*
139 152
  * Interrupt handlers
140 153
  */
141 154
 
142 155
 void __irq_exti0(void) {
143
-    dispatch_single_exti(AFIO_EXTI_0);
156
+    dispatch_single_exti(EXTI0);
144 157
 }
145 158
 
146 159
 void __irq_exti1(void) {
147
-    dispatch_single_exti(AFIO_EXTI_1);
160
+    dispatch_single_exti(EXTI1);
148 161
 }
149 162
 
150 163
 void __irq_exti2(void) {
151
-    dispatch_single_exti(AFIO_EXTI_2);
164
+    dispatch_single_exti(EXTI2);
152 165
 }
153 166
 
154 167
 void __irq_exti3(void) {
155
-    dispatch_single_exti(AFIO_EXTI_3);
168
+    dispatch_single_exti(EXTI3);
156 169
 }
157 170
 
158 171
 void __irq_exti4(void) {
159
-    dispatch_single_exti(AFIO_EXTI_4);
172
+    dispatch_single_exti(EXTI4);
160 173
 }
161 174
 
162 175
 void __irq_exti9_5(void) {
@@ -177,7 +190,7 @@ void __irq_exti15_10(void) {
177 190
  * won't actually be cleared in time and the ISR will fire again.  To
178 191
  * compensate, this function NOPs for 2 cycles after clearing the
179 192
  * pending bits to ensure it takes effect. */
180
-static inline void clear_pending_msk(uint32 exti_msk) {
193
+static __always_inline void clear_pending_msk(uint32 exti_msk) {
181 194
     EXTI_BASE->PR = exti_msk;
182 195
     asm volatile("nop");
183 196
     asm volatile("nop");
@@ -185,7 +198,7 @@ static inline void clear_pending_msk(uint32 exti_msk) {
185 198
 
186 199
 /* This dispatch routine is for non-multiplexed EXTI lines only; i.e.,
187 200
  * it doesn't check EXTI_PR. */
188
-static inline void dispatch_single_exti(uint32 exti) {
201
+static __always_inline void dispatch_single_exti(uint32 exti) {
189 202
     voidFuncPtr handler = exti_channels[exti].handler;
190 203
 
191 204
     if (!handler) {
@@ -193,18 +206,18 @@ static inline void dispatch_single_exti(uint32 exti) {
193 206
     }
194 207
 
195 208
     handler();
196
-    clear_pending_msk(BIT(exti));
209
+    clear_pending_msk(1U << exti);
197 210
 }
198 211
 
199 212
 /* Dispatch routine for EXTIs which share an IRQ. */
200
-static inline void dispatch_extis(uint32 start, uint32 stop) {
213
+static __always_inline void dispatch_extis(uint32 start, uint32 stop) {
201 214
     uint32 pr = EXTI_BASE->PR;
202 215
     uint32 handled_msk = 0;
203 216
     uint32 exti;
204 217
 
205 218
     /* Dispatch user handlers for pending EXTIs. */
206 219
     for (exti = start; exti <= stop; exti++) {
207
-        uint32 eb = BIT(exti);
220
+        uint32 eb = (1U << exti);
208 221
         if (pr & eb) {
209 222
             voidFuncPtr handler = exti_channels[exti].handler;
210 223
             if (handler) {

+ 34 - 0
libmaple/exti_private.h 파일 보기

@@ -0,0 +1,34 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+*****************************************************************************/
26
+
27
+#ifndef _LIBMAPLE_EXTI_PRIVATE_H_
28
+#define _LIBMAPLE_EXTI_PRIVATE_H_
29
+
30
+#include <libmaple/exti.h>
31
+
32
+void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port);
33
+
34
+#endif

+ 8 - 14
libmaple/flash.c 파일 보기

@@ -25,30 +25,24 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file flash.c
28
+ * @file libmaple/flash.c
29 29
  * @brief Flash management functions
30 30
  */
31 31
 
32
-#include "libmaple.h"
33
-#include "flash.h"
34
-#include "bitband.h"
35
-
36
-/**
37
- * @brief Turn on the hardware prefetcher.
38
- */
39
-void flash_enable_prefetch(void) {
40
-    *bb_perip(&FLASH_BASE->ACR, FLASH_ACR_PRFTBE_BIT) = 1;
41
-}
32
+#include <libmaple/libmaple_types.h>
33
+#include <libmaple/flash.h>
42 34
 
43 35
 /**
44 36
  * @brief Set flash wait states
45 37
  *
46
- * See ST PM0042, section 3.1 for restrictions on the acceptable value
47
- * of wait_states for a given SYSCLK configuration.
38
+ * Note that not all wait states are available on every MCU. See the
39
+ * Flash programming manual for your MCU for restrictions on the
40
+ * allowed value of wait_states for a given system clock (SYSCLK)
41
+ * frequency.
48 42
  *
49 43
  * @param wait_states number of wait states (one of
50 44
  *                    FLASH_WAIT_STATE_0, FLASH_WAIT_STATE_1,
51
- *                    FLASH_WAIT_STATE_2).
45
+ *                    ..., FLASH_WAIT_STATE_7).
52 46
  */
53 47
 void flash_set_latency(uint32 wait_states) {
54 48
     uint32 val = FLASH_BASE->ACR;

+ 5 - 152
libmaple/gpio.c 파일 보기

@@ -25,77 +25,15 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file gpio.c
29
- * @brief GPIO initialization routine
28
+ * @file libmaple/gpio.c
29
+ * @brief Generic STM32 GPIO support.
30 30
  */
31 31
 
32
-#include "gpio.h"
33
-#include "rcc.h"
32
+#include <libmaple/gpio.h>
33
+#include <libmaple/rcc.h>
34 34
 
35 35
 /*
36
- * GPIO devices
37
- */
38
-
39
-gpio_dev gpioa = {
40
-    .regs      = GPIOA_BASE,
41
-    .clk_id    = RCC_GPIOA,
42
-    .exti_port = AFIO_EXTI_PA,
43
-};
44
-/** GPIO port A device. */
45
-gpio_dev* const GPIOA = &gpioa;
46
-
47
-gpio_dev gpiob = {
48
-    .regs      = GPIOB_BASE,
49
-    .clk_id    = RCC_GPIOB,
50
-    .exti_port = AFIO_EXTI_PB,
51
-};
52
-/** GPIO port B device. */
53
-gpio_dev* const GPIOB = &gpiob;
54
-
55
-gpio_dev gpioc = {
56
-    .regs      = GPIOC_BASE,
57
-    .clk_id    = RCC_GPIOC,
58
-    .exti_port = AFIO_EXTI_PC,
59
-};
60
-/** GPIO port C device. */
61
-gpio_dev* const GPIOC = &gpioc;
62
-
63
-gpio_dev gpiod = {
64
-    .regs      = GPIOD_BASE,
65
-    .clk_id    = RCC_GPIOD,
66
-    .exti_port = AFIO_EXTI_PD,
67
-};
68
-/** GPIO port D device. */
69
-gpio_dev* const GPIOD = &gpiod;
70
-
71
-#ifdef STM32_HIGH_DENSITY
72
-gpio_dev gpioe = {
73
-    .regs      = GPIOE_BASE,
74
-    .clk_id    = RCC_GPIOE,
75
-    .exti_port = AFIO_EXTI_PE,
76
-};
77
-/** GPIO port E device. */
78
-gpio_dev* const GPIOE = &gpioe;
79
-
80
-gpio_dev gpiof = {
81
-    .regs      = GPIOF_BASE,
82
-    .clk_id    = RCC_GPIOF,
83
-    .exti_port = AFIO_EXTI_PF,
84
-};
85
-/** GPIO port F device. */
86
-gpio_dev* const GPIOF = &gpiof;
87
-
88
-gpio_dev gpiog = {
89
-    .regs      = GPIOG_BASE,
90
-    .clk_id    = RCC_GPIOG,
91
-    .exti_port = AFIO_EXTI_PG,
92
-};
93
-/** GPIO port G device. */
94
-gpio_dev* const GPIOG = &gpiog;
95
-#endif
96
-
97
-/*
98
- * GPIO convenience routines
36
+ * GPIO routines
99 37
  */
100 38
 
101 39
 /**
@@ -109,88 +47,3 @@ void gpio_init(gpio_dev *dev) {
109 47
     rcc_clk_enable(dev->clk_id);
110 48
     rcc_reset_dev(dev->clk_id);
111 49
 }
112
-
113
-/**
114
- * Initialize and reset all available GPIO devices.
115
- */
116
-void gpio_init_all(void) {
117
-    gpio_init(GPIOA);
118
-    gpio_init(GPIOB);
119
-    gpio_init(GPIOC);
120
-    gpio_init(GPIOD);
121
-#ifdef STM32_HIGH_DENSITY
122
-    gpio_init(GPIOE);
123
-    gpio_init(GPIOF);
124
-    gpio_init(GPIOG);
125
-#endif
126
-}
127
-
128
-/**
129
- * Set the mode of a GPIO pin.
130
- *
131
- * @param dev GPIO device.
132
- * @param pin Pin on the device whose mode to set, 0--15.
133
- * @param mode General purpose or alternate function mode to set the pin to.
134
- * @see gpio_pin_mode
135
- */
136
-void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) {
137
-    gpio_reg_map *regs = dev->regs;
138
-    __io uint32 *cr = &regs->CRL + (pin >> 3);
139
-    uint32 shift = (pin & 0x7) * 4;
140
-    uint32 tmp = *cr;
141
-
142
-    tmp &= ~(0xF << shift);
143
-    tmp |= (mode == GPIO_INPUT_PU ? GPIO_INPUT_PD : mode) << shift;
144
-    *cr = tmp;
145
-
146
-    if (mode == GPIO_INPUT_PD) {
147
-        regs->ODR &= ~BIT(pin);
148
-    } else if (mode == GPIO_INPUT_PU) {
149
-        regs->ODR |= BIT(pin);
150
-    }
151
-}
152
-
153
-/*
154
- * AFIO
155
- */
156
-
157
-/**
158
- * @brief Initialize the AFIO clock, and reset the AFIO registers.
159
- */
160
-void afio_init(void) {
161
-    rcc_clk_enable(RCC_AFIO);
162
-    rcc_reset_dev(RCC_AFIO);
163
-}
164
-
165
-#define AFIO_EXTI_SEL_MASK 0xF
166
-
167
-/**
168
- * @brief Select a source input for an external interrupt.
169
- *
170
- * @param exti      External interrupt.
171
- * @param gpio_port Port which contains pin to use as source input.
172
- * @see afio_exti_num
173
- * @see afio_exti_port
174
- */
175
-void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) {
176
-    __io uint32 *exti_cr = &AFIO_BASE->EXTICR1 + exti / 4;
177
-    uint32 shift = 4 * (exti % 4);
178
-    uint32 cr = *exti_cr;
179
-
180
-    cr &= ~(AFIO_EXTI_SEL_MASK << shift);
181
-    cr |= gpio_port << shift;
182
-    *exti_cr = cr;
183
-}
184
-
185
-/**
186
- * @brief Perform an alternate function remap.
187
- * @param remapping Remapping to perform.
188
- */
189
-void afio_remap(afio_remap_peripheral remapping) {
190
-    if (remapping & AFIO_REMAP_USE_MAPR2) {
191
-        remapping &= ~AFIO_REMAP_USE_MAPR2;
192
-        AFIO_BASE->MAPR2 |= remapping;
193
-    } else {
194
-        AFIO_BASE->MAPR |= remapping;
195
-    }
196
-}

+ 216 - 272
libmaple/i2c.c 파일 보기

@@ -2,6 +2,7 @@
2 2
  * The MIT License
3 3
  *
4 4
  * Copyright (c) 2010 Perry Hung.
5
+ * Copyright (c) 2012 LeafLabs, LLC.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
7 8
  * obtaining a copy of this software and associated documentation
@@ -25,49 +26,28 @@
25 26
  *****************************************************************************/
26 27
 
27 28
 /**
28
- * @file i2c.c
29
+ * @file libmaple/i2c.c
30
+ * @author Perry Hung <perry@leaflabs.com>
29 31
  * @brief Inter-Integrated Circuit (I2C) support.
30 32
  *
31 33
  * Currently, only master mode is supported.
32 34
  */
33 35
 
34
-#include "libmaple.h"
35
-#include "rcc.h"
36
-#include "gpio.h"
37
-#include "nvic.h"
38
-#include "i2c.h"
39
-#include "string.h"
40
-#include "systick.h"
41
-
42
-static i2c_dev i2c_dev1 = {
43
-    .regs         = I2C1_BASE,
44
-    .gpio_port    = &gpiob,
45
-    .sda_pin      = 7,
46
-    .scl_pin      = 6,
47
-    .clk_id       = RCC_I2C1,
48
-    .ev_nvic_line = NVIC_I2C1_EV,
49
-    .er_nvic_line = NVIC_I2C1_ER,
50
-    .state        = I2C_STATE_DISABLED
51
-};
52
-/** I2C1 device */
53
-i2c_dev* const I2C1 = &i2c_dev1;
54
-
55
-static i2c_dev i2c_dev2 = {
56
-    .regs         = I2C2_BASE,
57
-    .gpio_port    = &gpiob,
58
-    .sda_pin      = 11,
59
-    .scl_pin      = 10,
60
-    .clk_id       = RCC_I2C2,
61
-    .ev_nvic_line = NVIC_I2C2_EV,
62
-    .er_nvic_line = NVIC_I2C2_ER,
63
-    .state        = I2C_STATE_DISABLED
64
-};
65
-/** I2C2 device */
66
-i2c_dev* const I2C2 = &i2c_dev2;
36
+#include "i2c_private.h"
37
+
38
+#include <libmaple/libmaple.h>
39
+#include <libmaple/rcc.h>
40
+#include <libmaple/gpio.h>
41
+#include <libmaple/nvic.h>
42
+#include <libmaple/i2c.h>
43
+#include <libmaple/systick.h>
44
+
45
+#include <string.h>
67 46
 
68 47
 static inline int32 wait_for_state_change(i2c_dev *dev,
69 48
                                           i2c_state state,
70 49
                                           uint32 timeout);
50
+static void set_ccr_trise(i2c_dev *dev, uint32 flags);
71 51
 
72 52
 /**
73 53
  * @brief Fill data register with slave address
@@ -125,10 +105,191 @@ enum {
125 105
 };
126 106
 
127 107
 /**
128
- * @brief IRQ handler for I2C master. Handles transmission/reception.
108
+ * @brief Reset an I2C bus.
109
+ *
110
+ * Reset is accomplished by clocking out pulses until any hung slaves
111
+ * release SDA and SCL, then generating a START condition, then a STOP
112
+ * condition.
113
+ *
114
+ * @param dev I2C device
115
+ */
116
+void i2c_bus_reset(const i2c_dev *dev) {
117
+    /* Release both lines */
118
+    i2c_master_release_bus(dev);
119
+
120
+    /*
121
+     * Make sure the bus is free by clocking it until any slaves release the
122
+     * bus.
123
+     */
124
+    while (!gpio_read_bit(sda_port(dev), dev->sda_pin)) {
125
+        /* Wait for any clock stretching to finish */
126
+        while (!gpio_read_bit(scl_port(dev), dev->scl_pin))
127
+            ;
128
+        delay_us(10);
129
+
130
+        /* Pull low */
131
+        gpio_write_bit(scl_port(dev), dev->scl_pin, 0);
132
+        delay_us(10);
133
+
134
+        /* Release high again */
135
+        gpio_write_bit(scl_port(dev), dev->scl_pin, 1);
136
+        delay_us(10);
137
+    }
138
+
139
+    /* Generate start then stop condition */
140
+    gpio_write_bit(sda_port(dev), dev->sda_pin, 0);
141
+    delay_us(10);
142
+    gpio_write_bit(scl_port(dev), dev->scl_pin, 0);
143
+    delay_us(10);
144
+    gpio_write_bit(scl_port(dev), dev->scl_pin, 1);
145
+    delay_us(10);
146
+    gpio_write_bit(sda_port(dev), dev->sda_pin, 1);
147
+}
148
+
149
+/**
150
+ * @brief Initialize an I2C device and reset its registers to their
151
+ *        default values.
152
+ * @param dev Device to initialize.
153
+ */
154
+void i2c_init(i2c_dev *dev) {
155
+    rcc_reset_dev(dev->clk_id);
156
+    rcc_clk_enable(dev->clk_id);
157
+}
158
+
159
+/* Hack for deprecated bit of STM32F1 functionality */
160
+#ifndef _I2C_HAVE_DEPRECATED_I2C_REMAP
161
+#define _i2c_handle_remap(dev, flags) ((void)0)
162
+#endif
163
+
164
+/**
165
+ * @brief Initialize an I2C device as bus master
166
+ * @param dev Device to enable
167
+ * @param flags Bitwise or of the following I2C options:
168
+ *              I2C_FAST_MODE: 400 khz operation,
169
+ *              I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for
170
+ *                             fast mode),
171
+ *              I2C_BUS_RESET: Reset the bus and clock out any hung slaves on
172
+ *                             initialization,
173
+ *              I2C_10BIT_ADDRESSING: Enable 10-bit addressing,
174
+ *              I2C_REMAP: (deprecated, STM32F1 only) Remap I2C1 to SCL/PB8
175
+ *                         SDA/PB9.
176
+ */
177
+void i2c_master_enable(i2c_dev *dev, uint32 flags) {
178
+    /* PE must be disabled to configure the device */
179
+    ASSERT(!(dev->regs->CR1 & I2C_CR1_PE));
180
+
181
+    /* Ugh */
182
+    _i2c_handle_remap(dev, flags);
183
+
184
+    /* Reset the bus. Clock out any hung slaves. */
185
+    if (flags & I2C_BUS_RESET) {
186
+        i2c_bus_reset(dev);
187
+    }
188
+
189
+    /* Turn on clock and set GPIO modes */
190
+    i2c_init(dev);
191
+    i2c_config_gpios(dev);
192
+
193
+    /* Configure clock and rise time */
194
+    set_ccr_trise(dev, flags);
195
+
196
+    /* Enable event and buffer interrupts */
197
+    nvic_irq_enable(dev->ev_nvic_line);
198
+    nvic_irq_enable(dev->er_nvic_line);
199
+    i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_BUFFER | I2C_IRQ_ERROR);
200
+
201
+    /* Make it go! */
202
+    i2c_peripheral_enable(dev);
203
+
204
+    dev->state = I2C_STATE_IDLE;
205
+}
206
+
207
+/**
208
+ * @brief Process an i2c transaction.
209
+ *
210
+ * Transactions are composed of one or more i2c_msg's, and may be read
211
+ * or write tranfers.  Multiple i2c_msg's will generate a repeated
212
+ * start in between messages.
213
+ *
129 214
  * @param dev I2C device
215
+ * @param msgs Messages to send/receive
216
+ * @param num Number of messages to send/receive
217
+ * @param timeout Bus idle timeout in milliseconds before aborting the
218
+ *                transfer.  0 denotes no timeout.
219
+ * @return 0 on success,
220
+ *         I2C_ERROR_PROTOCOL if there was a protocol error,
221
+ *         I2C_ERROR_TIMEOUT if the transfer timed out.
130 222
  */
131
-static void i2c_irq_handler(i2c_dev *dev) {
223
+int32 i2c_master_xfer(i2c_dev *dev,
224
+                      i2c_msg *msgs,
225
+                      uint16 num,
226
+                      uint32 timeout) {
227
+    int32 rc;
228
+
229
+    ASSERT(dev->state == I2C_STATE_IDLE);
230
+
231
+    dev->msg = msgs;
232
+    dev->msgs_left = num;
233
+    dev->timestamp = systick_uptime();
234
+    dev->state = I2C_STATE_BUSY;
235
+
236
+    i2c_enable_irq(dev, I2C_IRQ_EVENT);
237
+    i2c_start_condition(dev);
238
+
239
+    rc = wait_for_state_change(dev, I2C_STATE_XFER_DONE, timeout);
240
+    if (rc < 0) {
241
+        goto out;
242
+    }
243
+
244
+    dev->state = I2C_STATE_IDLE;
245
+out:
246
+    return rc;
247
+}
248
+
249
+/**
250
+ * @brief Wait for an I2C event, or time out in case of error.
251
+ * @param dev I2C device
252
+ * @param state I2C_state state to wait for
253
+ * @param timeout Timeout, in milliseconds
254
+ * @return 0 if target state is reached, a negative value on error.
255
+ */
256
+static inline int32 wait_for_state_change(i2c_dev *dev,
257
+                                          i2c_state state,
258
+                                          uint32 timeout) {
259
+    i2c_state tmp;
260
+
261
+    while (1) {
262
+        tmp = dev->state;
263
+
264
+        if (tmp == I2C_STATE_ERROR) {
265
+            return I2C_STATE_ERROR;
266
+        }
267
+
268
+        if (tmp == state) {
269
+            return 0;
270
+        }
271
+
272
+        if (timeout) {
273
+            if (systick_uptime() > (dev->timestamp + timeout)) {
274
+                /* TODO: overflow? */
275
+                /* TODO: racy? */
276
+                return I2C_ERROR_TIMEOUT;
277
+            }
278
+        }
279
+    }
280
+}
281
+
282
+/*
283
+ * Private API
284
+ */
285
+
286
+/*
287
+ * IRQ handler for I2C master. Handles transmission/reception.
288
+ */
289
+void _i2c_irq_handler(i2c_dev *dev) {
290
+    /* WTFs:
291
+     * - Where is I2C_MSG_10BIT_ADDR handled?
292
+     */
132 293
     i2c_msg *msg = dev->msg;
133 294
 
134 295
     uint8 read = msg->flags & I2C_MSG_READ;
@@ -214,7 +375,7 @@ static void i2c_irq_handler(i2c_dev *dev) {
214 375
             /*
215 376
              * This should be impossible...
216 377
              */
217
-            throb();
378
+            ASSERT(0);
218 379
         }
219 380
         sr1 = sr2 = 0;
220 381
     }
@@ -288,20 +449,11 @@ static void i2c_irq_handler(i2c_dev *dev) {
288 449
     }
289 450
 }
290 451
 
291
-void __irq_i2c1_ev(void) {
292
-   i2c_irq_handler(&i2c_dev1);
293
-}
294
-
295
-void __irq_i2c2_ev(void) {
296
-   i2c_irq_handler(&i2c_dev2);
297
-}
298
-
299
-/**
300
- * @brief Interrupt handler for I2C error conditions
301
- * @param dev I2C device
302
- * @sideeffect Aborts any pending I2C transactions
452
+/*
453
+ * Interrupt handler for I2C error conditions. Aborts any pending I2C
454
+ * transactions.
303 455
  */
304
-static void i2c_irq_error_handler(i2c_dev *dev) {
456
+void _i2c_irq_error_handler(i2c_dev *dev) {
305 457
     I2C_CRUMB(ERROR_ENTRY, dev->regs->SR1, dev->regs->SR2);
306 458
 
307 459
     dev->error_flags = dev->regs->SR2 & (I2C_SR1_BERR |
@@ -317,125 +469,34 @@ static void i2c_irq_error_handler(i2c_dev *dev) {
317 469
     dev->state = I2C_STATE_ERROR;
318 470
 }
319 471
 
320
-void __irq_i2c1_er(void) {
321
-    i2c_irq_error_handler(&i2c_dev1);
322
-}
323
-
324
-void __irq_i2c2_er(void) {
325
-    i2c_irq_error_handler(&i2c_dev2);
326
-}
327
-
328
-/**
329
- * @brief Reset an I2C bus.
330
- *
331
- * Reset is accomplished by clocking out pulses until any hung slaves
332
- * release SDA and SCL, then generating a START condition, then a STOP
333
- * condition.
334
- *
335
- * @param dev I2C device
336
- */
337
-void i2c_bus_reset(const i2c_dev *dev) {
338
-    /* Release both lines */
339
-    gpio_write_bit(dev->gpio_port, dev->scl_pin, 1);
340
-    gpio_write_bit(dev->gpio_port, dev->sda_pin, 1);
341
-    gpio_set_mode(dev->gpio_port, dev->scl_pin, GPIO_OUTPUT_OD);
342
-    gpio_set_mode(dev->gpio_port, dev->sda_pin, GPIO_OUTPUT_OD);
343
-
344
-    /*
345
-     * Make sure the bus is free by clocking it until any slaves release the
346
-     * bus.
347
-     */
348
-    while (!gpio_read_bit(dev->gpio_port, dev->sda_pin)) {
349
-        /* Wait for any clock stretching to finish */
350
-        while (!gpio_read_bit(dev->gpio_port, dev->scl_pin))
351
-            ;
352
-        delay_us(10);
353
-
354
-        /* Pull low */
355
-        gpio_write_bit(dev->gpio_port, dev->scl_pin, 0);
356
-        delay_us(10);
357
-
358
-        /* Release high again */
359
-        gpio_write_bit(dev->gpio_port, dev->scl_pin, 1);
360
-        delay_us(10);
361
-    }
362
-
363
-    /* Generate start then stop condition */
364
-    gpio_write_bit(dev->gpio_port, dev->sda_pin, 0);
365
-    delay_us(10);
366
-    gpio_write_bit(dev->gpio_port, dev->scl_pin, 0);
367
-    delay_us(10);
368
-    gpio_write_bit(dev->gpio_port, dev->scl_pin, 1);
369
-    delay_us(10);
370
-    gpio_write_bit(dev->gpio_port, dev->sda_pin, 1);
371
-}
372
-
373
-/**
374
- * @brief Initialize an I2C device and reset its registers to their
375
- *        default values.
376
- * @param dev Device to initialize.
472
+/*
473
+ * CCR/TRISE configuration helper
377 474
  */
378
-void i2c_init(i2c_dev *dev) {
379
-    rcc_reset_dev(dev->clk_id);
380
-    rcc_clk_enable(dev->clk_id);
381
-}
475
+static void set_ccr_trise(i2c_dev *dev, uint32 flags) {
476
+    uint32 ccr     = 0;
477
+    uint32 trise   = 0;
478
+    uint32 clk_mhz = _i2c_bus_clk(dev);
479
+    uint32 clk_hz  = clk_mhz * (1000 * 1000);
382 480
 
383
-/**
384
- * @brief Initialize an I2C device as bus master
385
- * @param dev Device to enable
386
- * @param flags Bitwise or of the following I2C options:
387
- *              I2C_FAST_MODE: 400 khz operation,
388
- *              I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for
389
- *                             fast mode),
390
- *              I2C_BUS_RESET: Reset the bus and clock out any hung slaves on
391
- *                             initialization,
392
- *              I2C_10BIT_ADDRESSING: Enable 10-bit addressing,
393
- *              I2C_REMAP: Remap I2C1 to SCL/PB8 SDA/PB9.
394
- */
395
-void i2c_master_enable(i2c_dev *dev, uint32 flags) {
396
-#define I2C_CLK                (STM32_PCLK1/1000000)
397
-    uint32 ccr   = 0;
398
-    uint32 trise = 0;
399
-
400
-    /* PE must be disabled to configure the device */
401
-    ASSERT(!(dev->regs->CR1 & I2C_CR1_PE));
402
-
403
-    if ((dev == I2C1) && (flags & I2C_REMAP)) {
404
-        afio_remap(AFIO_REMAP_I2C1);
405
-        I2C1->sda_pin = 9;
406
-        I2C1->scl_pin = 8;
407
-    }
408
-
409
-    /* Reset the bus. Clock out any hung slaves. */
410
-    if (flags & I2C_BUS_RESET) {
411
-        i2c_bus_reset(dev);
412
-    }
413
-
414
-    /* Turn on clock and set GPIO modes */
415
-    i2c_init(dev);
416
-    gpio_set_mode(dev->gpio_port, dev->sda_pin, GPIO_AF_OUTPUT_OD);
417
-    gpio_set_mode(dev->gpio_port, dev->scl_pin, GPIO_AF_OUTPUT_OD);
418
-
419
-    /* I2C1 and I2C2 are fed from APB1, clocked at 36MHz */
420
-    i2c_set_input_clk(dev, I2C_CLK);
481
+    i2c_set_input_clk(dev, clk_mhz);
421 482
 
422 483
     if (flags & I2C_FAST_MODE) {
423 484
         ccr |= I2C_CCR_FS;
424 485
 
425 486
         if (flags & I2C_DUTY_16_9) {
426 487
             /* Tlow/Thigh = 16/9 */
427
-            ccr |= I2C_CCR_DUTY;
428
-            ccr |= STM32_PCLK1/(400000 * 25);
488
+            ccr |= I2C_CCR_DUTY_16_9;
489
+            ccr |= clk_hz / (400000 * 25);
429 490
         } else {
430 491
             /* Tlow/Thigh = 2 */
431
-            ccr |= STM32_PCLK1/(400000 * 3);
492
+            ccr |= clk_hz / (400000 * 3);
432 493
         }
433 494
 
434
-        trise = (300 * (I2C_CLK)/1000) + 1;
495
+        trise = (300 * clk_mhz / 1000) + 1;
435 496
     } else {
436 497
         /* Tlow/Thigh = 1 */
437
-        ccr = STM32_PCLK1/(100000 * 2);
438
-        trise = I2C_CLK + 1;
498
+        ccr = clk_hz / (100000 * 2);
499
+        trise = clk_mhz + 1;
439 500
     }
440 501
 
441 502
     /* Set minimum required value if CCR < 1*/
@@ -445,121 +506,4 @@ void i2c_master_enable(i2c_dev *dev, uint32 flags) {
445 506
 
446 507
     i2c_set_clk_control(dev, ccr);
447 508
     i2c_set_trise(dev, trise);
448
-
449
-    /* Enable event and buffer interrupts */
450
-    nvic_irq_enable(dev->ev_nvic_line);
451
-    nvic_irq_enable(dev->er_nvic_line);
452
-    i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_BUFFER | I2C_IRQ_ERROR);
453
-
454
-    /*
455
-     * Important STM32 Errata:
456
-     *
457
-     * See STM32F10xx8 and STM32F10xxB Errata sheet (Doc ID 14574 Rev 8),
458
-     * Section 2.11.1, 2.11.2.
459
-     *
460
-     * 2.11.1:
461
-     * When the EV7, EV7_1, EV6_1, EV6_3, EV2, EV8, and EV3 events are not
462
-     * managed before the current byte is being transferred, problems may be
463
-     * encountered such as receiving an extra byte, reading the same data twice
464
-     * or missing data.
465
-     *
466
-     * 2.11.2:
467
-     * In Master Receiver mode, when closing the communication using
468
-     * method 2, the content of the last read data can be corrupted.
469
-     *
470
-     * If the user software is not able to read the data N-1 before the STOP
471
-     * condition is generated on the bus, the content of the shift register
472
-     * (data N) will be corrupted. (data N is shifted 1-bit to the left).
473
-     *
474
-     * ----------------------------------------------------------------------
475
-     *
476
-     * In order to ensure that events are not missed, the i2c interrupt must
477
-     * not be preempted. We set the i2c interrupt priority to be the highest
478
-     * interrupt in the system (priority level 0). All other interrupts have
479
-     * been initialized to priority level 16. See nvic_init().
480
-     */
481
-    nvic_irq_set_priority(dev->ev_nvic_line, 0);
482
-    nvic_irq_set_priority(dev->er_nvic_line, 0);
483
-
484
-    /* Make it go! */
485
-    i2c_peripheral_enable(dev);
486
-
487
-    dev->state = I2C_STATE_IDLE;
488
-}
489
-
490
-
491
-/**
492
- * @brief Process an i2c transaction.
493
- *
494
- * Transactions are composed of one or more i2c_msg's, and may be read
495
- * or write tranfers.  Multiple i2c_msg's will generate a repeated
496
- * start in between messages.
497
- *
498
- * @param dev I2C device
499
- * @param msgs Messages to send/receive
500
- * @param num Number of messages to send/receive
501
- * @param timeout Bus idle timeout in milliseconds before aborting the
502
- *                transfer.  0 denotes no timeout.
503
- * @return 0 on success,
504
- *         I2C_ERROR_PROTOCOL if there was a protocol error,
505
- *         I2C_ERROR_TIMEOUT if the transfer timed out.
506
- */
507
-int32 i2c_master_xfer(i2c_dev *dev,
508
-                      i2c_msg *msgs,
509
-                      uint16 num,
510
-                      uint32 timeout) {
511
-    int32 rc;
512
-
513
-    ASSERT(dev->state == I2C_STATE_IDLE);
514
-
515
-    dev->msg = msgs;
516
-    dev->msgs_left = num;
517
-    dev->timestamp = systick_uptime();
518
-    dev->state = I2C_STATE_BUSY;
519
-
520
-    i2c_enable_irq(dev, I2C_IRQ_EVENT);
521
-    i2c_start_condition(dev);
522
-
523
-    rc = wait_for_state_change(dev, I2C_STATE_XFER_DONE, timeout);
524
-    if (rc < 0) {
525
-        goto out;
526
-    }
527
-
528
-    dev->state = I2C_STATE_IDLE;
529
-out:
530
-    return rc;
531
-}
532
-
533
-
534
-/**
535
- * @brief Wait for an I2C event, or time out in case of error.
536
- * @param dev I2C device
537
- * @param state I2C_state state to wait for
538
- * @param timeout Timeout, in milliseconds
539
- * @return 0 if target state is reached, a negative value on error.
540
- */
541
-static inline int32 wait_for_state_change(i2c_dev *dev,
542
-                                          i2c_state state,
543
-                                          uint32 timeout) {
544
-    i2c_state tmp;
545
-
546
-    while (1) {
547
-        tmp = dev->state;
548
-
549
-        if (tmp == I2C_STATE_ERROR) {
550
-            return I2C_STATE_ERROR;
551
-        }
552
-
553
-        if (tmp == state) {
554
-            return 0;
555
-        }
556
-
557
-        if (timeout) {
558
-            if (systick_uptime() > (dev->timestamp + timeout)) {
559
-                /* TODO: overflow? */
560
-                /* TODO: racy? */
561
-                return I2C_ERROR_TIMEOUT;
562
-            }
563
-        }
564
-    }
565 509
 }

+ 79 - 0
libmaple/i2c_private.h 파일 보기

@@ -0,0 +1,79 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+#ifndef _LIBMAPLE_I2C_PRIVATE_H_
28
+#define _LIBMAPLE_I2C_PRIVATE_H_
29
+
30
+#include <libmaple/i2c_common.h>
31
+
32
+/* For old-style definitions (SDA/SCL on same GPIO device) */
33
+#define I2C_DEV_OLD(num, port, sda, scl)          \
34
+    {                                             \
35
+        .regs         = I2C##num##_BASE,          \
36
+        .gpio_port    = port,                     \
37
+        .scl_port     = NULL,                     \
38
+        .sda_port     = NULL,                     \
39
+        .sda_pin      = sda,                      \
40
+        .scl_pin      = scl,                      \
41
+        .clk_id       = RCC_I2C##num,             \
42
+        .ev_nvic_line = NVIC_I2C##num##_EV,       \
43
+        .er_nvic_line = NVIC_I2C##num##_ER,       \
44
+        .state        = I2C_STATE_DISABLED,       \
45
+    }
46
+
47
+/* For new-style definitions (SDA/SCL may be on different GPIO devices) */
48
+#define I2C_DEV_NEW(num, sdaport, sdabit, sclport, sclbit)          \
49
+    {                                                               \
50
+        .regs         = I2C##num##_BASE,                            \
51
+        .gpio_port    = NULL,                                       \
52
+        .scl_port     = sclport,                                    \
53
+        .scl_pin      = sclbit,                                     \
54
+        .sda_port     = sdaport,                                    \
55
+        .sda_pin      = sdabit,                                     \
56
+        .clk_id       = RCC_I2C##num,                               \
57
+        .ev_nvic_line = NVIC_I2C##num##_EV,                         \
58
+        .er_nvic_line = NVIC_I2C##num##_ER,                         \
59
+        .state        = I2C_STATE_DISABLED,                         \
60
+    }
61
+
62
+void _i2c_irq_handler(i2c_dev *dev);
63
+void _i2c_irq_error_handler(i2c_dev *dev);
64
+
65
+struct gpio_dev;
66
+
67
+static inline struct gpio_dev* scl_port(const i2c_dev *dev) {
68
+    return (dev->gpio_port == NULL) ? dev->scl_port : dev->gpio_port;
69
+}
70
+
71
+static inline struct gpio_dev* sda_port(const i2c_dev *dev) {
72
+    return (dev->gpio_port == NULL) ? dev->sda_port : dev->gpio_port;
73
+}
74
+
75
+/* Auxiliary procedure for enabling an I2C peripheral; `flags' as for
76
+ * i2c_master_enable(). */
77
+void _i2c_set_ccr_trise(i2c_dev *dev, uint32 flags);
78
+
79
+#endif  /* _LIBMAPLE_I2C_PRIVATE_H_ */

libmaple/adc.h → libmaple/include/libmaple/adc.h 파일 보기

@@ -1,6 +1,7 @@
1 1
 /******************************************************************************
2 2
  * The MIT License
3 3
  *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
4 5
  * Copyright (c) 2010 Perry Hung.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
@@ -25,22 +26,29 @@
25 26
  *****************************************************************************/
26 27
 
27 28
 /**
28
- *  @file adc.h
29
- *
30
- *  @brief Analog-to-Digital Conversion (ADC) header.
29
+ * @file libmaple/include/libmaple/adc.h
30
+ * @author Marti Bolivar <mbolivar@leaflabs.com>,
31
+ *         Perry Hung <perry@leaflabs.com>
32
+ * @brief Analog-to-Digital Conversion (ADC) header.
31 33
  */
32 34
 
33
-#ifndef _ADC_H_
34
-#define _ADC_H_
35
-
36
-#include "libmaple.h"
37
-#include "bitband.h"
38
-#include "rcc.h"
35
+#ifndef _LIBMAPLE_ADC_H_
36
+#define _LIBMAPLE_ADC_H_
39 37
 
40 38
 #ifdef __cplusplus
41 39
 extern "C"{
42 40
 #endif
43 41
 
42
+#include <libmaple/libmaple.h>
43
+#include <libmaple/bitband.h>
44
+#include <libmaple/rcc.h>
45
+/* We include the series header below, after defining the register map
46
+ * and device structs. */
47
+
48
+/*
49
+ * Register map
50
+ */
51
+
44 52
 /** ADC register map type. */
45 53
 typedef struct adc_reg_map {
46 54
     __io uint32 SR;             ///< Status register
@@ -71,24 +79,30 @@ typedef struct adc_dev {
71 79
     rcc_clk_id clk_id; /**< RCC clock information */
72 80
 } adc_dev;
73 81
 
74
-extern const adc_dev *ADC1;
75
-extern const adc_dev *ADC2;
76
-#ifdef STM32_HIGH_DENSITY
77
-extern const adc_dev *ADC3;
78
-#endif
79
-
80
-/*
81
- * Register map base pointers
82
+/* Pull in the series header (which may need the above struct
83
+ * definitions).
84
+ *
85
+ * IMPORTANT: The series header must define the following:
86
+ *
87
+ * - enum adc_extsel_event (and typedef to adc_extsel_event): One per
88
+ *   external event used to trigger start of conversion of a regular
89
+ *   group. If two different series support the same event as a
90
+ *   trigger, they must use the same token for the enumerator for that
91
+ *   event. (The value of the enumerator is of course allowed to be
92
+ *   different).
93
+ *
94
+ * - enum adc_smp_rate (and typedef to adc_smp_rate): One per
95
+ *   available sampling time.  These must be in the form ADC_SMPR_X_Y
96
+ *   for X.Y cycles (e.g. ADC_SMPR_1_5 means 1.5 cycles), or
97
+ *   ADC_SMPR_X for X cycles (e.g. ADC_SMPR_3 means 3 cycles).
98
+ *
99
+ * - enum adc_prescaler (and typedef): One per available prescaler,
100
+ *   suitable for adc_set_prescaler. Series which have the same
101
+ *   prescaler dividers (e.g. STM32F1 and STM32F2 both divide PCLK2 by
102
+ *   2, 4, 6, or 8) must provide the same tokens as enumerators, for
103
+ *   portability.
82 104
  */
83
-
84
-/** ADC1 register map base pointer. */
85
-#define ADC1_BASE                       ((struct adc_reg_map*)0x40012400)
86
-/** ADC2 register map base pointer. */
87
-#define ADC2_BASE                       ((struct adc_reg_map*)0x40012800)
88
-#ifdef STM32_HIGH_DENSITY
89
-/** ADC3 register map base pointer. */
90
-#define ADC3_BASE                       ((struct adc_reg_map*)0x40013C00)
91
-#endif
105
+#include <series/adc.h>
92 106
 
93 107
 /*
94 108
  * Register bit definitions
@@ -136,31 +150,9 @@ extern const adc_dev *ADC3;
136 150
 
137 151
 /* Control register 2 */
138 152
 
139
-#define ADC_CR2_ADON_BIT                0
140
-#define ADC_CR2_CONT_BIT                1
141
-#define ADC_CR2_CAL_BIT                 2
142
-#define ADC_CR2_RSTCAL_BIT              3
143
-#define ADC_CR2_DMA_BIT                 8
144
-#define ADC_CR2_ALIGN_BIT               11
145
-#define ADC_CR2_JEXTTRIG_BIT            15
146
-#define ADC_CR2_EXTTRIG_BIT             20
147
-#define ADC_CR2_JSWSTART_BIT            21
148
-#define ADC_CR2_SWSTART_BIT             22
149
-#define ADC_CR2_TSEREFE_BIT             23
150
-
151
-#define ADC_CR2_ADON                    BIT(ADC_CR2_ADON_BIT)
152
-#define ADC_CR2_CONT                    BIT(ADC_CR2_CONT_BIT)
153
-#define ADC_CR2_CAL                     BIT(ADC_CR2_CAL_BIT)
154
-#define ADC_CR2_RSTCAL                  BIT(ADC_CR2_RSTCAL_BIT)
155
-#define ADC_CR2_DMA                     BIT(ADC_CR2_DMA_BIT)
156
-#define ADC_CR2_ALIGN                   BIT(ADC_CR2_ALIGN_BIT)
157
-#define ADC_CR2_JEXTSEL                 (0x7000)
158
-#define ADC_CR2_JEXTTRIG                BIT(ADC_CR2_JEXTTRIG_BIT)
159
-#define ADC_CR2_EXTSEL                  (0xE0000)
160
-#define ADC_CR2_EXTTRIG                 BIT(ADC_CR2_EXTTRIG_BIT)
161
-#define ADC_CR2_JSWSTART                BIT(ADC_CR2_JSWSTART_BIT)
162
-#define ADC_CR2_SWSTART                 BIT(ADC_CR2_SWSTART_BIT)
163
-#define ADC_CR2_TSEREFE                 BIT(ADC_CR2_TSEREFE_BIT)
153
+/* Because this register varies significantly by series (e.g. some
154
+ * bits moved and others disappeared in the F1->F2 transition), its
155
+ * definitions are in the series headers. */
164 156
 
165 157
 /* Sample time register 1 */
166 158
 
@@ -245,68 +237,51 @@ extern const adc_dev *ADC3;
245 237
 #define ADC_DR_ADC2DATA                 (0xFFFF << 16)
246 238
 #define ADC_DR_DATA                     0xFFFF
247 239
 
240
+/*
241
+ * Routines
242
+ */
243
+
248 244
 void adc_init(const adc_dev *dev);
245
+void adc_set_extsel(const adc_dev *dev, adc_extsel_event event);
246
+void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate);
247
+uint16 adc_read(const adc_dev *dev, uint8 channel);
249 248
 
250 249
 /**
251
- * @brief External event selector for regular group conversion.
252
- * @see adc_set_extsel
250
+ * @brief Set the ADC prescaler.
251
+ *
252
+ * This determines the ADC clock for all devices.
253 253
  */
254
-typedef enum adc_extsel_event {
255
-    ADC_ADC12_TIM1_CC1  = (0 << 17), /**< ADC1 and ADC2: Timer 1 CC1 event */
256
-    ADC_ADC12_TIM1_CC2  = (1 << 17), /**< ADC1 and ADC2: Timer 1 CC2 event */
257
-    ADC_ADC12_TIM1_CC3  = (2 << 17), /**< ADC1 and ADC2: Timer 1 CC3 event */
258
-    ADC_ADC12_TIM2_CC2  = (3 << 17), /**< ADC1 and ADC2: Timer 2 CC2 event */
259
-    ADC_ADC12_TIM3_TRGO = (4 << 17), /**< ADC1 and ADC2: Timer 3 TRGO event */
260
-    ADC_ADC12_TIM4_CC4  = (5 << 17), /**< ADC1 and ADC2: Timer 4 CC4 event */
261
-    ADC_ADC12_EXTI11    = (6 << 17), /**< ADC1 and ADC2: EXTI11 event */
262
-#ifdef STM32_HIGH_DENSITY
263
-    ADC_ADC12_TIM8_TRGO = (6 << 17), /**< ADC1 and ADC2: Timer 8 TRGO
264
-                                        event (high density only) */
265
-#endif
266
-    ADC_ADC12_SWSTART   = (7 << 17), /**< ADC1 and ADC2: Software start */
267
-#ifdef STM32_HIGH_DENSITY
268
-    ADC_ADC3_TIM3_CC1   = (0 << 17), /**< ADC3: Timer 3 CC1 event
269
-                                        (high density only) */
270
-    ADC_ADC3_TIM2_CC3   = (1 << 17), /**< ADC3: Timer 2 CC3 event
271
-                                        (high density only) */
272
-    ADC_ADC3_TIM1_CC3   = (2 << 17), /**< ADC3: Timer 1 CC3 event
273
-                                        (high density only) */
274
-    ADC_ADC3_TIM8_CC1   = (3 << 17), /**< ADC3: Timer 8 CC1 event
275
-                                        (high density only) */
276
-    ADC_ADC3_TIM8_TRGO  = (4 << 17), /**< ADC3: Timer 8 TRGO event
277
-                                        (high density only) */
278
-    ADC_ADC3_TIM5_CC1   = (5 << 17), /**< ADC3: Timer 5 CC1 event
279
-                                        (high density only) */
280
-    ADC_ADC3_TIM5_CC3   = (6 << 17), /**< ADC3: Timer 5 CC3 event
281
-                                        (high density only) */
282
-    ADC_ADC3_SWSTART    = (7 << 17), /**< ADC3: Software start (high
283
-                                        density only) */
284
-#endif
285
-    ADC_SWSTART         = (7 << 17) /**< ADC1, ADC2, ADC3: Software start */
286
-} adc_extsel_event;
254
+extern void adc_set_prescaler(adc_prescaler pre);
287 255
 
288
-void adc_set_extsel(const adc_dev *dev, adc_extsel_event event);
289
-void adc_foreach(void (*fn)(const adc_dev*));
256
+/**
257
+ * @brief Call a function on all ADC devices.
258
+ * @param fn Function to call on each ADC device.
259
+ */
260
+extern void adc_foreach(void (*fn)(const adc_dev*));
290 261
 
262
+struct gpio_dev;
291 263
 /**
292
- * @brief ADC sample times, in ADC clock cycles
293
- *
294
- * These control the amount of time spent sampling the input voltage.
264
+ * @brief Configure a GPIO pin for ADC conversion.
265
+ * @param dev ADC device to use for conversion (currently ignored on
266
+ *            all targets).
267
+ * @param gdev GPIO device to configure.
268
+ * @param bit Bit on gdev to configure for ADC conversion.
295 269
  */
296
-typedef enum {
297
-    ADC_SMPR_1_5,               /**< 1.5 ADC cycles */
298
-    ADC_SMPR_7_5,               /**< 7.5 ADC cycles */
299
-    ADC_SMPR_13_5,              /**< 13.5 ADC cycles */
300
-    ADC_SMPR_28_5,              /**< 28.5 ADC cycles */
301
-    ADC_SMPR_41_5,              /**< 41.5 ADC cycles */
302
-    ADC_SMPR_55_5,              /**< 55.5 ADC cycles */
303
-    ADC_SMPR_71_5,              /**< 71.5 ADC cycles */
304
-    ADC_SMPR_239_5              /**< 239.5 ADC cycles */
305
-} adc_smp_rate;
270
+extern void adc_config_gpio(const struct adc_dev *dev,
271
+                            struct gpio_dev *gdev,
272
+                            uint8 bit);
306 273
 
307
-void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate);
308
-void adc_calibrate(const adc_dev *dev);
309
-uint16 adc_read(const adc_dev *dev, uint8 channel);
274
+/**
275
+ * @brief Enable an ADC and configure it for single conversion mode.
276
+ *
277
+ * This function performs any initialization necessary to allow the
278
+ * ADC device to perform a single synchronous regular software
279
+ * triggered conversion, using adc_read().
280
+ *
281
+ * @param dev Device to enable.
282
+ * @see adc_read()
283
+ */
284
+extern void adc_enable_single_swstart(const adc_dev* dev);
310 285
 
311 286
 /**
312 287
  * @brief Set the regular channel sequence length.
@@ -325,16 +300,6 @@ static inline void adc_set_reg_seqlen(const adc_dev *dev, uint8 length) {
325 300
 }
326 301
 
327 302
 /**
328
- * @brief Set external trigger conversion mode event for regular channels
329
- * @param dev    ADC device
330
- * @param enable If 1, conversion on external events is enabled; if 0,
331
- *               disabled.
332
- */
333
-static inline void adc_set_exttrig(const adc_dev *dev, uint8 enable) {
334
-    *bb_perip(&dev->regs->CR2, ADC_CR2_EXTTRIG_BIT) = !!enable;
335
-}
336
-
337
-/**
338 303
  * @brief Enable an adc peripheral
339 304
  * @param dev ADC device to enable
340 305
  */

libmaple/bitband.h → libmaple/include/libmaple/bitband.h 파일 보기

@@ -25,15 +25,19 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file bitband.h
28
+ * @file libmaple/include/libmaple/bitband.h
29 29
  *
30 30
  * @brief Bit-banding utility functions
31 31
  */
32 32
 
33
-#include "libmaple_types.h"
33
+#ifndef _LIBMAPLE_BITBAND_H_
34
+#define _LIBMAPLE_BITBAND_H_
34 35
 
35
-#ifndef _BITBAND_H_
36
-#define _BITBAND_H_
36
+#ifdef __cplusplus
37
+extern "C" {
38
+#endif
39
+
40
+#include <libmaple/libmaple_types.h>
37 41
 
38 42
 #define BB_SRAM_REF      0x20000000
39 43
 #define BB_SRAM_BASE     0x22000000
@@ -47,7 +51,7 @@ static inline volatile uint32* __bb_addr(volatile void*,
47 51
 
48 52
 /**
49 53
  * @brief Obtain a pointer to the bit-band address corresponding to a
50
- * bit in a volatile SRAM address.
54
+ *        bit in a volatile SRAM address.
51 55
  * @param address Address in the bit-banded SRAM region
52 56
  * @param bit     Bit in address to bit-band
53 57
  */
@@ -79,7 +83,7 @@ static inline void bb_sram_set_bit(volatile void *address,
79 83
 
80 84
 /**
81 85
  * @brief Obtain a pointer to the bit-band address corresponding to a
82
- * bit in a peripheral address.
86
+ *        bit in a peripheral address.
83 87
  * @param address Address in the bit-banded peripheral region
84 88
  * @param bit     Bit in address to bit-band
85 89
  */
@@ -117,4 +121,8 @@ static inline volatile uint32* __bb_addr(volatile void *address,
117 121
                               bit * 4);
118 122
 }
119 123
 
120
-#endif  /* _BITBAND_H_ */
124
+#ifdef __cplusplus
125
+}
126
+#endif
127
+
128
+#endif

libmaple/bkp.h → libmaple/include/libmaple/bkp.h 파일 보기

@@ -25,19 +25,19 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file bkp.h
29
- * @brief Backup register support.
28
+ * @file libmaple/include/libmaple/bkp.h
29
+ * @brief Backup register support (STM32F1 only).
30 30
  */
31 31
 
32
-#ifndef _BKP_H_
33
-#define _BKP_H_
34
-
35
-#include "libmaple.h"
32
+#ifndef _LIBMAPLE_BKP_H_
33
+#define _LIBMAPLE_BKP_H_
36 34
 
37 35
 #ifdef __cplusplus
38 36
 extern "C" {
39 37
 #endif
40 38
 
39
+#include <libmaple/libmaple.h>
40
+
41 41
 #if defined(STM32_MEDIUM_DENSITY)
42 42
 #define BKP_NR_DATA_REGS 10
43 43
 #elif defined(STM32_HIGH_DENSITY)
@@ -60,7 +60,7 @@ typedef struct bkp_reg_map {
60 60
     __io uint32 RTCCR;          ///< RTC control register
61 61
     __io uint32 CR;             ///< Control register
62 62
     __io uint32 CSR;            ///< Control and status register
63
-#ifdef STM32_HIGH_DENSITY
63
+#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
64 64
     const uint32 RESERVED2;     ///< Reserved
65 65
     const uint32 RESERVED3;     ///< Reserved
66 66
     __io uint32 DR11;           ///< Data register 11

+ 158 - 0
libmaple/include/libmaple/dac.h 파일 보기

@@ -0,0 +1,158 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
5
+ * Copyright (c) 2010 Bryan Newbold.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person
8
+ * obtaining a copy of this software and associated documentation
9
+ * files (the "Software"), to deal in the Software without
10
+ * restriction, including without limitation the rights to use, copy,
11
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ * of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *****************************************************************************/
27
+
28
+/**
29
+ * @file libmaple/include/libmaple/dac.h
30
+ * @brief Digital to analog converter support.
31
+ */
32
+
33
+/* See notes/dac.txt for more info */
34
+
35
+#ifndef _LIBMAPLE_DAC_H_
36
+#define _LIBMAPLE_DAC_H_
37
+
38
+#ifdef __cplusplus
39
+extern "C"{
40
+#endif
41
+
42
+#include <series/dac.h>
43
+#include <libmaple/libmaple_types.h>
44
+#include <libmaple/rcc.h>
45
+#include <libmaple/stm32.h>
46
+
47
+/*
48
+ * Register map base and device pointers.
49
+ *
50
+ * The DACs are the same on all supported targets, so it's not worth
51
+ * repeating these in the series headers.
52
+ */
53
+
54
+#define DAC_BASE                ((struct dac_reg_map*)0x40007400)
55
+
56
+/** DAC device type. */
57
+typedef struct dac_dev {
58
+    dac_reg_map *regs; /**< Register map */
59
+} dac_dev;
60
+
61
+#if STM32_HAVE_DAC
62
+extern const dac_dev *DAC;
63
+#endif
64
+
65
+/*
66
+ * Register bit definitions
67
+ */
68
+
69
+/* Control register */
70
+
71
+/* Channel 1 control */
72
+#define DAC_CR_EN1                  (1U << 0)  /* Enable */
73
+#define DAC_CR_BOFF1                (1U << 1)  /* Output buffer disable */
74
+#define DAC_CR_TEN1                 (1U << 2)  /* Trigger enable */
75
+#define DAC_CR_TSEL1                (0x7 << 3) /* Trigger selection */
76
+#define DAC_CR_WAVE1                (0x3 << 6) /* Noise/triangle wave */
77
+#define DAC_CR_MAMP1                (0xF << 8) /* Mask/amplitude selector */
78
+#define DAC_CR_DMAEN1               (1U << 12) /* DMA enable */
79
+/* Channel 2 control */
80
+#define DAC_CR_EN2                  (1U << 16)  /* Enable */
81
+#define DAC_CR_BOFF2                (1U << 17)  /* Output buffer disable */
82
+#define DAC_CR_TEN2                 (1U << 18)  /* Trigger enable */
83
+#define DAC_CR_TSEL2                (0x7 << 19) /* Trigger selection */
84
+#define DAC_CR_WAVE2                (0x3 << 22) /* Noise/triangle wave */
85
+#define DAC_CR_MAMP2                (0xF << 24) /* Mask/amplitude selector */
86
+#define DAC_CR_DMAEN2               (1U << 28)  /* DMA enable */
87
+
88
+/* Software trigger register */
89
+
90
+#define DAC_SWTRIGR_SWTRIG1         (1U << 0) /* Channel 1 software trigger */
91
+#define DAC_SWTRIGR_SWTRIG2         (1U << 1) /* Channel 2 software trigger */
92
+
93
+/* Channel 1 12-bit right-aligned data holding register */
94
+
95
+#define DAC_DHR12R1_DACC1DHR        0x00000FFF
96
+
97
+/* Channel 1 12-bit left-aligned data holding register */
98
+
99
+#define DAC_DHR12L1_DACC1DHR        0x0000FFF0
100
+
101
+/* Channel 1 8-bit left-aligned data holding register */
102
+
103
+#define DAC_DHR8R1_DACC1DHR         0x000000FF
104
+
105
+/* Channel 2 12-bit right-aligned data holding register */
106
+
107
+#define DAC_DHR12R2_DACC2DHR        0x00000FFF
108
+
109
+/* Channel 2 12-bit left-aligned data holding register */
110
+
111
+#define DAC_DHR12L2_DACC2DHR        0x0000FFF0
112
+
113
+/* Channel 2 8-bit left-aligned data holding register */
114
+
115
+#define DAC_DHR8R2_DACC2DHR         0x000000FF
116
+
117
+/* Dual DAC 12-bit right-aligned data holding register */
118
+
119
+#define DAC_DHR12RD_DACC1DHR        0x00000FFF
120
+#define DAC_DHR12RD_DACC2DHR        0x0FFF0000
121
+
122
+/* Dual DAC 12-bit left-aligned data holding register */
123
+
124
+#define DAC_DHR12LD_DACC1DHR        0x0000FFF0
125
+#define DAC_DHR12LD_DACC2DHR        0xFFF00000
126
+
127
+/* Dual DAC 8-bit left-aligned data holding register */
128
+
129
+#define DAC_DHR8RD_DACC1DHR         0x000000FF
130
+#define DAC_DHR8RD_DACC2DHR         0x0000FF00
131
+
132
+/* Channel 1 data output register */
133
+
134
+#define DAC_DOR1_DACC1DOR           0x00000FFF
135
+
136
+/* Channel 1 data output register */
137
+
138
+#define DAC_DOR2_DACC2DOR           0x00000FFF
139
+
140
+/*
141
+ * Routines
142
+ */
143
+
144
+/* We take the dev argument in these for future-proofing */
145
+
146
+#define DAC_CH1 0x1
147
+#define DAC_CH2 0x2
148
+void dac_init(const dac_dev *dev, uint32 flags);
149
+
150
+void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val);
151
+void dac_enable_channel(const dac_dev *dev, uint8 channel);
152
+void dac_disable_channel(const dac_dev *dev, uint8 channel);
153
+
154
+#ifdef __cplusplus
155
+} // extern "C"
156
+#endif
157
+
158
+#endif

+ 65 - 0
libmaple/include/libmaple/delay.h 파일 보기

@@ -0,0 +1,65 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Perry Hung.
5
+ * Copyright (c) 2011 LeafLabs, LLC.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person
8
+ * obtaining a copy of this software and associated documentation
9
+ * files (the "Software"), to deal in the Software without
10
+ * restriction, including without limitation the rights to use, copy,
11
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ * of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *****************************************************************************/
27
+
28
+/**
29
+ * @file libmaple/include/libmaple/delay.h
30
+ * @brief Delay implementation
31
+ */
32
+
33
+#ifndef _LIBMAPLE_DELAY_H_
34
+#define _LIBMAPLE_DELAY_H_
35
+
36
+#ifdef __cplusplus
37
+extern "C" {
38
+#endif
39
+
40
+#include <libmaple/libmaple_types.h>
41
+#include <libmaple/stm32.h>
42
+
43
+/**
44
+ * @brief Delay the given number of microseconds.
45
+ *
46
+ * @param us Number of microseconds to delay.
47
+ */
48
+static inline void delay_us(uint32 us) {
49
+    us *= STM32_DELAY_US_MULT;
50
+
51
+    /* fudge for function call overhead  */
52
+    us--;
53
+    asm volatile("   mov r0, %[us]          \n\t"
54
+                 "1: subs r0, #1            \n\t"
55
+                 "   bhi 1b                 \n\t"
56
+                 :
57
+                 : [us] "r" (us)
58
+                 : "r0");
59
+}
60
+
61
+#ifdef __cplusplus
62
+}
63
+#endif
64
+
65
+#endif

+ 444 - 0
libmaple/include/libmaple/dma.h 파일 보기

@@ -0,0 +1,444 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Michael Hope.
5
+ * Copyright (c) 2012 LeafLabs, LLC.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person
8
+ * obtaining a copy of this software and associated documentation
9
+ * files (the "Software"), to deal in the Software without
10
+ * restriction, including without limitation the rights to use, copy,
11
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ * of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *****************************************************************************/
27
+
28
+/**
29
+ * @file libmaple/include/libmaple/dma.h
30
+ *
31
+ * @author Marti Bolivar <mbolivar@leaflabs.com>;
32
+ *         Original implementation by Michael Hope
33
+ *
34
+ * @brief Direct Memory Access peripheral support
35
+ */
36
+
37
+#ifndef _LIBMAPLE_DMA_H_
38
+#define _LIBMAPLE_DMA_H_
39
+
40
+#ifdef __cplusplus
41
+extern "C"{
42
+#endif
43
+
44
+/* <series/dma.h> provides:
45
+ *
46
+ * - An opaque dma_tube type, and predefined rvalues for each tube
47
+ *   supported by the series.
48
+ *
49
+ *   A "DMA tube" is a series-specific (hopefully integer) datatype
50
+ *   that abstracts the conduit through which DMA-ed data flow.
51
+ *
52
+ *   Examples: On STM32F1, dma_tube is just an alias for dma_channel,
53
+ *   and the tube values are just DMA_CH1 (=1), DMA_CH2 (=2), etc.
54
+ *
55
+ *   Note that a dma_tube doesn't have to be an enum, and its values
56
+ *   don't have to be integral. They _do_ need to be cheap to pass as
57
+ *   arguments, though.
58
+ *
59
+ * - struct dma_tube_reg_map (and typedef to dma_tube_reg_map). DMA
60
+ *   register maps tend to be split into global registers and per-tube
61
+ *   registers. It's convenient to pass around pointers to a tube's
62
+ *   registers, since that makes it possible to configure or otherwise
63
+ *   mess with a tube without knowing which one you're dealing with.
64
+ *
65
+ * - Base pointers to the various dma_tube_reg_maps.
66
+ *
67
+ *   Examples: On STM32F1, these are DMAxCHy_BASE. You can access
68
+ *   registers like DMAxCHy_BASE->CPAR, etc.
69
+ *
70
+ * - enum dma_request_src (and typedef to dma_request_src). This
71
+ *   specifies the peripheral DMA request sources (e.g. USART TX DMA
72
+ *   requests, etc.).
73
+ *
74
+ * - enum dma_mode_flags (and typedef to dma_mode_flags). Used in
75
+ *   dma_tube_config. If two series both support the same mode flags,
76
+ *   they must use the same enumerator names for those flags (the
77
+ *   values of those enumerators are of course allowed to differ).
78
+ *
79
+ * - Normal stuff: dma_reg_map and base pointers, register bit
80
+ *   definitions, dma_dev pointer declarations, and any other
81
+ *   convenience functions useful for the series. */
82
+#include <series/dma.h>
83
+/* <libmaple/dma_common.h> buys us dma_dev and other necessities. */
84
+#include <libmaple/dma_common.h>
85
+#include <libmaple/libmaple_types.h>
86
+
87
+/*
88
+ * Declarations/documentation for some of the series-provided types.
89
+ */
90
+
91
+/**
92
+ * @brief (Series-dependent) DMA request sources.
93
+ *
94
+ * These specify the various pieces of peripheral functionality which
95
+ * may make DMA requests.  Use them to set up a DMA transfer (see
96
+ * struct dma_tube_config, dma_tube_cfg()).
97
+ */
98
+enum dma_request_src;
99
+
100
+/**
101
+ * @brief (Series-dependent) DMA tube configuration flags.
102
+ * These specify miscellaneous bits of configuration for a DMA tube.
103
+ * @see struct dma_mode_config
104
+ */
105
+enum dma_cfg_flags;
106
+
107
+/**
108
+ * @brief (Series-dependent) DMA tube register map type.
109
+ * This allows you to access a tube's registers as a group.
110
+ * @see dma_tube_regs()
111
+ */
112
+struct dma_tube_reg_map;
113
+
114
+/*
115
+ * Convenience functions
116
+ */
117
+
118
+/* Initialization */
119
+
120
+void dma_init(dma_dev *dev);
121
+
122
+/* dma_tube configuration
123
+ *
124
+ * Use these types and functions to set up DMA transfers, handle
125
+ * interrupts, etc. The main function of interest is dma_tube_cfg(),
126
+ * which the various series implement separately. */
127
+
128
+/**
129
+ * @brief Specifies a DMA tube configuration.
130
+ *
131
+ * Use one of these to set up a DMA transfer by passing it to
132
+ * dma_tube_cfg().
133
+ *
134
+ * @see dma_tube_cfg()
135
+ * @see dma_xfer_size
136
+ */
137
+typedef struct dma_tube_config {
138
+    /** Source of data */
139
+    __io void     *tube_src;
140
+    /** Source transfer size */
141
+    dma_xfer_size  tube_src_size;
142
+
143
+    /** Destination of data */
144
+    __io void     *tube_dst;
145
+    /** Destination transfer size */
146
+    dma_xfer_size  tube_dst_size;
147
+
148
+    /**
149
+     * Number of data to transfer (0 to 65,535).
150
+     *
151
+     * Note that this is NOT measured in bytes; it's measured in
152
+     * number of data, which occur in multiples of tube_src_size. For
153
+     * example, if tube_src_size is DMA_SIZE_32BITS and tube_nr_xfers
154
+     * is 2, then 8 total bytes will be transferred.
155
+     */
156
+    unsigned tube_nr_xfers;
157
+
158
+    /**
159
+     * Target-specific configuration flags.
160
+     *
161
+     * These are an OR of series-specific enum dma_mode_flags values.
162
+     * Consult the documentation for your target for what flags you
163
+     * can use here.
164
+     *
165
+     * Typical flag examples: DMA_CFG_SRC_INC, DMA_CFG_DST_INC,
166
+     * DMA_CFG_CIRC, DMA_CFG_CMPLT_IE, etc.
167
+     */
168
+    unsigned tube_flags;
169
+
170
+    /**
171
+     * Currently unused. You must set this to 0 or something valid for
172
+     * your target. */
173
+    void *target_data;
174
+
175
+    /**
176
+     * Hardware DMA request source.
177
+     *
178
+     * This is ignored for memory-to-memory transfers.
179
+     */
180
+    enum dma_request_src tube_req_src;
181
+} dma_tube_config;
182
+
183
+#define DMA_TUBE_CFG_SUCCESS 0
184
+#define DMA_TUBE_CFG_EREQ    1
185
+#define DMA_TUBE_CFG_ENDATA  2
186
+#define DMA_TUBE_CFG_EDEV    3
187
+#define DMA_TUBE_CFG_ESRC    4
188
+#define DMA_TUBE_CFG_EDST    5
189
+#define DMA_TUBE_CFG_EDIR    6
190
+#define DMA_TUBE_CFG_ESIZE   7
191
+#define DMA_TUBE_CFG_ECFG    0xFF
192
+/**
193
+ * @brief Configure a DMA tube.
194
+ *
195
+ * Use this function to set up a DMA transfer. The tube will be
196
+ * disabled before being reconfigured. The transfer will have low
197
+ * priority by default. You can choose another priority before the
198
+ * transfer begins using dma_set_priority(). You can manage your
199
+ * interrupt handlers for the tube using dma_attach_interrupt() and
200
+ * dma_detach_interrupt().
201
+ *
202
+ * After calling dma_tube_cfg() and performing any other desired
203
+ * configuration, start the transfer using dma_enable().
204
+ *
205
+ * @param dev  DMA device.
206
+ * @param tube DMA tube to configure.
207
+ * @param cfg  Configuration to apply to tube.
208
+ *
209
+ * @return DMA_TUBE_CFG_SUCCESS (0) on success, <0 on failure. On
210
+ *         failure, returned value will be the opposite (-) of one of:
211
+ *
212
+ *         - DMA_TUBE_CFG_EREQ: tube doesn't work with cfg->tube_req_src
213
+ *         - DMA_TUBE_CFG_ENDATA: cfg->tube_[src,dst]_size are
214
+ *           incompatible with cfg->tube_nr_xfers, or cfg->tube_nr_xfers
215
+ *           is out of bounds.
216
+ *         - DMA_TUBE_CFG_EDEV: dev does not support cfg
217
+ *         - DMA_TUBE_CFG_ESRC: bad cfg->tube_src
218
+ *         - DMA_TUBE_CFG_EDST: bad cfg->tube_dst
219
+ *         - DMA_TUBE_CFG_EDIR: dev can't transfer from cfg->tube_src to
220
+ *           cfg->tube_dst
221
+ *         - DMA_TUBE_CFG_ESIZE: something ended up wrong due to MSIZE/PSIZE
222
+ *         - DMA_TUBE_CFG_ECFG: generic "something's wrong"
223
+ *
224
+ * @sideeffect Disables tube. May alter tube's registers even when an
225
+ *             error occurs.
226
+ * @see struct dma_tube_config
227
+ * @see dma_attach_interrupt()
228
+ * @see dma_detach_interrupt()
229
+ * @see dma_enable()
230
+ */
231
+extern int dma_tube_cfg(dma_dev *dev, dma_tube tube, dma_tube_config *cfg);
232
+
233
+/* Other tube configuration functions. You can use these if
234
+ * dma_tube_cfg() isn't enough, or to adjust parts of an existing tube
235
+ * configuration. */
236
+
237
+/** DMA transfer priority. */
238
+typedef enum dma_priority {
239
+    DMA_PRIORITY_LOW       = 0, /**< Low priority */
240
+    DMA_PRIORITY_MEDIUM    = 1, /**< Medium priority */
241
+    DMA_PRIORITY_HIGH      = 2, /**< High priority */
242
+    DMA_PRIORITY_VERY_HIGH = 3, /**< Very high priority */
243
+} dma_priority;
244
+
245
+/**
246
+ * @brief Set the priority of a DMA transfer.
247
+ *
248
+ * You may not call this function while the tube is enabled.
249
+ *
250
+ * @param dev DMA device
251
+ * @param tube DMA tube
252
+ * @param priority priority to set.
253
+ */
254
+extern void dma_set_priority(dma_dev *dev, dma_tube tube,
255
+                             dma_priority priority);
256
+
257
+/**
258
+ * @brief Set the number of data transfers on a DMA tube.
259
+ *
260
+ * You may not call this function while the tube is enabled.
261
+ *
262
+ * @param dev DMA device
263
+ * @param tube Tube through which the transfer will occur.
264
+ * @param num_transfers Number of DMA transactions to set.
265
+ */
266
+extern void dma_set_num_transfers(dma_dev *dev, dma_tube tube,
267
+                                  uint16 num_transfers);
268
+
269
+/**
270
+ * @brief Set the base memory address where data will be read from or
271
+ *        written to.
272
+ *
273
+ * You must not call this function while the tube is enabled.
274
+ *
275
+ * If the DMA memory size is 16 bits, the address is automatically
276
+ * aligned to a half-word.  If the DMA memory size is 32 bits, the
277
+ * address is aligned to a word.
278
+ *
279
+ * @param dev DMA Device
280
+ * @param tube Tube whose base memory address to set.
281
+ * @param address Memory base address to use.
282
+ */
283
+extern void dma_set_mem_addr(dma_dev *dev, dma_tube tube, __io void *address);
284
+
285
+/**
286
+ * @brief Set the base peripheral address where data will be read from
287
+ *        or written to.
288
+ *
289
+ * You must not call this function while the channel is enabled.
290
+ *
291
+ * If the DMA peripheral size is 16 bits, the address is automatically
292
+ * aligned to a half-word. If the DMA peripheral size is 32 bits, the
293
+ * address is aligned to a word.
294
+ *
295
+ * @param dev DMA Device
296
+ * @param tube Tube whose peripheral data register base address to set.
297
+ * @param addr Peripheral memory base address to use.
298
+ */
299
+extern void dma_set_per_addr(dma_dev *dev, dma_tube tube, __io void *address);
300
+
301
+/* Interrupt handling */
302
+
303
+/**
304
+ * @brief Attach an interrupt to a DMA transfer.
305
+ *
306
+ * Interrupts are enabled using series-specific mode flags in
307
+ * dma_tube_cfg().
308
+ *
309
+ * @param dev DMA device
310
+ * @param tube Tube to attach handler to
311
+ * @param handler Interrupt handler to call when tube interrupt fires.
312
+ * @see dma_tube_cfg()
313
+ * @see dma_get_irq_cause()
314
+ * @see dma_detach_interrupt()
315
+ */
316
+extern void dma_attach_interrupt(dma_dev *dev, dma_tube tube,
317
+                                 void (*handler)(void));
318
+
319
+
320
+/**
321
+ * @brief Detach a DMA transfer interrupt handler.
322
+ *
323
+ * After calling this function, the given tube's interrupts will be
324
+ * disabled.
325
+ *
326
+ * @param dev DMA device
327
+ * @param tube Tube whose handler to detach
328
+ * @sideeffect Clears the tube's interrupt enable bits.
329
+ * @see dma_attach_interrupt()
330
+ */
331
+extern void dma_detach_interrupt(dma_dev *dev, dma_tube tube);
332
+
333
+/* Tube enable/disable */
334
+
335
+/**
336
+ * @brief Enable a DMA tube.
337
+ *
338
+ * If the tube has been properly configured, calling this function
339
+ * allows it to start serving DMA requests.
340
+ *
341
+ * @param dev DMA device
342
+ * @param tube Tube to enable
343
+ * @see dma_tube_cfg()
344
+ */
345
+extern void dma_enable(dma_dev *dev, dma_tube tube);
346
+
347
+/**
348
+ * @brief Disable a DMA channel.
349
+ *
350
+ * Calling this function makes the tube stop serving DMA requests.
351
+ *
352
+ * @param dev DMA device
353
+ * @param tube Tube to disable
354
+ */
355
+extern void dma_disable(dma_dev *dev, dma_tube tube);
356
+
357
+/**
358
+ * @brief Check if a DMA tube is enabled.
359
+ * @param dev DMA device.
360
+ * @param tube Tube to check.
361
+ * @return 0 if the tube is disabled, >0 if it is enabled.
362
+ */
363
+static inline uint8 dma_is_enabled(dma_dev *dev, dma_tube tube);
364
+
365
+/* Other conveniences */
366
+
367
+/**
368
+ * @brief Obtain a pointer to an individual DMA tube's registers.
369
+ *
370
+ * Examples:
371
+ *
372
+ * - On STM32F1, dma_channel_regs(DMA1, DMA_CH1)->CCR is DMA1_BASE->CCR1.
373
+ *
374
+ * @param dev DMA device.
375
+ * @param tube DMA tube whose register map to obtain.
376
+ * @return (Series-specific) tube register map.
377
+ */
378
+static inline dma_tube_reg_map* dma_tube_regs(dma_dev *dev, dma_tube tube);
379
+
380
+/**
381
+ * Encodes the reason why a DMA interrupt was called.
382
+ * @see dma_get_irq_cause()
383
+ */
384
+typedef enum dma_irq_cause {
385
+    DMA_TRANSFER_COMPLETE,      /**< Transfer is complete. */
386
+    DMA_TRANSFER_HALF_COMPLETE, /**< Transfer is half complete. */
387
+    DMA_TRANSFER_ERROR,         /**< Error occurred during transfer. */
388
+    DMA_TRANSFER_DME_ERROR,     /**<
389
+                                 * @brief Direct mode error occurred during
390
+                                 *        transfer. */
391
+    DMA_TRANSFER_FIFO_ERROR,    /**< FIFO error occurred during transfer. */
392
+} dma_irq_cause;
393
+
394
+/**
395
+ * @brief Discover the reason why a DMA interrupt was called.
396
+ *
397
+ * You may only call this function within an attached interrupt
398
+ * handler for the given channel.
399
+ *
400
+ * This function resets the internal DMA register state which encodes
401
+ * the cause of the interrupt; consequently, it can only be called
402
+ * once per interrupt handler invocation.
403
+ *
404
+ * @param dev DMA device
405
+ * @param tube Tube whose interrupt is being handled.
406
+ * @return Reason why the interrupt fired.
407
+ * @sideeffect Clears flags in dev's interrupt status registers.
408
+ * @see dma_attach_interrupt()
409
+ * @see dma_irq_cause
410
+ */
411
+extern dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_tube tube);
412
+
413
+/**
414
+ * @brief Get the ISR status bits for a DMA channel.
415
+ *
416
+ * The bits are returned right-aligned, in the order they appear in
417
+ * the corresponding ISR register.
418
+ *
419
+ * If you're trying to figure out why a DMA interrupt fired, you may
420
+ * find dma_get_irq_cause() more convenient.
421
+ *
422
+ * @param dev DMA device
423
+ * @param tube Tube whose ISR bits to return.
424
+ * @see dma_get_irq_cause().
425
+ */
426
+static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_tube tube);
427
+
428
+/**
429
+ * @brief Clear the ISR status bits for a given DMA tube.
430
+ *
431
+ * If you're trying to clean up after yourself in a DMA interrupt, you
432
+ * may find dma_get_irq_cause() more convenient.
433
+ *
434
+ * @param dev DMA device
435
+ * @param tube Tube whose ISR bits to clear.
436
+ * @see dma_get_irq_cause()
437
+ */
438
+static inline void dma_clear_isr_bits(dma_dev *dev, dma_tube tube);
439
+
440
+#ifdef __cplusplus
441
+} // extern "C"
442
+#endif
443
+
444
+#endif

+ 114 - 0
libmaple/include/libmaple/dma_common.h 파일 보기

@@ -0,0 +1,114 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @file libmaple/include/libmaple/dma_common.h
29
+ * @author Marti Bolivar <mbolivar@leaflabs.com>
30
+ * @brief Common DMA sub-header for <series/dma.h> and <libmaple/dma.h>.
31
+ *
32
+ * WARNING: CONTENTS UNSTABLE
33
+ *
34
+ * The existence of this file is an implementation detail.  Its
35
+ * contents are not stable, so never include it directly.  If you need
36
+ * something from here, #include <libmaple/dma.h> instead.
37
+ */
38
+
39
+/*
40
+ * There's a fair amount of common DMA functionality needed by each
41
+ * <series/dma.h> and <libmaple/dma.h>.  This header exists in order
42
+ * to provide it to both, avoiding some hacks and circular
43
+ * dependencies.
44
+ */
45
+
46
+#ifndef _LIBMAPLE_DMA_COMMON_H_
47
+#define _LIBMAPLE_DMA_COMMON_H_
48
+
49
+#ifdef __cplusplus
50
+extern "C"{
51
+#endif
52
+
53
+#include <libmaple/libmaple_types.h>
54
+#include <libmaple/nvic.h>
55
+#include <libmaple/rcc.h>
56
+
57
+/*
58
+ * Devices
59
+ */
60
+
61
+struct dma_reg_map;
62
+
63
+/* Encapsulates state related to user interrupt handlers. You
64
+ * shouldn't touch these directly; use dma_attach_interrupt() and
65
+ * dma_detach_interupt() instead. */
66
+typedef struct dma_handler_config {
67
+    void (*handler)(void);     /* User handler */
68
+    nvic_irq_num irq_line;     /* IRQ line for interrupt */
69
+} dma_handler_config;
70
+
71
+/** DMA device type */
72
+typedef struct dma_dev {
73
+    struct dma_reg_map        *regs;       /**< Register map */
74
+    rcc_clk_id                 clk_id;     /**< Clock ID */
75
+    struct dma_handler_config  handlers[]; /**< For internal use */
76
+} dma_dev;
77
+
78
+/**
79
+ * @brief DMA channels
80
+ *
81
+ * Notes:
82
+ * - This is also the dma_tube type for STM32F1.
83
+ * - Channel 0 is not available on all STM32 series.
84
+ *
85
+ * @see dma_tube
86
+ */
87
+typedef enum dma_channel {
88
+    DMA_CH0 = 0,                /**< Channel 0 */
89
+    DMA_CH1 = 1,                /**< Channel 1 */
90
+    DMA_CH2 = 2,                /**< Channel 2 */
91
+    DMA_CH3 = 3,                /**< Channel 3 */
92
+    DMA_CH4 = 4,                /**< Channel 4 */
93
+    DMA_CH5 = 5,                /**< Channel 5 */
94
+    DMA_CH6 = 6,                /**< Channel 6 */
95
+    DMA_CH7 = 7,                /**< Channel 7 */
96
+} dma_channel;
97
+
98
+/**
99
+ * @brief Source and destination transfer sizes.
100
+ * Use these when initializing a struct dma_tube_config.
101
+ * @see struct dma_tube_config
102
+ * @see dma_tube_cfg
103
+ */
104
+typedef enum dma_xfer_size {
105
+    DMA_SIZE_8BITS  = 0,        /**< 8-bit transfers */
106
+    DMA_SIZE_16BITS = 1,        /**< 16-bit transfers */
107
+    DMA_SIZE_32BITS = 2,        /**< 32-bit transfers */
108
+} dma_xfer_size;
109
+
110
+#ifdef __cplusplus
111
+} // extern "C"
112
+#endif
113
+
114
+#endif

libmaple/exti.h → libmaple/include/libmaple/exti.h 파일 보기

@@ -25,22 +25,26 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file exti.h
29
- * @brief External interrupt control prototypes and defines
28
+ * @file libmaple/include/libmaple/exti.h
29
+ * @brief External interrupt control
30 30
  */
31 31
 
32 32
 /* See notes/exti.txt for more info */
33 33
 
34
-#include "libmaple.h"
35
-#include "gpio.h"
36
-
37
-#ifndef _EXTI_H_
38
-#define _EXTI_H_
34
+#ifndef _LIBMAPLE_EXTI_H_
35
+#define _LIBMAPLE_EXTI_H_
39 36
 
40 37
 #ifdef __cplusplus
41 38
 extern "C"{
42 39
 #endif
43 40
 
41
+#include <series/exti.h>        /* provides EXTI_BASE */
42
+#include <libmaple/libmaple_types.h>
43
+
44
+/*
45
+ * Register map and base pointer.
46
+ */
47
+
44 48
 /** EXTI register map type */
45 49
 typedef struct exti_reg_map {
46 50
     __io uint32 IMR;   /**< Interrupt mask register */
@@ -51,8 +55,50 @@ typedef struct exti_reg_map {
51 55
     __io uint32 PR;    /**< Pending register */
52 56
 } exti_reg_map;
53 57
 
54
-/** EXTI register map base pointer */
55
-#define EXTI_BASE                       ((struct exti_reg_map*)0x40010400)
58
+/*
59
+ * Types: exti_num, exti_cfg, exti_trigger_mode.
60
+ *
61
+ * A combination of these three specifies an external interrupt
62
+ * configuration (see exti_attach_interrupt()).
63
+ */
64
+
65
+/** EXTI line. */
66
+typedef enum exti_num {
67
+    EXTI0,    /**< EXTI line 0 */
68
+    EXTI1,    /**< EXTI line 1 */
69
+    EXTI2,    /**< EXTI line 2 */
70
+    EXTI3,    /**< EXTI line 3 */
71
+    EXTI4,    /**< EXTI line 4 */
72
+    EXTI5,    /**< EXTI line 5 */
73
+    EXTI6,    /**< EXTI line 6 */
74
+    EXTI7,    /**< EXTI line 7 */
75
+    EXTI8,    /**< EXTI line 8 */
76
+    EXTI9,    /**< EXTI line 9 */
77
+    EXTI10,   /**< EXTI line 10 */
78
+    EXTI11,   /**< EXTI line 11 */
79
+    EXTI12,   /**< EXTI line 12 */
80
+    EXTI13,   /**< EXTI line 13 */
81
+    EXTI14,   /**< EXTI line 14 */
82
+    EXTI15,   /**< EXTI line 15 */
83
+} exti_num;
84
+
85
+/**
86
+ * @brief EXTI port configuration
87
+ *
88
+ * These specify which GPIO port an external interrupt line should be
89
+ * connected to.
90
+ */
91
+typedef enum exti_cfg {
92
+    EXTI_PA,                    /**< Use PAx pin */
93
+    EXTI_PB,                    /**< Use PBx pin */
94
+    EXTI_PC,                    /**< Use PCx pin */
95
+    EXTI_PD,                    /**< Use PDx pin */
96
+    EXTI_PE,                    /**< Use PEx pin */
97
+    EXTI_PF,                    /**< Use PFx pin */
98
+    EXTI_PG,                    /**< Use PGx pin */
99
+    EXTI_PH,                    /**< Use PHx pin */
100
+    EXTI_PI,                    /**< Use PIx pin */
101
+} exti_cfg;
56 102
 
57 103
 /** External interrupt trigger mode */
58 104
 typedef enum exti_trigger_mode {
@@ -61,11 +107,29 @@ typedef enum exti_trigger_mode {
61 107
     EXTI_RISING_FALLING  /**< Trigger on both the rising and falling edges */
62 108
 } exti_trigger_mode;
63 109
 
64
-void exti_attach_interrupt(afio_exti_num num,
65
-                           afio_exti_port port,
110
+/*
111
+ * Routines
112
+ */
113
+
114
+void exti_attach_interrupt(exti_num num,
115
+                           exti_cfg port,
66 116
                            voidFuncPtr handler,
67 117
                            exti_trigger_mode mode);
68
-void exti_detach_interrupt(afio_exti_num num);
118
+void exti_detach_interrupt(exti_num num);
119
+
120
+/**
121
+ * @brief Set the GPIO port for an EXTI line.
122
+ *
123
+ * This is a low-level routine that most users will not
124
+ * need. exti_attach_interrupt() handles calling this function
125
+ * appropriately.
126
+ *
127
+ * @param num EXTI line
128
+ * @param port EXTI configuration for GPIO port to connect to num.
129
+ * @see exti_num
130
+ * @see exti_cfg
131
+ */
132
+extern void exti_select(exti_num num, exti_cfg port);
69 133
 
70 134
 #ifdef __cplusplus
71 135
 } // extern "C"

+ 106 - 0
libmaple/include/libmaple/flash.h 파일 보기

@@ -0,0 +1,106 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Perry Hung.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @file libmaple/include/libmaple/flash.h
29
+ * @brief Flash support.
30
+ */
31
+
32
+#ifndef _LIBMAPLE_FLASH_H_
33
+#define _LIBMAPLE_FLASH_H_
34
+
35
+#ifdef __cplusplus
36
+extern "C"{
37
+#endif
38
+
39
+#include <libmaple/libmaple_types.h>
40
+
41
+#define FLASH_WAIT_STATE_0              0x0
42
+#define FLASH_WAIT_STATE_1              0x1
43
+#define FLASH_WAIT_STATE_2              0x2
44
+#define FLASH_WAIT_STATE_3              0x3
45
+#define FLASH_WAIT_STATE_4              0x4
46
+#define FLASH_WAIT_STATE_5              0x5
47
+#define FLASH_WAIT_STATE_6              0x6
48
+#define FLASH_WAIT_STATE_7              0x7
49
+
50
+/* The series header must define:
51
+ *
52
+ * - FLASH_SAFE_WAIT_STATES, the smallest number of wait states that
53
+ *   it is safe to use when SYSCLK is at its fastest documented rate
54
+ *   and the MCU is powered at 3.3V (i.e. this doesn't consider
55
+ *   overclocking or low voltage operation).
56
+ *
57
+ * - The following bit flags, for flash_enable_features():
58
+ *
59
+ *       -- FLASH_PREFETCH: prefetcher
60
+ *       -- FLASH_ICACHE: instruction cache
61
+ *       -- FLASH_DCACHE: data cache
62
+ *
63
+ *   See that function's Doxygen for more restrictions.
64
+ */
65
+#include <series/flash.h>
66
+
67
+#ifdef __DOXYGEN__
68
+/** Flash register map base pointer. */
69
+#define FLASH_BASE
70
+#endif
71
+
72
+/*
73
+ * Flash routines
74
+ */
75
+
76
+void flash_set_latency(uint32 wait_states);
77
+
78
+/**
79
+ * @brief Enable Flash memory features
80
+ *
81
+ * If the target MCU doesn't provide a feature (e.g. instruction and
82
+ * data caches on the STM32F1), the flag will be ignored. This allows
83
+ * using these flags unconditionally, with the desired effect taking
84
+ * place on targets that support them.
85
+ *
86
+ * @param feature_flags Bitwise OR of the following:
87
+ *                      FLASH_PREFETCH (turns on prefetcher),
88
+ *                      FLASH_ICACHE (turns on instruction cache),
89
+ *                      FLASH_DCACHE (turns on data cache).
90
+ */
91
+static inline void flash_enable_features(uint32 feature_flags) {
92
+    FLASH_BASE->ACR |= feature_flags;
93
+}
94
+
95
+/**
96
+ * @brief Deprecated. Use flash_enable_features(FLASH_PREFETCH) instead.
97
+ */
98
+static inline void flash_enable_prefetch(void) {
99
+    flash_enable_features(FLASH_PREFETCH);
100
+}
101
+
102
+#ifdef __cplusplus
103
+}
104
+#endif
105
+
106
+#endif

libmaple/fsmc.h → libmaple/include/libmaple/fsmc.h 파일 보기

@@ -25,7 +25,7 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file fsmc.h
28
+ * @file libmaple/include/libmaple/fsmc.h
29 29
  * @brief Flexible static memory controller support.
30 30
  */
31 31
 
@@ -33,20 +33,19 @@
33 33
  * See ../notes/fsmc.txt for more info
34 34
  */
35 35
 
36
-#include "libmaple_types.h"
37
-
38
-/**
39
- * @file fsmc.h
40
- */
41
-
42
-#ifndef _FSMC_H_
43
-#define _FSMC_H_
36
+#ifndef _LIBMAPLE_FSMC_H_
37
+#define _LIBMAPLE_FSMC_H_
44 38
 
45 39
 #ifdef __cplusplus
46 40
 extern "C"{
47 41
 #endif
48 42
 
49
-#ifdef STM32_HIGH_DENSITY
43
+#include <libmaple/libmaple_types.h>
44
+#include <libmaple/stm32.h>
45
+
46
+#if !STM32_HAVE_FSMC
47
+#error "FSMC is unavailable on your MCU"
48
+#endif
50 49
 
51 50
 /*
52 51
  * Register maps and devices
@@ -136,16 +135,16 @@ typedef struct fsmc_nor_psram_reg_map {
136 135
 #define FSMC_BCR_MUXEN_BIT              1
137 136
 #define FSMC_BCR_MBKEN_BIT              0
138 137
 
139
-#define FSMC_BCR_CBURSTRW               BIT(FSMC_BCR_CBURSTRW_BIT)
140
-#define FSMC_BCR_ASYNCWAIT              BIT(FSMC_BCR_ASYNCWAIT_BIT)
141
-#define FSMC_BCR_EXTMOD                 BIT(FSMC_BCR_EXTMOD_BIT)
142
-#define FSMC_BCR_WAITEN                 BIT(FSMC_BCR_WAITEN_BIT)
143
-#define FSMC_BCR_WREN                   BIT(FSMC_BCR_WREN_BIT)
144
-#define FSMC_BCR_WAITCFG                BIT(FSMC_BCR_WAITCFG_BIT)
145
-#define FSMC_BCR_WRAPMOD                BIT(FSMC_BCR_WRAPMOD_BIT)
146
-#define FSMC_BCR_WAITPOL                BIT(FSMC_BCR_WAITPOL_BIT)
147
-#define FSMC_BCR_BURSTEN                BIT(FSMC_BCR_BURSTEN_BIT)
148
-#define FSMC_BCR_FACCEN                 BIT(FSMC_BCR_FACCEN_BIT)
138
+#define FSMC_BCR_CBURSTRW               (1U << FSMC_BCR_CBURSTRW_BIT)
139
+#define FSMC_BCR_ASYNCWAIT              (1U << FSMC_BCR_ASYNCWAIT_BIT)
140
+#define FSMC_BCR_EXTMOD                 (1U << FSMC_BCR_EXTMOD_BIT)
141
+#define FSMC_BCR_WAITEN                 (1U << FSMC_BCR_WAITEN_BIT)
142
+#define FSMC_BCR_WREN                   (1U << FSMC_BCR_WREN_BIT)
143
+#define FSMC_BCR_WAITCFG                (1U << FSMC_BCR_WAITCFG_BIT)
144
+#define FSMC_BCR_WRAPMOD                (1U << FSMC_BCR_WRAPMOD_BIT)
145
+#define FSMC_BCR_WAITPOL                (1U << FSMC_BCR_WAITPOL_BIT)
146
+#define FSMC_BCR_BURSTEN                (1U << FSMC_BCR_BURSTEN_BIT)
147
+#define FSMC_BCR_FACCEN                 (1U << FSMC_BCR_FACCEN_BIT)
149 148
 #define FSMC_BCR_MWID                   (0x3 << 4)
150 149
 #define FSMC_BCR_MWID_8BITS             (0x0 << 4)
151 150
 #define FSMC_BCR_MWID_16BITS            (0x1 << 4)
@@ -153,8 +152,8 @@ typedef struct fsmc_nor_psram_reg_map {
153 152
 #define FSMC_BCR_MTYP_SRAM              (0x0 << 2)
154 153
 #define FSMC_BCR_MTYP_PSRAM             (0x1 << 2)
155 154
 #define FSMC_BCR_MTYP_NOR_FLASH         (0x2 << 2)
156
-#define FSMC_BCR_MUXEN                  BIT(FSMC_BCR_MUXEN_BIT)
157
-#define FSMC_BCR_MBKEN                  BIT(FSMC_BCR_MBKEN_BIT)
155
+#define FSMC_BCR_MUXEN                  (1U << FSMC_BCR_MUXEN_BIT)
156
+#define FSMC_BCR_MBKEN                  (1U << FSMC_BCR_MBKEN_BIT)
158 157
 
159 158
 /* SRAM/NOR-Flash chip-select timing registers */
160 159
 
@@ -199,15 +198,15 @@ typedef struct fsmc_nor_psram_reg_map {
199 198
 #define FSMC_PCR_ECCPS_8192B             (0x5 << 17)
200 199
 #define FSMC_PCR_TAR                     (0xF << 13)
201 200
 #define FSMC_PCR_TCLR                    (0xF << 9)
202
-#define FSMC_PCR_ECCEN                   BIT(FSMC_PCR_ECCEN_BIT)
201
+#define FSMC_PCR_ECCEN                   (1U << FSMC_PCR_ECCEN_BIT)
203 202
 #define FSMC_PCR_PWID                    (0x3 << 4)
204 203
 #define FSMC_PCR_PWID_8BITS              (0x0 << 4)
205 204
 #define FSMC_PCR_PWID_16BITS             (0x1 << 4)
206
-#define FSMC_PCR_PTYP                    BIT(FSMC_PCR_PTYP_BIT)
205
+#define FSMC_PCR_PTYP                    (1U << FSMC_PCR_PTYP_BIT)
207 206
 #define FSMC_PCR_PTYP_PC_CF_PCMCIA       (0x0 << FSMC_PCR_PTYP_BIT)
208 207
 #define FSMC_PCR_PTYP_NAND               (0x1 << FSMC_PCR_PTYP_BIT)
209
-#define FSMC_PCR_PBKEN                   BIT(FSMC_PCR_PBKEN_BIT)
210
-#define FSMC_PCR_PWAITEN                 BIT(FSMC_PCR_PWAITEN_BIT)
208
+#define FSMC_PCR_PBKEN                   (1U << FSMC_PCR_PBKEN_BIT)
209
+#define FSMC_PCR_PWAITEN                 (1U << FSMC_PCR_PWAITEN_BIT)
211 210
 
212 211
 /* FIFO status and interrupt registers */
213 212
 
@@ -219,13 +218,13 @@ typedef struct fsmc_nor_psram_reg_map {
219 218
 #define FSMC_SR_ILS_BIT                  1
220 219
 #define FSMC_SR_IRS_BIT                  0
221 220
 
222
-#define FSMC_SR_FEMPT                    BIT(FSMC_SR_FEMPT_BIT)
223
-#define FSMC_SR_IFEN                     BIT(FSMC_SR_IFEN_BIT)
224
-#define FSMC_SR_ILEN                     BIT(FSMC_SR_ILEN_BIT)
225
-#define FSMC_SR_IREN                     BIT(FSMC_SR_IREN_BIT)
226
-#define FSMC_SR_IFS                      BIT(FSMC_SR_IFS_BIT)
227
-#define FSMC_SR_ILS                      BIT(FSMC_SR_ILS_BIT)
228
-#define FSMC_SR_IRS                      BIT(FSMC_SR_IRS_BIT)
221
+#define FSMC_SR_FEMPT                    (1U << FSMC_SR_FEMPT_BIT)
222
+#define FSMC_SR_IFEN                     (1U << FSMC_SR_IFEN_BIT)
223
+#define FSMC_SR_ILEN                     (1U << FSMC_SR_ILEN_BIT)
224
+#define FSMC_SR_IREN                     (1U << FSMC_SR_IREN_BIT)
225
+#define FSMC_SR_IFS                      (1U << FSMC_SR_IFS_BIT)
226
+#define FSMC_SR_ILS                      (1U << FSMC_SR_ILS_BIT)
227
+#define FSMC_SR_IRS                      (1U << FSMC_SR_IRS_BIT)
229 228
 
230 229
 /* Common memory space timing registers */
231 230
 
@@ -252,35 +251,58 @@ typedef struct fsmc_nor_psram_reg_map {
252 251
  * Memory bank boundary addresses
253 252
  */
254 253
 
255
-/** Pointer to base address of FSMC memory bank 1 (split into 4
256
- * regions, each supporting 1 NOR Flash, SRAM, or PSRAM chip)  */
254
+/**
255
+ * @brief Void pointer to base address of FSMC memory bank 1 (NOR/PSRAM).
256
+ *
257
+ * This bank is split into 4 regions. Each region supports interfacing
258
+ * with 1 NOR Flash, SRAM, or PSRAM chip. The base addresses of these
259
+ * regions are FSMC_NOR_PSRAM_REGIONx, for x = 1, 2, 3, 4.
260
+ */
257 261
 #define FSMC_BANK1                      ((void*)0x60000000)
258 262
 
259
-/** Pointer to base address of FSMC memory bank 1, region 1 (for NOR/PSRAM) */
263
+/**
264
+ * @brief Void pointer to base address of FSMC memory bank 1, region 1
265
+ *        (NOR/PSRAM).
266
+ */
260 267
 #define FSMC_NOR_PSRAM_REGION1          FSMC_BANK1
261 268
 
262
-/** Pointer to base address of FSMC memory bank 1, region 2 (for NOR/PSRAM) */
269
+/**
270
+ * @brief Void pointer to base address of FSMC memory bank 1, region 2
271
+ *        (NOR/PSRAM).
272
+ */
263 273
 #define FSMC_NOR_PSRAM_REGION2          ((void*)0x64000000)
264 274
 
265
-/** Pointer to base address of FSMC memory bank 1, region 3 (for NOR/PSRAM) */
275
+/**
276
+ * @brief Void pointer to base address of FSMC memory bank 1, region 3
277
+ *        (NOR/PSRAM).
278
+ */
266 279
 #define FSMC_NOR_PSRAM_REGION3          ((void*)0x68000000)
267 280
 
268
-/** Pointer to base address of FSMC memory bank 1, region 4 (for NOR/PSRAM) */
281
+/**
282
+ * @brief Void pointer to base address of FSMC memory bank 1, region 4
283
+ *        (NOR/PSRAM).
284
+ */
269 285
 #define FSMC_NOR_PSRAM_REGION4          ((void*)0x6C000000)
270 286
 
271
-/** Pointer to base address of FSMC memory bank 2 (for NAND Flash) */
287
+/** Void pointer to base address of FSMC memory bank 2 (NAND Flash). */
272 288
 #define FSMC_BANK2                      ((void*)0x70000000)
273 289
 
274
-/** Pointer to base address of FSMC memory bank 3 (for NAND Flash) */
290
+/** Void pointer to base address of FSMC memory bank 3 (NAND Flash). */
275 291
 #define FSMC_BANK3                      ((void*)0x80000000)
276 292
 
277
-/** Pointer to base address of FSMC memory bank 4 (for PC card devices */
293
+/**
294
+ * @brief Void pointer to base address of FSMC memory bank 4 (PC card
295
+ *        devices).
296
+ */
278 297
 #define FSMC_BANK4                      ((void*)0x90000000)
279 298
 
280 299
 /*
281 300
  * SRAM/NOR Flash routines
282 301
  */
283 302
 
303
+/**
304
+ * @brief Configure FSMC GPIOs for use with SRAM.
305
+ */
284 306
 void fsmc_sram_init_gpios(void);
285 307
 
286 308
 /**
@@ -311,8 +333,6 @@ static inline void fsmc_nor_psram_set_addset(fsmc_nor_psram_reg_map *regs,
311 333
     regs->BTR |= addset & 0xF;
312 334
 }
313 335
 
314
-#endif /* STM32_HIGH_DENSITY */
315
-
316 336
 #ifdef __cplusplus
317 337
 } /* extern "C" */
318 338
 #endif

+ 121 - 0
libmaple/include/libmaple/gpio.h 파일 보기

@@ -0,0 +1,121 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Perry Hung.
5
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person
8
+ * obtaining a copy of this software and associated documentation
9
+ * files (the "Software"), to deal in the Software without
10
+ * restriction, including without limitation the rights to use, copy,
11
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ * of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+*****************************************************************************/
27
+
28
+/**
29
+ * @file libmaple/include/libmaple/gpio.h
30
+ * @brief General Purpose I/O (GPIO) interace.
31
+ */
32
+
33
+#ifndef _LIBMAPLE_GPIO_H_
34
+#define _LIBMAPLE_GPIO_H_
35
+
36
+#ifdef __cplusplus
37
+extern "C"{
38
+#endif
39
+
40
+/*
41
+ * Note: Series header must define:
42
+ * - enum gpio_pin_mode (TODO think harder about portability here)
43
+ */
44
+#include <series/gpio.h>
45
+#include <libmaple/libmaple_types.h>
46
+#include <libmaple/rcc.h>
47
+#include <libmaple/exti.h>
48
+
49
+/*
50
+ * Device type
51
+ */
52
+
53
+/** GPIO device type */
54
+typedef struct gpio_dev {
55
+    gpio_reg_map *regs;         /**< Register map */
56
+    rcc_clk_id    clk_id;       /**< RCC clock information */
57
+    /**
58
+     * @brief (Deprecated) External interrupt port.
59
+     * Instead of dev->exti_port, use gpio_exti_port(dev).
60
+     */
61
+    exti_cfg      exti_port;
62
+} gpio_dev;
63
+
64
+/*
65
+ * Portable routines
66
+ */
67
+
68
+void gpio_init(gpio_dev *dev);
69
+void gpio_init_all(void);
70
+/* TODO flags argument version? */
71
+void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode);
72
+
73
+/**
74
+ * @brief Get a GPIO port's corresponding EXTI port configuration.
75
+ * @param dev GPIO port whose exti_cfg to return.
76
+ */
77
+static inline exti_cfg gpio_exti_port(gpio_dev *dev) {
78
+    return (exti_cfg)(EXTI_PA + (dev->clk_id - RCC_GPIOA));
79
+}
80
+
81
+/**
82
+ * Set or reset a GPIO pin.
83
+ *
84
+ * Pin must have previously been configured to output mode.
85
+ *
86
+ * @param dev GPIO device whose pin to set.
87
+ * @param pin Pin on to set or reset
88
+ * @param val If true, set the pin.  If false, reset the pin.
89
+ */
90
+static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) {
91
+    val = !val;          /* "set" bits are lower than "reset" bits  */
92
+    dev->regs->BSRR = (1U << pin) << (16 * val);
93
+}
94
+
95
+/**
96
+ * Determine whether or not a GPIO pin is set.
97
+ *
98
+ * Pin must have previously been configured to input mode.
99
+ *
100
+ * @param dev GPIO device whose pin to test.
101
+ * @param pin Pin on dev to test.
102
+ * @return True if the pin is set, false otherwise.
103
+ */
104
+static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) {
105
+    return dev->regs->IDR & (1U << pin);
106
+}
107
+
108
+/**
109
+ * Toggle a pin configured as output push-pull.
110
+ * @param dev GPIO device.
111
+ * @param pin Pin on dev to toggle.
112
+ */
113
+static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) {
114
+    dev->regs->ODR = dev->regs->ODR ^ (1U << pin);
115
+}
116
+
117
+#ifdef __cplusplus
118
+}
119
+#endif
120
+
121
+#endif

libmaple/i2c.h → libmaple/include/libmaple/i2c.h 파일 보기

@@ -2,6 +2,7 @@
2 2
  * The MIT License
3 3
  *
4 4
  * Copyright (c) 2010 Perry Hung.
5
+ * Copyright (c) 2012 LeafLabs, LLC.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
7 8
  * obtaining a copy of this software and associated documentation
@@ -25,17 +26,51 @@
25 26
  *****************************************************************************/
26 27
 
27 28
 /**
28
- * @file i2c.h
29
+ * @file libmaple/include/libmaple/i2c.h
29 30
  * @brief Inter-Integrated Circuit (I2C) peripheral support
31
+ *
32
+ * Currently master-only. Usage notes:
33
+ *
34
+ * - Enable an I2C device with i2c_master_enable().
35
+ * - Initialize an array of struct i2c_msg to suit the bus
36
+ *   transactions (reads/writes) you wish to perform.
37
+ * - Call i2c_master_xfer() to do the work.
30 38
  */
31 39
 
32
-#include "libmaple_types.h"
33
-#include "rcc.h"
34
-#include "nvic.h"
35
-#include "gpio.h"
40
+#ifndef _LIBMAPLE_I2C_H_
41
+#define _LIBMAPLE_I2C_H_
36 42
 
37
-#ifndef _I2C_H_
38
-#define _I2C_H_
43
+#ifdef __cplusplus
44
+extern "C" {
45
+#endif
46
+
47
+/*
48
+ * Series header must provide:
49
+ *
50
+ * - uint32 _i2c_bus_clk(i2c_dev*): Clock frequency of dev's bus, in
51
+ *   MHz. (This is for internal use only).
52
+ *
53
+ * - (optional) _I2C_HAVE_IRQ_FIXUP: Leave undefined, or define to 1.
54
+ *   This is for internal use only. It's a hack to work around a
55
+ *   silicon bug related to I2C IRQ pre-emption on some targets. If 1,
56
+ *   the series header must also declare and implement a routine with
57
+ *   this signature (it may also be provided as a macro):
58
+ *
59
+ *       void _i2c_irq_priority_fixup(i2c_dev*)
60
+ *
61
+ *   This will be called by i2c_enable_irq() before actually enabling
62
+ *   I2C interrupts.
63
+ *
64
+ * - Reg. map base pointers, device pointer declarations.
65
+ */
66
+
67
+#include <series/i2c.h>
68
+#include <libmaple/i2c_common.h>
69
+
70
+#include <libmaple/libmaple_types.h>
71
+#include <libmaple/rcc.h>
72
+#include <libmaple/nvic.h>
73
+#include <libmaple/gpio.h>
39 74
 
40 75
 /** I2C register map type */
41 76
 typedef struct i2c_reg_map {
@@ -50,136 +85,118 @@ typedef struct i2c_reg_map {
50 85
     __io uint32 TRISE;          /**< TRISE (rise time) register */
51 86
 } i2c_reg_map;
52 87
 
53
-/** I2C device states */
54
-typedef enum i2c_state {
55
-    I2C_STATE_DISABLED          = 0, /**< Disabled */
56
-    I2C_STATE_IDLE              = 1, /**< Idle */
57
-    I2C_STATE_XFER_DONE         = 2, /**< Done with transfer */
58
-    I2C_STATE_BUSY              = 3, /**< Busy */
59
-    I2C_STATE_ERROR             = -1 /**< Error occurred */
60
-} i2c_state;
61
-
62 88
 /**
63 89
  * @brief I2C message type
64 90
  */
65 91
 typedef struct i2c_msg {
66 92
     uint16 addr;                /**< Address */
93
+
67 94
 #define I2C_MSG_READ            0x1
68 95
 #define I2C_MSG_10BIT_ADDR      0x2
69
-    uint16 flags;               /**< Bitwise OR of I2C_MSG_READ and
70
-                                     I2C_MSG_10BIT_ADDR */
96
+    /**
97
+     * Bitwise OR of:
98
+     * - I2C_MSG_READ (write is default)
99
+     * - I2C_MSG_10BIT_ADDR (7-bit is default) */
100
+    uint16 flags;
101
+
71 102
     uint16 length;              /**< Message length */
72 103
     uint16 xferred;             /**< Messages transferred */
73 104
     uint8 *data;                /**< Data */
74 105
 } i2c_msg;
75 106
 
76
-/**
77
- * @brief I2C device type.
78
- */
79
-typedef struct i2c_dev {
80
-    i2c_reg_map *regs;          /**< Register map */
81
-    gpio_dev *gpio_port;        /**< SDA, SCL pins' GPIO port */
82
-    uint8 sda_pin;              /**< SDA bit on gpio_port */
83
-    uint8 scl_pin;              /**< SCL bit on gpio_port */
84
-    rcc_clk_id clk_id;          /**< RCC clock information */
85
-    nvic_irq_num ev_nvic_line;  /**< Event IRQ number */
86
-    nvic_irq_num er_nvic_line;  /**< Error IRQ number */
87
-    volatile i2c_state state;   /**< Device state */
88
-    uint16 msgs_left;           /**< Messages left */
89
-    i2c_msg *msg;               /**< Messages */
90
-    volatile uint32 timestamp;  /**< For internal use */
91
-    uint32 error_flags;         /**< Error flags, set on I2C error condition */
92
-} i2c_dev;
93
-
94
-/*
95
- * Devices
96
- */
97
-
98
-extern i2c_dev* const I2C1;
99
-extern i2c_dev* const I2C2;
100
-
101
-/*
102
- * Register map base pointers
103
- */
104
-
105
-/** I2C1 register map base pointer */
106
-#define I2C1_BASE               ((struct i2c_reg_map*)0x40005400)
107
-/** I2C2 register map base pointer */
108
-#define I2C2_BASE               ((struct i2c_reg_map*)0x40005800)
109
-
110 107
 /*
111 108
  * Register bit definitions
112 109
  */
113 110
 
114 111
 /* Control register 1 */
115 112
 
116
-#define I2C_CR1_SWRST           BIT(15)       // Software reset
117
-#define I2C_CR1_ALERT           BIT(13)       // SMBus alert
118
-#define I2C_CR1_PEC             BIT(12)       // Packet error checking
119
-#define I2C_CR1_POS             BIT(11)       // Acknowledge/PEC position
120
-#define I2C_CR1_ACK             BIT(10)       // Acknowledge enable
121
-#define I2C_CR1_START           BIT(8)        // Start generation
122
-#define I2C_CR1_STOP            BIT(9)        // Stop generation
123
-#define I2C_CR1_PE              BIT(0)        // Peripheral Enable
113
+#define I2C_CR1_SWRST           (1U << 15)    // Software reset
114
+#define I2C_CR1_ALERT           (1U << 13)    // SMBus alert
115
+#define I2C_CR1_PEC             (1U << 12)    // Packet error checking
116
+#define I2C_CR1_POS             (1U << 11)    // Acknowledge/PEC position
117
+#define I2C_CR1_ACK             (1U << 10)    // Acknowledge enable
118
+#define I2C_CR1_STOP            (1U << 9)     // Stop generation
119
+#define I2C_CR1_START           (1U << 8)     // Start generation
120
+#define I2C_CR1_NOSTRETCH       (1U << 7)     // Clock stretching disable
121
+#define I2C_CR1_ENGC            (1U << 6)     // General call enable
122
+#define I2C_CR1_ENPEC           (1U << 5)     // PEC enable
123
+#define I2C_CR1_ENARP           (1U << 4)     // ARP enable
124
+#define I2C_CR1_SMBTYPE         (1U << 3)     // SMBus type
125
+#define I2C_CR1_SMBTYPE_DEVICE  (0U << 3)     //     SMBus type: device
126
+#define I2C_CR1_SMBTYPE_HOST    (1U << 3)     //     SMBus type: host
127
+#define I2C_CR1_SMBUS           (1U << 1)     // SMBus mode
128
+#define I2C_CR1_SMBUS_I2C       (0U << 1)     //     SMBus mode: I2C
129
+#define I2C_CR1_SMBUS_SMBUS     (1U << 1)     //     SMBus mode: SMBus
130
+#define I2C_CR1_PE              (1U << 0)     // Peripheral Enable
124 131
 
125 132
 /* Control register 2 */
126 133
 
127
-#define I2C_CR2_LAST            BIT(12)       // DMA last transfer
128
-#define I2C_CR2_DMAEN           BIT(11)       // DMA requests enable
129
-#define I2C_CR2_ITBUFEN         BIT(10)       // Buffer interrupt enable
130
-#define I2C_CR2_ITEVTEN         BIT(9)        // Event interupt enable
131
-#define I2C_CR2_ITERREN         BIT(8)        // Error interupt enable
132
-#define I2C_CR2_FREQ            0xFFF         // Peripheral input frequency
134
+#define I2C_CR2_LAST            (1U << 12)    // DMA last transfer
135
+#define I2C_CR2_DMAEN           (1U << 11)    // DMA requests enable
136
+#define I2C_CR2_ITBUFEN         (1U << 10)    // Buffer interrupt enable
137
+#define I2C_CR2_ITEVTEN         (1U << 9)     // Event interupt enable
138
+#define I2C_CR2_ITERREN         (1U << 8)     // Error interupt enable
139
+#define I2C_CR2_FREQ            0x3F          // Peripheral input frequency
133 140
 
134
-/* Clock control register */
141
+/* Own address register 1 */
135 142
 
136
-#define I2C_CCR_FS              BIT(15)       // Fast mode selection
137
-#define I2C_CCR_DUTY            BIT(14)       // 16/9 duty ratio
138
-#define I2C_CCR_CCR             0xFFF         // Clock control bits
143
+#define I2C_OAR1_ADDMODE        (1U << 15)    // Addressing mode
144
+#define I2C_OAR1_ADDMODE_7_BIT  (0U << 15)    //     Addressing mode: 7-bit
145
+#define I2C_OAR1_ADDMODE_10_BIT (1U << 15)    //     Addressing mode: 10-bit
146
+#define I2C_OAR1_ADD            0x3FF         // Interface address
147
+
148
+/* Own address register 2 */
149
+
150
+#define I2C_OAR2_ADD2           0xFE          // Interface address
151
+#define I2C_OAR2_ENDUAL         1U            // Dual addressing mode enable
139 152
 
140 153
 /* Status register 1 */
141 154
 
142
-#define I2C_SR1_SB              BIT(0)        // Start bit
143
-#define I2C_SR1_ADDR            BIT(1)        // Address sent/matched
144
-#define I2C_SR1_BTF             BIT(2)        // Byte transfer finished
145
-#define I2C_SR1_ADD10           BIT(3)        // 10-bit header sent
146
-#define I2C_SR1_STOPF           BIT(4)        // Stop detection
147
-#define I2C_SR1_RXNE            BIT(6)        // Data register not empty
148
-#define I2C_SR1_TXE             BIT(7)        // Data register empty
149
-#define I2C_SR1_BERR            BIT(8)        // Bus error
150
-#define I2C_SR1_ARLO            BIT(9)        // Arbitration lost
151
-#define I2C_SR1_AF              BIT(10)       // Acknowledge failure
152
-#define I2C_SR1_OVR             BIT(11)       // Overrun/underrun
153
-#define I2C_SR1_PECERR          BIT(12)       // PEC Error in reception
154
-#define I2C_SR1_TIMEOUT         BIT(14)       // Timeout or Tlow error
155
-#define I2C_SR1_SMBALERT        BIT(15)       // SMBus alert
155
+#define I2C_SR1_SMBALERT        (1U << 15)    // SMBus alert
156
+#define I2C_SR1_TIMEOUT         (1U << 14)    // Timeout or Tlow error
157
+#define I2C_SR1_PECERR          (1U << 12)    // PEC Error in reception
158
+#define I2C_SR1_OVR             (1U << 11)    // Overrun/underrun
159
+#define I2C_SR1_AF              (1U << 10)    // Acknowledge failure
160
+#define I2C_SR1_ARLO            (1U << 9)     // Arbitration lost
161
+#define I2C_SR1_BERR            (1U << 8)     // Bus error
162
+#define I2C_SR1_TXE             (1U << 7)     // Data register empty
163
+#define I2C_SR1_RXNE            (1U << 6)     // Data register not empty
164
+#define I2C_SR1_STOPF           (1U << 4)     // Stop detection
165
+#define I2C_SR1_ADD10           (1U << 3)     // 10-bit header sent
166
+#define I2C_SR1_BTF             (1U << 2)     // Byte transfer finished
167
+#define I2C_SR1_ADDR            (1U << 1)     // Address sent/matched
168
+#define I2C_SR1_SB              (1U << 0)     // Start bit
156 169
 
157 170
 /* Status register 2 */
158 171
 
159
-#define I2C_SR2_MSL             BIT(0)        // Master/slave
160
-#define I2C_SR2_BUSY            BIT(1)        // Bus busy
161
-#define I2C_SR2_TRA             BIT(2)        // Transmitter/receiver
162
-#define I2C_SR2_GENCALL         BIT(4)        // General call address
163
-#define I2C_SR2_SMBDEFAULT      BIT(5)        // SMBus device default address
164
-#define I2C_SR2_SMBHOST         BIT(6)        // SMBus host header
165
-#define I2C_SR2_DUALF           BIT(7)        // Dual flag
166 172
 #define I2C_SR2_PEC             0xFF00        // Packet error checking register
173
+#define I2C_SR2_DUALF           (1U << 7)     // Dual flag
174
+#define I2C_SR2_SMBHOST         (1U << 6)     // SMBus host header
175
+#define I2C_SR2_SMBDEFAULT      (1U << 5)     // SMBus device default address
176
+#define I2C_SR2_GENCALL         (1U << 4)     // General call address
177
+#define I2C_SR2_TRA             (1U << 2)     // Transmitter/receiver
178
+#define I2C_SR2_BUSY            (1U << 1)     // Bus busy
179
+#define I2C_SR2_MSL             (1U << 0)     // Master/slave
180
+
181
+/* Clock control register */
182
+
183
+#define I2C_CCR_FS              (1U << 15)    // Fast mode selection
184
+#define I2C_CCR_DUTY            (1U << 14)    // Fast mode duty cycle
185
+#define I2C_CCR_DUTY_2_1        (0U << 14)    //     Fast mode duty: 2/1
186
+#define I2C_CCR_DUTY_16_9       (1U << 14)    //     Fast mode duty: 16/9
187
+#define I2C_CCR_CCR             0xFFF         // Clock control bits
167 188
 
168 189
 /*
169 190
  * Convenience routines
170 191
  */
171 192
 
172
-#ifdef __cplusplus
173
-extern "C" {
174
-#endif
175
-
176
-void i2c_init(i2c_dev *dev);
193
+/* Main I2C API */
177 194
 
178 195
 /* I2C enable options */
179
-#define I2C_FAST_MODE           BIT(0)      // 400 khz
180
-#define I2C_DUTY_16_9           BIT(1)      // 16/9 duty ratio
181
-#define I2C_REMAP               BIT(2)      // Use alternate pin mapping
182
-#define I2C_BUS_RESET           BIT(3)      // Perform a bus reset
196
+#define I2C_FAST_MODE           0x1           // 400 khz
197
+#define I2C_DUTY_16_9           0x2           // 16/9 duty ratio
198
+/* Flag 0x4 is reserved; DO NOT USE. */
199
+#define I2C_BUS_RESET           0x8           // Perform a bus reset
183 200
 void i2c_master_enable(i2c_dev *dev, uint32 flags);
184 201
 
185 202
 #define I2C_ERROR_PROTOCOL      (-1)
@@ -201,67 +218,7 @@ static inline void i2c_disable(i2c_dev *dev) {
201 218
     dev->state = I2C_STATE_DISABLED;
202 219
 }
203 220
 
204
-/**
205
- * @brief Turn on an I2C peripheral
206
- * @param dev Device to enable
207
- */
208
-static inline void i2c_peripheral_enable(i2c_dev *dev) {
209
-    dev->regs->CR1 |= I2C_CR1_PE;
210
-}
211
-
212
-/**
213
- * @brief Turn off an I2C peripheral
214
- * @param dev Device to turn off
215
- */
216
-static inline void i2c_peripheral_disable(i2c_dev *dev) {
217
-    dev->regs->CR1 &= ~I2C_CR1_PE;
218
-}
219
-
220
-/**
221
- * @brief Fill transmit register
222
- * @param dev I2C device
223
- * @param byte Byte to write
224
- */
225
-static inline void i2c_write(i2c_dev *dev, uint8 byte) {
226
-    dev->regs->DR = byte;
227
-}
228
-
229
-/**
230
- * @brief Set input clock frequency, in MHz
231
- * @param dev I2C device
232
- * @param freq Frequency in megahertz (2-36)
233
- */
234
-static inline void i2c_set_input_clk(i2c_dev *dev, uint32 freq) {
235
-    uint32 cr2 = dev->regs->CR2;
236
-    cr2 &= ~I2C_CR2_FREQ;
237
-    cr2 |= freq;
238
-    dev->regs->CR2 = freq;
239
-}
240
-
241
-/**
242
- * @brief Set I2C clock control register. See RM008
243
- * @param dev I2C device
244
- * @param val Value to use for clock control register (in
245
- *            Fast/Standard mode)
246
- */
247
-static inline void i2c_set_clk_control(i2c_dev *dev, uint32 val) {
248
-    uint32 ccr = dev->regs->CCR;
249
-    ccr &= ~I2C_CCR_CCR;
250
-    ccr |= val;
251
-    dev->regs->CCR = ccr;
252
-}
253
-
254
-
255
-/**
256
- * @brief Set SCL rise time
257
- * @param dev I2C device
258
- * @param trise Maximum rise time in fast/standard mode (see RM0008
259
- *              for relevant formula).
260
- */
261
-static inline void i2c_set_trise(i2c_dev *dev, uint32 trise) {
262
-    dev->regs->TRISE = trise;
263
-}
264
-
221
+/* Start/stop conditions */
265 222
 
266 223
 /**
267 224
  * @brief Generate a start condition on the bus.
@@ -297,6 +254,17 @@ static inline void i2c_stop_condition(i2c_dev *dev) {
297 254
 
298 255
 }
299 256
 
257
+/* IRQ enable/disable */
258
+
259
+#ifndef _I2C_HAVE_IRQ_FIXUP
260
+/* The series header provides this if _I2C_HAVE_IRQ_FIXUP is defined,
261
+ * but we need it either way. */
262
+#define _i2c_irq_priority_fixup(dev) ((void)0)
263
+#endif
264
+
265
+#define I2C_IRQ_ERROR              I2C_CR2_ITERREN
266
+#define I2C_IRQ_EVENT              I2C_CR2_ITEVTEN
267
+#define I2C_IRQ_BUFFER             I2C_CR2_ITBUFEN
300 268
 /**
301 269
  * @brief Enable one or more I2C interrupts
302 270
  * @param dev I2C device
@@ -305,10 +273,8 @@ static inline void i2c_stop_condition(i2c_dev *dev) {
305 273
  *             I2C_IRQ_EVENT (event interrupt), and
306 274
  *             I2C_IRQ_BUFFER (buffer interrupt).
307 275
  */
308
-#define I2C_IRQ_ERROR              I2C_CR2_ITERREN
309
-#define I2C_IRQ_EVENT              I2C_CR2_ITEVTEN
310
-#define I2C_IRQ_BUFFER             I2C_CR2_ITBUFEN
311 276
 static inline void i2c_enable_irq(i2c_dev *dev, uint32 irqs) {
277
+    _i2c_irq_priority_fixup(dev);
312 278
     dev->regs->CR2 |= irqs;
313 279
 }
314 280
 
@@ -324,6 +290,7 @@ static inline void i2c_disable_irq(i2c_dev *dev, uint32 irqs) {
324 290
     dev->regs->CR2 &= ~irqs;
325 291
 }
326 292
 
293
+/* ACK/NACK */
327 294
 
328 295
 /**
329 296
  * @brief Enable I2C acknowledgment
@@ -341,6 +308,104 @@ static inline void i2c_disable_ack(i2c_dev *dev) {
341 308
     dev->regs->CR1 &= ~I2C_CR1_ACK;
342 309
 }
343 310
 
311
+/* GPIO control */
312
+
313
+/**
314
+ * @brief Configure device GPIOs.
315
+ *
316
+ * Configure GPIO bits dev->sda_pin and dev->scl_pin on GPIO device
317
+ * dev->gpio_port for use with I2C device dev.
318
+ *
319
+ * @param dev I2C Device
320
+ * @see i2c_release_gpios()
321
+ */
322
+extern void i2c_config_gpios(const i2c_dev *dev);
323
+
324
+/**
325
+ * @brief Release GPIOs controlling an I2C bus
326
+ *
327
+ * Releases the I2C bus controlled by dev as master, and disconnects
328
+ * GPIO bits dev->sda_pin and dev->scl_pin on GPIO device
329
+ * dev->gpio_port from I2C device dev.
330
+ *
331
+ * @param dev I2C device
332
+ * @see i2c_config_gpios()
333
+ */
334
+extern void i2c_master_release_bus(const i2c_dev *dev);
335
+
336
+/* Miscellaneous low-level routines */
337
+
338
+void i2c_init(i2c_dev *dev);
339
+
340
+/**
341
+ * @brief Turn on an I2C peripheral
342
+ * @param dev Device to enable
343
+ */
344
+static inline void i2c_peripheral_enable(i2c_dev *dev) {
345
+    dev->regs->CR1 |= I2C_CR1_PE;
346
+}
347
+
348
+/**
349
+ * @brief Turn off an I2C peripheral
350
+ * @param dev Device to turn off
351
+ */
352
+static inline void i2c_peripheral_disable(i2c_dev *dev) {
353
+    dev->regs->CR1 &= ~I2C_CR1_PE;
354
+}
355
+
356
+/**
357
+ * @brief Fill transmit register
358
+ * @param dev I2C device
359
+ * @param byte Byte to write
360
+ */
361
+static inline void i2c_write(i2c_dev *dev, uint8 byte) {
362
+    dev->regs->DR = byte;
363
+}
364
+
365
+/**
366
+ * @brief Set input clock frequency, in MHz
367
+ * @param dev I2C device
368
+ * @param freq Frequency, in MHz. This must be at least 2, and at most
369
+ *             the APB frequency of dev's bus. (For example, if
370
+ *             rcc_dev_clk(dev) == RCC_APB1, freq must be at most
371
+ *             PCLK1, in MHz). There is an additional limit of 46 MHz.
372
+ */
373
+static inline void i2c_set_input_clk(i2c_dev *dev, uint32 freq) {
374
+#define I2C_MAX_FREQ_MHZ 46
375
+    ASSERT(2 <= freq && freq <= _i2c_bus_clk(dev) && freq <= I2C_MAX_FREQ_MHZ);
376
+    uint32 cr2 = dev->regs->CR2;
377
+    cr2 &= ~I2C_CR2_FREQ;
378
+    cr2 |= freq;
379
+    dev->regs->CR2 = freq;
380
+#undef I2C_MAX_FREQ_MHZ
381
+}
382
+
383
+/**
384
+ * @brief Set I2C clock control register.
385
+ *
386
+ * See the chip reference manual for the details.
387
+ *
388
+ * @param dev I2C device
389
+ * @param val Value to use for clock control register (in
390
+ *            Fast/Standard mode)
391
+ */
392
+static inline void i2c_set_clk_control(i2c_dev *dev, uint32 val) {
393
+    uint32 ccr = dev->regs->CCR;
394
+    ccr &= ~I2C_CCR_CCR;
395
+    ccr |= val;
396
+    dev->regs->CCR = ccr;
397
+}
398
+
399
+/**
400
+ * @brief Set SCL rise time
401
+ * @param dev I2C device
402
+ * @param trise Maximum rise time in fast/standard mode (see chip
403
+ *              reference manual for the relevant formulas).
404
+ */
405
+static inline void i2c_set_trise(i2c_dev *dev, uint32 trise) {
406
+    dev->regs->TRISE = trise;
407
+}
408
+
344 409
 #ifdef __cplusplus
345 410
 }
346 411
 #endif

+ 95 - 0
libmaple/include/libmaple/i2c_common.h 파일 보기

@@ -0,0 +1,95 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Perry Hung (from <libmaple/i2c.h>).
5
+ * Copyright (c) 2012 LeafLabs, LLC.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person
8
+ * obtaining a copy of this software and associated documentation
9
+ * files (the "Software"), to deal in the Software without
10
+ * restriction, including without limitation the rights to use, copy,
11
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ * of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *****************************************************************************/
27
+
28
+/**
29
+ * @file libmaple/include/libmaple/i2c_common.h
30
+ * @author Marti Bolivar <mbolivar@leaflabs.com>
31
+ * @brief This file is an implementation detail
32
+ *
33
+ * WARNING: CONTENTS UNSTABLE
34
+ *
35
+ * The existence of this file is an implementation detail.  Its
36
+ * contents are not stable, so never include it directly.  If you need
37
+ * something from here, #include <libmaple/i2c.h> instead.
38
+ */
39
+
40
+#ifndef _LIBMAPLE_I2C_COMMON_H_
41
+#define _LIBMAPLE_I2C_COMMON_H_
42
+
43
+#include <libmaple/libmaple_types.h>
44
+#include <libmaple/nvic.h>
45
+#include <libmaple/rcc.h>
46
+
47
+struct gpio_dev;
48
+struct i2c_reg_map;
49
+struct i2c_msg;
50
+
51
+/** I2C device states */
52
+typedef enum i2c_state {
53
+    I2C_STATE_DISABLED          = 0, /**< Disabled */
54
+    I2C_STATE_IDLE              = 1, /**< Idle */
55
+    I2C_STATE_XFER_DONE         = 2, /**< Done with transfer */
56
+    I2C_STATE_BUSY              = 3, /**< Busy */
57
+    I2C_STATE_ERROR             = -1 /**< Error occurred */
58
+} i2c_state;
59
+
60
+/**
61
+ * @brief I2C device type.
62
+ */
63
+typedef struct i2c_dev {
64
+    struct i2c_reg_map *regs;   /**< Register map */
65
+    struct i2c_msg *msg;        /**< Messages */
66
+    uint32 error_flags;         /**< Error flags, set on I2C error condition */
67
+    volatile uint32 timestamp;  /**< For internal use */
68
+
69
+    /**
70
+     * @brief Deprecated. Use .scl_port or .sda_port instead.
71
+     * If non-null, this will be used as SDA, SCL pins' GPIO port. If
72
+     * null, then .sda_port will be used for SDA, and .sda_port for
73
+     * SDA. */
74
+    struct gpio_dev *gpio_port;
75
+
76
+    /**
77
+     * @brief SDA GPIO device (but see .gpio_port).
78
+     */
79
+    struct gpio_dev *sda_port;
80
+
81
+    /**
82
+     * @brief SCL GPIO device (but see .gpio_port).
83
+     */
84
+    struct gpio_dev *scl_port;
85
+
86
+    uint16 msgs_left;           /**< Messages left */
87
+    uint8 sda_pin;              /**< SDA bit on gpio_port */
88
+    uint8 scl_pin;              /**< SCL bit on gpio_port */
89
+    rcc_clk_id clk_id;          /**< RCC clock information */
90
+    nvic_irq_num ev_nvic_line;  /**< Event IRQ number */
91
+    nvic_irq_num er_nvic_line;  /**< Error IRQ number */
92
+    volatile i2c_state state;   /**< Device state */
93
+} i2c_dev;
94
+
95
+#endif

libmaple/iwdg.h → libmaple/include/libmaple/iwdg.h 파일 보기

@@ -25,7 +25,7 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file iwdg.h
28
+ * @file libmaple/include/libmaple/iwdg.h
29 29
  * @author Michael Hope, Marti Bolivar <mbolivar@leaflabs.com>
30 30
  * @brief Independent watchdog support.
31 31
  *
@@ -38,16 +38,15 @@
38 38
  * Once started, the independent watchdog cannot be turned off.
39 39
  */
40 40
 
41
-#ifndef _IWDG_H_
42
-#define _IWDG_H_
43
-
44
-#include "libmaple_types.h"
45
-#include "util.h"
41
+#ifndef _LIBMAPLE_IWDG_H_
42
+#define _LIBMAPLE_IWDG_H_
46 43
 
47 44
 #ifdef __cplusplus
48 45
 extern "C"{
49 46
 #endif
50 47
 
48
+#include <libmaple/libmaple_types.h>
49
+
51 50
 /*
52 51
  * Register map
53 52
  */
@@ -88,8 +87,8 @@ typedef struct iwdg_reg_map {
88 87
 #define IWDG_SR_RVU_BIT                 1
89 88
 #define IWDG_SR_PVU_BIT                 0
90 89
 
91
-#define IWDG_SR_RVU                     BIT(IWDG_SR_RVU_BIT)
92
-#define IWDG_SR_PVU                     BIT(IWDG_SR_PVU_BIT)
90
+#define IWDG_SR_RVU                     (1U << IWDG_SR_RVU_BIT)
91
+#define IWDG_SR_PVU                     (1U << IWDG_SR_PVU_BIT)
93 92
 
94 93
 /**
95 94
  * @brief Independent watchdog prescalers.

libmaple/libmaple.h → libmaple/include/libmaple/libmaple.h 파일 보기

@@ -25,17 +25,21 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- *  @file libmaple.h
28
+ *  @file libmaple/include/libmaple/libmaple.h
29 29
  *  @brief General include file for libmaple
30 30
  */
31 31
 
32
-#ifndef _LIBMAPLE_H_
33
-#define _LIBMAPLE_H_
32
+#ifndef _LIBMAPLE_LIBMAPLE_H_
33
+#define _LIBMAPLE_LIBMAPLE_H_
34 34
 
35
-#include "libmaple_types.h"
36
-#include "stm32.h"
37
-#include "util.h"
38
-#include "delay.h"
35
+#ifdef __cplusplus
36
+extern "C" {
37
+#endif
38
+
39
+#include <libmaple/libmaple_types.h>
40
+#include <libmaple/stm32.h>
41
+#include <libmaple/util.h>
42
+#include <libmaple/delay.h>
39 43
 
40 44
 /*
41 45
  * Where to put usercode, based on space reserved for bootloader.
@@ -46,5 +50,8 @@
46 50
 #define USER_ADDR_RAM 0x20000C00
47 51
 #define STACK_TOP     0x20000800
48 52
 
53
+#ifdef __cplusplus
54
+}
49 55
 #endif
50 56
 
57
+#endif

libmaple/libmaple_types.h → libmaple/include/libmaple/libmaple_types.h 파일 보기

@@ -25,13 +25,17 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- *  @file libmaple_types.h
28
+ *  @file libmaple/include/libmaple/libmaple_types.h
29 29
  *
30
- *  @brief libmaple types
30
+ *  @brief libmaple's types, and operations on types.
31 31
  */
32 32
 
33
-#ifndef _LIBMAPLE_TYPES_H_
34
-#define _LIBMAPLE_TYPES_H_
33
+#ifndef _LIBMAPLE_LIBMAPLE_TYPES_H_
34
+#define _LIBMAPLE_LIBMAPLE_TYPES_H_
35
+
36
+#ifdef __cplusplus
37
+extern "C" {
38
+#endif
35 39
 
36 40
 typedef unsigned char uint8;
37 41
 typedef unsigned short uint16;
@@ -48,10 +52,21 @@ typedef void (*voidFuncPtr)(void);
48 52
 #define __io volatile
49 53
 #define __attr_flash __attribute__((section (".USER_FLASH")))
50 54
 #define __packed __attribute__((__packed__))
55
+#define __deprecated __attribute__((__deprecated__))
56
+#define __weak __attribute__((weak))
57
+#define __always_inline inline __attribute__((always_inline))
58
+#define __unused __attribute__((unused))
51 59
 
52 60
 #ifndef NULL
53 61
 #define NULL 0
54 62
 #endif
55 63
 
64
+#ifndef offsetof
65
+#define offsetof(type, member) __builtin_offsetof(type, member)
56 66
 #endif
57 67
 
68
+#ifdef __cplusplus
69
+}
70
+#endif
71
+
72
+#endif

+ 155 - 0
libmaple/include/libmaple/nvic.h 파일 보기

@@ -0,0 +1,155 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Perry Hung.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @file libmaple/include/libmaple/nvic.h
29
+ * @brief Nested vectored interrupt controller support.
30
+ *
31
+ * Basic usage:
32
+ *
33
+ * @code
34
+ *   // Initialise the interrupt controller and point to the vector
35
+ *   // table at the start of flash.
36
+ *   nvic_init(0x08000000, 0);
37
+ *   // Bind in a timer interrupt handler
38
+ *   timer_attach_interrupt(TIMER_CC1_INTERRUPT, handler);
39
+ *   // Optionally set the priority
40
+ *   nvic_irq_set_priority(NVIC_TIMER1_CC, 5);
41
+ *   // All done, enable all interrupts
42
+ *   nvic_globalirq_enable();
43
+ * @endcode
44
+ */
45
+
46
+#ifndef _LIBMAPLE_NVIC_H_
47
+#define _LIBMAPLE_NVIC_H_
48
+
49
+#ifdef __cplusplus
50
+extern "C"{
51
+#endif
52
+
53
+#include <libmaple/libmaple_types.h>
54
+#include <libmaple/util.h>
55
+
56
+/** NVIC register map type. */
57
+typedef struct nvic_reg_map {
58
+    __io uint32 ISER[8];      /**< Interrupt Set Enable Registers */
59
+    /** Reserved */
60
+    uint32 RESERVED0[24];
61
+
62
+    __io uint32 ICER[8];      /**< Interrupt Clear Enable Registers */
63
+    /** Reserved */
64
+    uint32 RESERVED1[24];
65
+
66
+    __io uint32 ISPR[8];      /**< Interrupt Set Pending Registers */
67
+    /** Reserved */
68
+    uint32 RESERVED2[24];
69
+
70
+    __io uint32 ICPR[8];      /**< Interrupt Clear Pending Registers */
71
+    /** Reserved */
72
+    uint32 RESERVED3[24];
73
+
74
+    __io uint32 IABR[8];      /**< Interrupt Active bit Registers */
75
+    /** Reserved */
76
+    uint32 RESERVED4[56];
77
+
78
+    __io uint8  IP[240];      /**< Interrupt Priority Registers */
79
+    /** Reserved */
80
+    uint32 RESERVED5[644];
81
+
82
+    __io uint32 STIR;         /**< Software Trigger Interrupt Registers */
83
+} nvic_reg_map;
84
+
85
+/** NVIC register map base pointer. */
86
+#define NVIC_BASE                       ((struct nvic_reg_map*)0xE000E100)
87
+
88
+/*
89
+ * Note: The series header must define enum nvic_irq_num, which gives
90
+ * descriptive names to the interrupts and exceptions from NMI (-14)
91
+ * to the largest interrupt available in the series, where the value
92
+ * for nonnegative enumerators corresponds to its position in the
93
+ * vector table.
94
+ *
95
+ * It also must define a static inline nvic_irq_disable_all(), which
96
+ * writes 0xFFFFFFFF to all ICE registers available in the series. (We
97
+ * place the include here to give the series header access to
98
+ * NVIC_BASE, in order to let it do so).
99
+ */
100
+#include <series/nvic.h>
101
+
102
+void nvic_init(uint32 address, uint32 offset);
103
+void nvic_set_vector_table(uint32 address, uint32 offset);
104
+void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority);
105
+void nvic_sys_reset();
106
+
107
+/**
108
+ * Enables interrupts and configurable fault handlers (clear PRIMASK).
109
+ */
110
+static inline void nvic_globalirq_enable() {
111
+    asm volatile("cpsie i");
112
+}
113
+
114
+/**
115
+ * Disable interrupts and configurable fault handlers (set PRIMASK).
116
+ */
117
+static inline void nvic_globalirq_disable() {
118
+    asm volatile("cpsid i");
119
+}
120
+
121
+/**
122
+ * @brief Enable interrupt irq_num
123
+ * @param irq_num Interrupt to enable
124
+ */
125
+static inline void nvic_irq_enable(nvic_irq_num irq_num) {
126
+    if (irq_num < 0) {
127
+        return;
128
+    }
129
+    NVIC_BASE->ISER[irq_num / 32] = BIT(irq_num % 32);
130
+}
131
+
132
+/**
133
+ * @brief Disable interrupt irq_num
134
+ * @param irq_num Interrupt to disable
135
+ */
136
+static inline void nvic_irq_disable(nvic_irq_num irq_num) {
137
+    if (irq_num < 0) {
138
+        return;
139
+    }
140
+    NVIC_BASE->ICER[irq_num / 32] = BIT(irq_num % 32);
141
+}
142
+
143
+/**
144
+ * @brief Quickly disable all interrupts.
145
+ *
146
+ * Calling this function is significantly faster than calling
147
+ * nvic_irq_disable() in a loop.
148
+ */
149
+static inline void nvic_irq_disable_all(void);
150
+
151
+#ifdef __cplusplus
152
+}
153
+#endif
154
+
155
+#endif

libmaple/pwr.h → libmaple/include/libmaple/pwr.h 파일 보기

@@ -25,16 +25,20 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file pwr.h
29
- * @brief Power control (PWR) defines.
28
+ * @file libmaple/include/libmaple/pwr.h
29
+ * @brief Power control (PWR).
30 30
  */
31 31
 
32
-#include "libmaple.h"
32
+#ifndef _LIBMAPLE_PWR_H_
33
+#define _LIBMAPLE_PWR_H_
33 34
 
34 35
 #ifdef __cplusplus
35 36
 extern "C" {
36 37
 #endif
37 38
 
39
+#include <libmaple/libmaple.h>
40
+#include <series/pwr.h>
41
+
38 42
 /** Power interface register map. */
39 43
 typedef struct pwr_reg_map {
40 44
     __io uint32 CR;      /**< Control register */
@@ -51,28 +55,52 @@ typedef struct pwr_reg_map {
51 55
 /* Control register */
52 56
 
53 57
 /** Disable backup domain write protection bit */
54
-#define PWR_CR_DBP  8
58
+#define PWR_CR_DBP_BIT                  8
55 59
 /** Power voltage detector enable bit */
56
-#define PWR_CR_PVDE 4
60
+#define PWR_CR_PVDE_BIT                 4
57 61
 /** Clear standby flag bit */
58
-#define PWR_CR_CSBF 3
62
+#define PWR_CR_CSBF_BIT                 3
59 63
 /** Clear wakeup flag bit */
60
-#define PWR_CR_CWUF 2
64
+#define PWR_CR_CWUF_BIT                 2
61 65
 /** Power down deepsleep bit */
62
-#define PWR_CR_PDDS 1
66
+#define PWR_CR_PDDS_BIT                 1
63 67
 /** Low-power deepsleep bit */
64
-#define PWR_CR_LPDS 0
68
+#define PWR_CR_LPDS_BIT                 0
69
+
70
+/** Disable backup domain write protection */
71
+#define PWR_CR_DBP                      (1U << PWR_CR_DBP_BIT)
72
+/** Power voltage detector (PVD) level selection */
73
+#define PWR_CR_PLS                      (0x7 << 5)
74
+/** Power voltage detector enable */
75
+#define PWR_CR_PVDE                     (1U << PWR_CR_PVDE_BIT)
76
+/** Clear standby flag */
77
+#define PWR_CR_CSBF                     (1U << PWR_CR_CSBF_BIT)
78
+/** Clear wakeup flag */
79
+#define PWR_CR_CWUF                     (1U << PWR_CR_CWUF_BIT)
80
+/** Power down deepsleep */
81
+#define PWR_CR_PDDS                     (1U << PWR_CR_PDDS_BIT)
82
+/** Low-power deepsleep */
83
+#define PWR_CR_LPDS                     (1U << PWR_CR_LPDS_BIT)
65 84
 
66 85
 /* Control and status register */
67 86
 
68 87
 /** Enable wakeup pin bit */
69
-#define PWR_CSR_EWUP 8
88
+#define PWR_CSR_EWUP_BIT                 8
70 89
 /** PVD output bit */
71
-#define PWR_CSR_PVDO 2
90
+#define PWR_CSR_PVDO_BIT                 2
72 91
 /** Standby flag bit */
73
-#define PWR_CSR_SBF  1
92
+#define PWR_CSR_SBF_BIT                  1
74 93
 /** Wakeup flag bit */
75
-#define PWR_CSR_WUF  0
94
+#define PWR_CSR_WUF_BIT                  0
95
+
96
+/** Enable wakeup pin */
97
+#define PWR_CSR_EWUP                     (1U << PWR_CSR_EWUP_BIT)
98
+/** PVD output */
99
+#define PWR_CSR_PVDO                     (1U << PWR_CSR_PVDO_BIT)
100
+/** Standby flag */
101
+#define PWR_CSR_SBF                      (1U << PWR_CSR_SBF_BIT)
102
+/** Wakeup flag */
103
+#define PWR_CSR_WUF                      (1U << PWR_CSR_WUF_BIT)
76 104
 
77 105
 /*
78 106
  * Convenience functions
@@ -83,3 +111,5 @@ void pwr_init(void);
83 111
 #ifdef __cplusplus
84 112
 }
85 113
 #endif
114
+
115
+#endif

+ 175 - 0
libmaple/include/libmaple/rcc.h 파일 보기

@@ -0,0 +1,175 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Perry Hung.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @file libmaple/include/libmaple/rcc.h
29
+ * @brief Reset and Clock Control (RCC) interface.
30
+ */
31
+
32
+#ifndef _LIBMAPLE_RCC_H_
33
+#define _LIBMAPLE_RCC_H_
34
+
35
+#ifdef __cplusplus
36
+extern "C"{
37
+#endif
38
+
39
+#include <libmaple/libmaple_types.h>
40
+
41
+/* Put the SYSCLK sources before the series header is included, as it
42
+ * might need them. */
43
+/**
44
+ * @brief SYSCLK sources
45
+ * @see rcc_switch_sysclk()
46
+ */
47
+typedef enum rcc_sysclk_src {
48
+    RCC_CLKSRC_HSI = 0x0,
49
+    RCC_CLKSRC_HSE = 0x1,
50
+    RCC_CLKSRC_PLL = 0x2,
51
+} rcc_sysclk_src;
52
+
53
+#include <series/rcc.h>
54
+
55
+/* Note: Beyond the usual (registers, etc.), it's up to the series
56
+ * header to define the following types:
57
+ *
58
+ * - enum rcc_clk: Available system and secondary clock sources,
59
+ *   e.g. RCC_CLK_HSE, RCC_CLK_PLL, RCC_CLK_LSE.
60
+ *
61
+ *   Note that the inclusion of secondary clock sources (like LSI and
62
+ *   LSE) makes enum rcc_clk different from the SYSCLK sources, which
63
+ *   are defined in this header as enum rcc_sysclk_src.
64
+ *
65
+ *   IMPORTANT NOTE TO IMPLEMENTORS: If you are adding support for a
66
+ *   new STM32 series, see the comment near rcc_clk_reg() in
67
+ *   libmaple/rcc.c for information on how to choose these values so
68
+ *   that rcc_turn_on_clk() etc. will work on your series.
69
+ *
70
+ * - enum rcc_clk_id: For each available peripheral. These are widely used
71
+ *   as unique IDs (TODO extricate from RCC?). Peripherals which are
72
+ *   common across STM32 series should use the same token for their
73
+ *   rcc_clk_id in each series header.
74
+ *
75
+ * - enum rcc_clk_domain: For each clock domain. This is returned by
76
+ *   rcc_dev_clk(). For instance, each AHB and APB is a clock domain.
77
+ *
78
+ * - enum rcc_prescaler: And a suitable set of dividers for
79
+ *   rcc_set_prescaler().
80
+ *
81
+ * - enum rcc_pllsrc: For each PLL source. Same source, same token.
82
+ *
83
+ * - A target-dependent type to be pointed to by the data field in a
84
+ *   struct rcc_pll_cfg.
85
+ */
86
+
87
+#ifdef __DOXYGEN__
88
+/** RCC register map base pointer */
89
+#define RCC_BASE
90
+#endif
91
+
92
+/* Clock prescaler management. */
93
+
94
+/**
95
+ * @brief Set the divider on a peripheral prescaler
96
+ * @param prescaler prescaler to set
97
+ * @param divider prescaler divider
98
+ */
99
+extern void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider);
100
+
101
+/* SYSCLK. */
102
+
103
+void rcc_switch_sysclk(rcc_sysclk_src sysclk_src);
104
+
105
+/* PLL configuration */
106
+
107
+/**
108
+ * @brief Specifies a configuration for the main PLL.
109
+ */
110
+typedef struct rcc_pll_cfg {
111
+    rcc_pllsrc  pllsrc;     /**< PLL source */
112
+
113
+    /** Series-specific configuration data. */
114
+    void       *data;
115
+} rcc_pll_cfg;
116
+
117
+/**
118
+ * @brief Configure the main PLL.
119
+ *
120
+ * You may only call this function while the PLL is disabled.
121
+ *
122
+ * @param pll_cfg Desired PLL configuration. The contents of this
123
+ *                struct depend entirely on the target.
124
+ */
125
+extern void rcc_configure_pll(rcc_pll_cfg *pll_cfg);
126
+
127
+/* System and secondary clock sources. */
128
+
129
+void rcc_turn_on_clk(rcc_clk clock);
130
+void rcc_turn_off_clk(rcc_clk clock);
131
+int rcc_is_clk_on(rcc_clk clock);
132
+int rcc_is_clk_ready(rcc_clk clock);
133
+
134
+/* Peripheral clock lines and clock domains. */
135
+
136
+/**
137
+ * @brief Turn on the clock line on a peripheral
138
+ * @param id Clock ID of the peripheral to turn on.
139
+ */
140
+extern void rcc_clk_enable(rcc_clk_id id);
141
+
142
+/**
143
+ * @brief Reset a peripheral.
144
+ *
145
+ * Caution: not all rcc_clk_id values refer to a peripheral which can
146
+ * be reset. (Only rcc_clk_ids for peripherals with bits in an RCC
147
+ * reset register can be used here.)
148
+ *
149
+ * @param id Clock ID of the peripheral to reset.
150
+ */
151
+extern void rcc_reset_dev(rcc_clk_id id);
152
+
153
+rcc_clk_domain rcc_dev_clk(rcc_clk_id id);
154
+
155
+/* Clock security system */
156
+
157
+/**
158
+ * @brief Enable the clock security system (CSS).
159
+ */
160
+static inline void rcc_enable_css() {
161
+    RCC_BASE->CR |= RCC_CR_CSSON;
162
+}
163
+
164
+/**
165
+ * @brief Disable the clock security system (CSS).
166
+ */
167
+static inline void rcc_disable_css() {
168
+    RCC_BASE->CR &= ~RCC_CR_CSSON;
169
+}
170
+
171
+#ifdef __cplusplus
172
+} // extern "C"
173
+#endif
174
+
175
+#endif

libmaple/ring_buffer.h → libmaple/include/libmaple/ring_buffer.h 파일 보기

@@ -25,22 +25,22 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file ring_buffer.h
28
+ * @file libmaple/include/libmaple/ring_buffer.h
29 29
  * @brief Simple circular buffer
30 30
  *
31 31
  * This implementation is not thread-safe.  In particular, none of
32 32
  * these functions is guaranteed re-entrant.
33 33
  */
34 34
 
35
-#ifndef _RING_BUFFER_H_
36
-#define _RING_BUFFER_H_
37
-
38
-#include "libmaple_types.h"
35
+#ifndef _LIBMAPLE_RING_BUFFER_H_
36
+#define _LIBMAPLE_RING_BUFFER_H_
39 37
 
40 38
 #ifdef __cplusplus
41 39
 extern "C"{
42 40
 #endif
43 41
 
42
+#include <libmaple/libmaple_types.h>
43
+
44 44
 /**
45 45
  * Ring buffer type.
46 46
  *
@@ -186,4 +186,3 @@ static inline void rb_reset(ring_buffer *rb) {
186 186
 #endif
187 187
 
188 188
 #endif
189
-

libmaple/scb.h → libmaple/include/libmaple/scb.h 파일 보기

@@ -25,14 +25,18 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file scb.h
28
+ * @file libmaple/include/libmaple/scb.h
29 29
  * @brief System control block header
30 30
  */
31 31
 
32
-#include "libmaple_types.h"
32
+#ifndef _LIBMAPLE_SCB_H_
33
+#define _LIBMAPLE_SCB_H_
33 34
 
34
-#ifndef _SCB_H_
35
-#define _SCB_H_
35
+#ifdef __cplusplus
36
+extern "C" {
37
+#endif
38
+
39
+#include <libmaple/libmaple_types.h>
36 40
 
37 41
 /*
38 42
  * Register map and base pointer
@@ -198,4 +202,8 @@ typedef struct scb_reg_map {
198 202
 #define SCB_DFSR_BKPT                   BIT(1)
199 203
 #define SCB_DFSR_HALTED                 BIT(0)
200 204
 
205
+#ifdef __cplusplus
206
+}
207
+#endif
208
+
201 209
 #endif

libmaple/spi.h → libmaple/include/libmaple/spi.h 파일 보기

@@ -1,6 +1,7 @@
1 1
 /******************************************************************************
2 2
  * The MIT License
3 3
  *
4
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
4 5
  * Copyright (c) 2010 Perry Hung.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
@@ -25,7 +26,7 @@
25 26
  *****************************************************************************/
26 27
 
27 28
 /**
28
- * @file spi.h
29
+ * @file libmaple/include/libmaple/spi.h
29 30
  * @author Marti Bolivar <mbolivar@leaflabs.com>
30 31
  * @brief Serial Peripheral Interface (SPI) and Integrated
31 32
  *        Interchip Sound (I2S) peripheral support.
@@ -33,19 +34,18 @@
33 34
  * I2S support is currently limited to register maps and bit definitions.
34 35
  */
35 36
 
36
-#ifndef _SPI_H_
37
-#define _SPI_H_
38
-
39
-#include "libmaple_types.h"
40
-#include "rcc.h"
41
-#include "nvic.h"
42
-#include "gpio.h"
43
-#include "util.h"
37
+#ifndef _LIBMAPLE_SPI_H_
38
+#define _LIBMAPLE_SPI_H_
44 39
 
45 40
 #ifdef __cplusplus
46 41
 extern "C" {
47 42
 #endif
48 43
 
44
+#include <libmaple/libmaple_types.h>
45
+#include <libmaple/rcc.h>
46
+#include <libmaple/nvic.h>
47
+#include <series/spi.h>
48
+
49 49
 /*
50 50
  * Register maps
51 51
  */
@@ -63,13 +63,6 @@ typedef struct spi_reg_map {
63 63
     __io uint32 I2SPR;          /**< I2S prescaler register */
64 64
 } spi_reg_map;
65 65
 
66
-/** SPI1 register map base pointer */
67
-#define SPI1_BASE                       ((struct spi_reg_map*)0x40013000)
68
-/** SPI2 register map base pointer */
69
-#define SPI2_BASE                       ((struct spi_reg_map*)0x40003800)
70
-/** SPI3 register map base pointer */
71
-#define SPI3_BASE                       ((struct spi_reg_map*)0x40003C00)
72
-
73 66
 /*
74 67
  * Register bit definitions
75 68
  */
@@ -90,20 +83,20 @@ typedef struct spi_reg_map {
90 83
 #define SPI_CR1_CPOL_BIT                1
91 84
 #define SPI_CR1_CPHA_BIT                0
92 85
 
93
-#define SPI_CR1_BIDIMODE                BIT(SPI_CR1_BIDIMODE_BIT)
86
+#define SPI_CR1_BIDIMODE                (1U << SPI_CR1_BIDIMODE_BIT)
94 87
 #define SPI_CR1_BIDIMODE_2_LINE         (0x0 << SPI_CR1_BIDIMODE_BIT)
95 88
 #define SPI_CR1_BIDIMODE_1_LINE         (0x1 << SPI_CR1_BIDIMODE_BIT)
96
-#define SPI_CR1_BIDIOE                  BIT(SPI_CR1_BIDIOE_BIT)
97
-#define SPI_CR1_CRCEN                   BIT(SPI_CR1_CRCEN_BIT)
98
-#define SPI_CR1_CRCNEXT                 BIT(SPI_CR1_CRCNEXT_BIT)
99
-#define SPI_CR1_DFF                     BIT(SPI_CR1_DFF_BIT)
89
+#define SPI_CR1_BIDIOE                  (1U << SPI_CR1_BIDIOE_BIT)
90
+#define SPI_CR1_CRCEN                   (1U << SPI_CR1_CRCEN_BIT)
91
+#define SPI_CR1_CRCNEXT                 (1U << SPI_CR1_CRCNEXT_BIT)
92
+#define SPI_CR1_DFF                     (1U << SPI_CR1_DFF_BIT)
100 93
 #define SPI_CR1_DFF_8_BIT               (0x0 << SPI_CR1_DFF_BIT)
101 94
 #define SPI_CR1_DFF_16_BIT              (0x1 << SPI_CR1_DFF_BIT)
102
-#define SPI_CR1_RXONLY                  BIT(SPI_CR1_RXONLY_BIT)
103
-#define SPI_CR1_SSM                     BIT(SPI_CR1_SSM_BIT)
104
-#define SPI_CR1_SSI                     BIT(SPI_CR1_SSI_BIT)
105
-#define SPI_CR1_LSBFIRST                BIT(SPI_CR1_LSBFIRST_BIT)
106
-#define SPI_CR1_SPE                     BIT(SPI_CR1_SPE_BIT)
95
+#define SPI_CR1_RXONLY                  (1U << SPI_CR1_RXONLY_BIT)
96
+#define SPI_CR1_SSM                     (1U << SPI_CR1_SSM_BIT)
97
+#define SPI_CR1_SSI                     (1U << SPI_CR1_SSI_BIT)
98
+#define SPI_CR1_LSBFIRST                (1U << SPI_CR1_LSBFIRST_BIT)
99
+#define SPI_CR1_SPE                     (1U << SPI_CR1_SPE_BIT)
107 100
 #define SPI_CR1_BR                      (0x7 << 3)
108 101
 #define SPI_CR1_BR_PCLK_DIV_2           (0x0 << 3)
109 102
 #define SPI_CR1_BR_PCLK_DIV_4           (0x1 << 3)
@@ -113,17 +106,14 @@ typedef struct spi_reg_map {
113 106
 #define SPI_CR1_BR_PCLK_DIV_64          (0x5 << 3)
114 107
 #define SPI_CR1_BR_PCLK_DIV_128         (0x6 << 3)
115 108
 #define SPI_CR1_BR_PCLK_DIV_256         (0x7 << 3)
116
-#define SPI_CR1_MSTR                    BIT(SPI_CR1_MSTR_BIT)
117
-#define SPI_CR1_CPOL                    BIT(SPI_CR1_CPOL_BIT)
109
+#define SPI_CR1_MSTR                    (1U << SPI_CR1_MSTR_BIT)
110
+#define SPI_CR1_CPOL                    (1U << SPI_CR1_CPOL_BIT)
118 111
 #define SPI_CR1_CPOL_LOW                (0x0 << SPI_CR1_CPOL_BIT)
119 112
 #define SPI_CR1_CPOL_HIGH               (0x1 << SPI_CR1_CPOL_BIT)
120
-#define SPI_CR1_CPHA                    BIT(SPI_CR1_CPHA_BIT)
113
+#define SPI_CR1_CPHA                    (1U << SPI_CR1_CPHA_BIT)
121 114
 
122 115
 /* Control register 2 */
123 116
 
124
-/* RM0008-ism: SPI CR2 has "TXDMAEN" and "RXDMAEN" bits, while the
125
- * USARTs have CR3 "DMAR" and "DMAT" bits. */
126
-
127 117
 #define SPI_CR2_TXEIE_BIT               7
128 118
 #define SPI_CR2_RXNEIE_BIT              6
129 119
 #define SPI_CR2_ERRIE_BIT               5
@@ -131,12 +121,12 @@ typedef struct spi_reg_map {
131 121
 #define SPI_CR2_TXDMAEN_BIT             1
132 122
 #define SPI_CR2_RXDMAEN_BIT             0
133 123
 
134
-#define SPI_CR2_TXEIE                   BIT(SPI_CR2_TXEIE_BIT)
135
-#define SPI_CR2_RXNEIE                  BIT(SPI_CR2_RXNEIE_BIT)
136
-#define SPI_CR2_ERRIE                   BIT(SPI_CR2_ERRIE_BIT)
137
-#define SPI_CR2_SSOE                    BIT(SPI_CR2_SSOE_BIT)
138
-#define SPI_CR2_TXDMAEN                 BIT(SPI_CR2_TXDMAEN_BIT)
139
-#define SPI_CR2_RXDMAEN                 BIT(SPI_CR2_RXDMAEN_BIT)
124
+#define SPI_CR2_TXEIE                   (1U << SPI_CR2_TXEIE_BIT)
125
+#define SPI_CR2_RXNEIE                  (1U << SPI_CR2_RXNEIE_BIT)
126
+#define SPI_CR2_ERRIE                   (1U << SPI_CR2_ERRIE_BIT)
127
+#define SPI_CR2_SSOE                    (1U << SPI_CR2_SSOE_BIT)
128
+#define SPI_CR2_TXDMAEN                 (1U << SPI_CR2_TXDMAEN_BIT)
129
+#define SPI_CR2_RXDMAEN                 (1U << SPI_CR2_RXDMAEN_BIT)
140 130
 
141 131
 /* Status register */
142 132
 
@@ -149,37 +139,35 @@ typedef struct spi_reg_map {
149 139
 #define SPI_SR_TXE_BIT                  1
150 140
 #define SPI_SR_RXNE_BIT                 0
151 141
 
152
-#define SPI_SR_BSY                      BIT(SPI_SR_BSY_BIT)
153
-#define SPI_SR_OVR                      BIT(SPI_SR_OVR_BIT)
154
-#define SPI_SR_MODF                     BIT(SPI_SR_MODF_BIT)
155
-#define SPI_SR_CRCERR                   BIT(SPI_SR_CRCERR_BIT)
156
-#define SPI_SR_UDR                      BIT(SPI_SR_UDR_BIT)
157
-#define SPI_SR_CHSIDE                   BIT(SPI_SR_CHSIDE_BIT)
142
+#define SPI_SR_BSY                      (1U << SPI_SR_BSY_BIT)
143
+#define SPI_SR_OVR                      (1U << SPI_SR_OVR_BIT)
144
+#define SPI_SR_MODF                     (1U << SPI_SR_MODF_BIT)
145
+#define SPI_SR_CRCERR                   (1U << SPI_SR_CRCERR_BIT)
146
+#define SPI_SR_UDR                      (1U << SPI_SR_UDR_BIT)
147
+#define SPI_SR_CHSIDE                   (1U << SPI_SR_CHSIDE_BIT)
158 148
 #define SPI_SR_CHSIDE_LEFT              (0x0 << SPI_SR_CHSIDE_BIT)
159 149
 #define SPI_SR_CHSIDE_RIGHT             (0x1 << SPI_SR_CHSIDE_BIT)
160
-#define SPI_SR_TXE                      BIT(SPI_SR_TXE_BIT)
161
-#define SPI_SR_RXNE                     BIT(SPI_SR_RXNE_BIT)
150
+#define SPI_SR_TXE                      (1U << SPI_SR_TXE_BIT)
151
+#define SPI_SR_RXNE                     (1U << SPI_SR_RXNE_BIT)
162 152
 
163 153
 /* I2S configuration register */
164 154
 
165
-/* RM0008-ism: CR1 has "CPOL", I2SCFGR has "CKPOL". */
166
-
167 155
 #define SPI_I2SCFGR_I2SMOD_BIT          11
168 156
 #define SPI_I2SCFGR_I2SE_BIT            10
169 157
 #define SPI_I2SCFGR_PCMSYNC_BIT         7
170 158
 #define SPI_I2SCFGR_CKPOL_BIT           3
171 159
 #define SPI_I2SCFGR_CHLEN_BIT           0
172 160
 
173
-#define SPI_I2SCFGR_I2SMOD              BIT(SPI_I2SCFGR_I2SMOD_BIT)
161
+#define SPI_I2SCFGR_I2SMOD              (1U << SPI_I2SCFGR_I2SMOD_BIT)
174 162
 #define SPI_I2SCFGR_I2SMOD_SPI          (0x0 << SPI_I2SCFGR_I2SMOD_BIT)
175 163
 #define SPI_I2SCFGR_I2SMOD_I2S          (0x1 << SPI_I2SCFGR_I2SMOD_BIT)
176
-#define SPI_I2SCFGR_I2SE                BIT(SPI_I2SCFGR_I2SE_BIT)
164
+#define SPI_I2SCFGR_I2SE                (1U << SPI_I2SCFGR_I2SE_BIT)
177 165
 #define SPI_I2SCFGR_I2SCFG              (0x3 << 8)
178 166
 #define SPI_I2SCFGR_I2SCFG_SLAVE_TX     (0x0 << 8)
179 167
 #define SPI_I2SCFGR_I2SCFG_SLAVE_RX     (0x1 << 8)
180 168
 #define SPI_I2SCFGR_I2SCFG_MASTER_TX    (0x2 << 8)
181 169
 #define SPI_I2SCFGR_I2SCFG_MASTER_RX    (0x3 << 8)
182
-#define SPI_I2SCFGR_PCMSYNC             BIT(SPI_I2SCFGR_PCMSYNC_BIT)
170
+#define SPI_I2SCFGR_PCMSYNC             (1U << SPI_I2SCFGR_PCMSYNC_BIT)
183 171
 #define SPI_I2SCFGR_PCMSYNC_SHORT       (0x0 << SPI_I2SCFGR_PCMSYNC_BIT)
184 172
 #define SPI_I2SCFGR_PCMSYNC_LONG        (0x1 << SPI_I2SCFGR_PCMSYNC_BIT)
185 173
 #define SPI_I2SCFGR_I2SSTD              (0x3 << 4)
@@ -187,17 +175,26 @@ typedef struct spi_reg_map {
187 175
 #define SPI_I2SCFGR_I2SSTD_MSB          (0x1 << 4)
188 176
 #define SPI_I2SCFGR_I2SSTD_LSB          (0x2 << 4)
189 177
 #define SPI_I2SCFGR_I2SSTD_PCM          (0x3 << 4)
190
-#define SPI_I2SCFGR_CKPOL               BIT(SPI_I2SCFGR_CKPOL_BIT)
178
+#define SPI_I2SCFGR_CKPOL               (1U << SPI_I2SCFGR_CKPOL_BIT)
191 179
 #define SPI_I2SCFGR_CKPOL_LOW           (0x0 << SPI_I2SCFGR_CKPOL_BIT)
192 180
 #define SPI_I2SCFGR_CKPOL_HIGH          (0x1 << SPI_I2SCFGR_CKPOL_BIT)
193 181
 #define SPI_I2SCFGR_DATLEN              (0x3 << 1)
194 182
 #define SPI_I2SCFGR_DATLEN_16_BIT       (0x0 << 1)
195 183
 #define SPI_I2SCFGR_DATLEN_24_BIT       (0x1 << 1)
196 184
 #define SPI_I2SCFGR_DATLEN_32_BIT       (0x2 << 1)
197
-#define SPI_I2SCFGR_CHLEN               BIT(SPI_I2SCFGR_CHLEN_BIT)
185
+#define SPI_I2SCFGR_CHLEN               (1U << SPI_I2SCFGR_CHLEN_BIT)
198 186
 #define SPI_I2SCFGR_CHLEN_16_BIT        (0x0 << SPI_I2SCFGR_CHLEN_BIT)
199 187
 #define SPI_I2SCFGR_CHLEN_32_BIT        (0x1 << SPI_I2SCFGR_CHLEN_BIT)
200 188
 
189
+/* I2S prescaler register */
190
+
191
+#define SPI_I2SPR_MCKOE_BIT             9
192
+#define SPI_I2SPR_ODD_BIT               8
193
+
194
+#define SPI_I2SPR_MCKOE                 (1U << SPI_I2SPR_MCKOE_BIT)
195
+#define SPI_I2SPR_ODD                   (1U << SPI_I2SPR_ODD_BIT)
196
+#define SPI_I2SPR_I2SDIV                0xFF
197
+
201 198
 /*
202 199
  * Devices
203 200
  */
@@ -209,42 +206,54 @@ typedef struct spi_dev {
209 206
     nvic_irq_num irq_num;       /**< NVIC interrupt number */
210 207
 } spi_dev;
211 208
 
212
-extern spi_dev *SPI1;
213
-extern spi_dev *SPI2;
214
-#ifdef STM32_HIGH_DENSITY
215
-extern spi_dev *SPI3;
216
-#endif
217
-
218 209
 /*
219 210
  * SPI Convenience functions
220 211
  */
221 212
 
222 213
 void spi_init(spi_dev *dev);
223 214
 
224
-void spi_gpio_cfg(uint8 as_master,
225
-                  gpio_dev *nss_dev,
226
-                  uint8 nss_bit,
227
-                  gpio_dev *comm_dev,
228
-                  uint8 sck_bit,
229
-                  uint8 miso_bit,
230
-                  uint8 mosi_bit);
215
+struct gpio_dev;
216
+/**
217
+ * @brief Configure GPIO bit modes for use as a SPI port's pins.
218
+ * @param as_master If true, configure bits for use as a bus master.
219
+ *                  Otherwise, configure bits for use as slave.
220
+ * @param nss_dev NSS pin's GPIO device
221
+ * @param comm_dev SCK, MISO, MOSI pins' GPIO device
222
+ * @param nss_bit NSS pin's GPIO bit on nss_dev
223
+ * @param sck_bit SCK pin's GPIO bit on comm_dev
224
+ * @param miso_bit MISO pin's GPIO bit on comm_dev
225
+ * @param mosi_bit MOSI pin's GPIO bit on comm_dev
226
+ */
227
+extern void spi_config_gpios(spi_dev *dev,
228
+                             uint8 as_master,
229
+                             struct gpio_dev *nss_dev,
230
+                             uint8 nss_bit,
231
+                             struct gpio_dev *comm_dev,
232
+                             uint8 sck_bit,
233
+                             uint8 miso_bit,
234
+                             uint8 mosi_bit);
231 235
 
232 236
 /**
233 237
  * @brief SPI mode configuration.
234 238
  *
235
- * Determines a combination of clock polarity (CPOL), which determines
236
- * idle state of the clock line, and clock phase (CPHA), which
237
- * determines which clock edge triggers data capture.
239
+ * A SPI mode determines a combination of the idle state of the clock
240
+ * line (the clock polarity, or "CPOL"), and which clock edge triggers
241
+ * data capture (the clock phase, or "CPHA").
238 242
  */
239 243
 typedef enum spi_mode {
240
-    SPI_MODE_0,  /**< Clock line idles low (0), data capture on first
241
-                    clock transition. */
242
-    SPI_MODE_1,  /**< Clock line idles low (0), data capture on second
243
-                    clock transition */
244
-    SPI_MODE_2,  /**< Clock line idles high (1), data capture on first
245
-                    clock transition. */
246
-    SPI_MODE_3   /**< Clock line idles high (1), data capture on
247
-                    second clock transition. */
244
+    /** Clock idles low, data captured on rising edge (first transition) */
245
+    SPI_MODE_LOW_RISING = 0,
246
+    /** Clock idles low, data captured on falling edge (second transition) */
247
+    SPI_MODE_LOW_FALLING = 1,
248
+    /** Clock idles high, data captured on falling edge (first transition) */
249
+    SPI_MODE_HIGH_FALLING = 2,
250
+    /** Clock idles high, data captured on rising edge (second transition) */
251
+    SPI_MODE_HIGH_RISING = 3,
252
+
253
+    SPI_MODE_0 = SPI_MODE_LOW_RISING,   /**< Same as SPI_MODE_LOW_RISING */
254
+    SPI_MODE_1 = SPI_MODE_LOW_FALLING,  /**< Same as SPI_MODE_LOW_FALLING */
255
+    SPI_MODE_2 = SPI_MODE_HIGH_FALLING, /**< Same as SPI_MODE_HIGH_FALLING */
256
+    SPI_MODE_3 = SPI_MODE_HIGH_RISING,  /**< Same as SPI_MODE_HIGH_RISING */
248 257
 } spi_mode;
249 258
 
250 259
 /**
@@ -299,7 +308,11 @@ void spi_slave_enable(spi_dev *dev,
299 308
 
300 309
 uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len);
301 310
 
302
-void spi_foreach(void (*fn)(spi_dev (*dev)));
311
+/**
312
+ * @brief Call a function on each SPI port
313
+ * @param fn Function to call.
314
+ */
315
+extern void spi_foreach(void (*fn)(spi_dev*));
303 316
 
304 317
 void spi_peripheral_enable(spi_dev *dev);
305 318
 void spi_peripheral_disable(spi_dev *dev);

+ 237 - 0
libmaple/include/libmaple/stm32.h 파일 보기

@@ -0,0 +1,237 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010, 2011, 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @file libmaple/include/libmaple/stm32.h
29
+ * @brief STM32 chip header
30
+ *
31
+ * This header supplies various chip-specific values for the current
32
+ * build target. It's useful both to abstract away hardware details
33
+ * (e.g. through use of STM32_NR_INTERRUPTS) and to decide what to do
34
+ * when you want something nonportable (e.g. by checking
35
+ * STM32_MCU_SERIES).
36
+ */
37
+
38
+#ifndef _LIBMAPLE_STM32_H_
39
+#define _LIBMAPLE_STM32_H_
40
+
41
+#ifdef __cplusplus
42
+extern "C" {
43
+#endif
44
+
45
+/*
46
+ * STM32 series identifiers.
47
+ *
48
+ * Don't make these into an enum; the preprocessor needs them.
49
+ */
50
+
51
+/** STM32F1 series. */
52
+#define STM32_SERIES_F1 0
53
+/** STM32F2 series. */
54
+#define STM32_SERIES_F2 1
55
+/** STM32L1 series. */
56
+#define STM32_SERIES_L1 2
57
+/** STM32F4 series. */
58
+#define STM32_SERIES_F4 3
59
+
60
+/* The series header is responsible for defining:
61
+ *
62
+ * - Everything in the following __DOXYGEN__ conditional block.
63
+ *
64
+ * - STM32_HAVE_FSMC: 1 if the MCU has the FSMC peripheral, and 0
65
+ *   otherwise.
66
+ *
67
+ * - STM32_HAVE_USB: 1 if the MCU has a USB peripheral, and 0
68
+ *   otherwise.
69
+ */
70
+#include <series/stm32.h>
71
+
72
+/* Ensure the series header isn't broken. */
73
+#if (!defined(STM32_PCLK1)         ||     \
74
+     !defined(STM32_PCLK2)         ||     \
75
+     !defined(STM32_MCU_SERIES)    ||     \
76
+     !defined(STM32_NR_INTERRUPTS) ||     \
77
+     !defined(STM32_NR_GPIO_PORTS) ||     \
78
+     !defined(STM32_TIMER_MASK)    ||     \
79
+     !defined(STM32_DELAY_US_MULT) ||     \
80
+     !defined(STM32_SRAM_END)      ||     \
81
+     !defined(STM32_HAVE_DAC)      ||     \
82
+     !defined(STM32_HAVE_FSMC)     ||     \
83
+     !defined(STM32_HAVE_USB))
84
+#error "Bad STM32F1 configuration. Check <series/stm32.h> header for your MCU."
85
+#endif
86
+
87
+/*
88
+ * Derived macros
89
+ */
90
+
91
+/* FIXME [0.0.13] add this to ReST API page */
92
+/**
93
+ * @brief Statically determine whether a timer is present.
94
+ *
95
+ * Given a constant timer number n (starting from 1), this macro has a
96
+ * nonzero value exactly when TIMERn is available.
97
+ */
98
+#define STM32_HAVE_TIMER(n) (STM32_TIMER_MASK & (1 << (n)))
99
+
100
+/*
101
+ * Doxygen for functionality provided by series header.
102
+ */
103
+
104
+#ifdef __DOXYGEN__
105
+
106
+/*
107
+ * Clock configuration.
108
+ *
109
+ * These defines depend upon how the MCU is configured.  Because of
110
+ * the potential for a mismatch between them and the actual clock
111
+ * configuration, keep their number to a minimum.
112
+ */
113
+
114
+/**
115
+ * @brief APB1 clock speed, in Hz.
116
+ */
117
+#define STM32_PCLK1
118
+
119
+/**
120
+ *  @brief APB2 clock speed, in Hz.
121
+ */
122
+#define STM32_PCLK2
123
+
124
+/** @brief Deprecated. Use STM32_PCLK1 instead. */
125
+#define PCLK1
126
+/** @brief Deprecated. Use STM32_PCLK2 instead. */
127
+#define PCLK2
128
+
129
+/*
130
+ * Series- and MCU-specific values.
131
+ */
132
+
133
+/**
134
+ * @brief STM32 series value for the MCU being targeted.
135
+ *
136
+ * At time of writing, allowed values are: STM32_SERIES_F1,
137
+ * STM32_SERIES_F2. This set of values will expand as libmaple adds
138
+ * support for more STM32 series MCUs.
139
+ */
140
+#define STM32_MCU_SERIES
141
+
142
+/**
143
+ * @brief Number of interrupts in the vector table.
144
+ *
145
+ * This does not include Cortex-M interrupts (NMI, HardFault, etc.).
146
+ */
147
+#define STM32_NR_INTERRUPTS
148
+
149
+/**
150
+ * Number of GPIO ports.
151
+ */
152
+#define STM32_NR_GPIO_PORTS
153
+
154
+/* FIXME [0.0.13] add this to ReST API page */
155
+/**
156
+ * @brief Bitmask of timers available on the MCU.
157
+ *
158
+ * That is, if TIMERn is available, then STM32_TIMER_MASK & (1 << n)
159
+ * will be nonzero. For example, a nonzero value of "STM32_TIMER_MASK
160
+ * & 0x2" means TIMER1 is available.
161
+ *
162
+ * A bitmask is necessary as some STM32 MCUs have "holes" in the range
163
+ * of available timers.
164
+ */
165
+#define STM32_TIMER_MASK
166
+
167
+/**
168
+ * @brief Multiplier to convert microseconds into loop iterations
169
+ *        in delay_us().
170
+ *
171
+ * @see delay_us()
172
+ */
173
+#define STM32_DELAY_US_MULT
174
+
175
+/**
176
+ * @brief Pointer to end of built-in SRAM.
177
+ *
178
+ * Points to the address which is 1 byte past the last valid
179
+ * SRAM address.
180
+ */
181
+#define STM32_SRAM_END
182
+
183
+/**
184
+ * @brief 1 if the target MCU has a DAC, and 0 otherwise.
185
+ */
186
+#define STM32_HAVE_DAC
187
+
188
+/**
189
+ * @brief 1 if the target MCU has the FSMC peripheral, and 0 otherwise.
190
+ *
191
+ * Note that the feature set of the FSMC peripheral is restricted on
192
+ * some MCUs.
193
+ */
194
+#define STM32_HAVE_FSMC
195
+
196
+/**
197
+ * @brief 1 if the target MCU has a USB peripheral, and 0 otherwise.
198
+ *
199
+ * Note that a variety of USB peripherals are available across the
200
+ * different series, with widely varying feature sets and programming
201
+ * interfaces. This macro will be 1 if any such peripheral is present.
202
+ */
203
+#define STM32_HAVE_USB
204
+
205
+#endif  /* __DOXYGEN__ */
206
+
207
+/*
208
+ * The following are for backwards compatibility only.
209
+ */
210
+
211
+/* PCLK1 and PCLK2 are for backwards compatibility only; don't use in
212
+ * new code. */
213
+#ifndef PCLK1
214
+#define PCLK1 STM32_PCLK1
215
+#endif
216
+#if PCLK1 != STM32_PCLK1
217
+#error "PCLK1 (which is deprecated) differs from STM32_PCLK1."
218
+#endif
219
+#ifndef PCLK2
220
+#define PCLK2 STM32_PCLK2
221
+#endif
222
+#if PCLK2 != STM32_PCLK2
223
+#error "PCLK2 (which is deprecated) differs from STM32_PCLK2."
224
+#endif
225
+
226
+/** @brief Deprecated. Use STM32_NR_INTERRUPTS instead. */
227
+#define NR_INTERRUPTS                   STM32_NR_INTERRUPTS
228
+/** @brief Deprecated. Use STM32_NR_GPIO_PORTS instead. */
229
+#define NR_GPIO_PORTS                   STM32_NR_GPIO_PORTS
230
+/** @brief Deprecated. Use STM32_DELAY_US_MULT instead. */
231
+#define DELAY_US_MULT                   STM32_DELAY_US_MULT
232
+
233
+#ifdef __cplusplus
234
+}
235
+#endif
236
+
237
+#endif

+ 151 - 0
libmaple/include/libmaple/syscfg.h 파일 보기

@@ -0,0 +1,151 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @file libmaple/include/libmaple/syscfg.h
29
+ * @brief System configuration controller (SYSCFG)
30
+ *
31
+ * Availability: STM32F2, STM32F4.
32
+ */
33
+
34
+#ifndef _LIBMAPLE_SYSCFG_H_
35
+#define _LIBMAPLE_SYSCFG_H_
36
+
37
+#ifdef __cplusplus
38
+extern "C" {
39
+#endif
40
+
41
+#include <libmaple/libmaple_types.h>
42
+
43
+/*
44
+ * Register map and base pointer
45
+ */
46
+
47
+/**
48
+ * @brief SYSCFG register map type.
49
+ */
50
+typedef struct syscfg_reg_map {
51
+    __io uint32 MEMRMP;    /**< Memory remap register */
52
+    __io uint32 PMC;       /**< Peripheral mode configuration */
53
+    __io uint32 EXTICR[4]; /**< External interrupt configuration registers */
54
+    const uint32 RESERVED1;
55
+    const uint32 RESERVED2;
56
+    __io uint32 CMPCR;   /**< Compensation cell control register */
57
+} syscfg_reg_map;
58
+
59
+/** SYSCFG register map base pointer */
60
+#define SYSCFG_BASE                     ((struct syscfg_reg_map*)0x40013800)
61
+
62
+/*
63
+ * Register bit definitions
64
+ */
65
+
66
+/* Memory remap register */
67
+
68
+#define SYSCFG_MEMRMP_MEM_MODE           0x3
69
+#define SYSCFG_MEMRMP_MEM_MODE_FLASH     0x0
70
+#define SYSCFG_MEMRMP_MEM_MODE_SYS_FLASH 0x1
71
+#define SYSCFG_MEMRMP_MEM_MODE_FSMC_1    0x2
72
+#define SYSCFG_MEMRMP_MEM_MODE_EMB_SRAM  0x3
73
+
74
+/* Peripheral mode configuration register */
75
+
76
+#define SYSCFG_PMC_MII_RMII_SEL_BIT     23
77
+
78
+#define SYSCFG_PMC_MII_RMII_SEL         (1U << SYSCFG_PMC_MII_RMII_SEL_BIT)
79
+#define SYSCFG_PMC_MII_RMII_SEL_MII     (0U << SYSCFG_PMC_MII_RMII_SEL_BIT)
80
+#define SYSCFG_PMC_MII_RMII_SEL_RMII    (1U << SYSCFG_PMC_MII_RMII_SEL_BIT)
81
+
82
+/* External interrupt configuration register 1 */
83
+
84
+#define SYSCFG_EXTICR1_EXTI0            0xF
85
+#define SYSCFG_EXTICR1_EXTI1            0xF0
86
+#define SYSCFG_EXTICR1_EXTI2            0xF00
87
+#define SYSCFG_EXTICR1_EXTI3            0xF000
88
+
89
+/* External interrupt configuration register 2 */
90
+
91
+#define SYSCFG_EXTICR2_EXTI4            0xF
92
+#define SYSCFG_EXTICR2_EXTI5            0xF0
93
+#define SYSCFG_EXTICR2_EXTI6            0xF00
94
+#define SYSCFG_EXTICR2_EXTI7            0xF000
95
+
96
+/* External interrupt configuration register 3 */
97
+
98
+#define SYSCFG_EXTICR3_EXTI8            0xF
99
+#define SYSCFG_EXTICR3_EXTI9            0xF0
100
+#define SYSCFG_EXTICR3_EXTI10           0xF00
101
+#define SYSCFG_EXTICR3_EXTI11           0xF000
102
+
103
+/* External interrupt configuration register 4 */
104
+
105
+#define SYSCFG_EXTICR4_EXTI12           0xF
106
+#define SYSCFG_EXTICR4_EXTI13           0xF0
107
+#define SYSCFG_EXTICR4_EXTI14           0xF00
108
+#define SYSCFG_EXTICR4_EXTI15           0xF000
109
+
110
+/* Compensation cell control register */
111
+
112
+#define SYSCFG_CMPCR_READY_BIT          8
113
+#define SYSCFG_CMPCR_CMP_PD_BIT         0
114
+
115
+#define SYSCFG_CMPCR_READY              (1U << SYSCFG_CMPCR_READY_BIT)
116
+#define SYSCFG_CMPCR_CMP_PD             (1U << SYSCFG_CMPCR_CMP_PD_BIT)
117
+#define SYSCFG_CMPCR_CMP_PD_PDWN        (0U << SYSCFG_CMPCR_CMP_PD_BIT)
118
+#define SYSCFG_CMPCR_CMP_PD_ENABLE      (1U << SYSCFG_CMPCR_CMP_PD_BIT)
119
+
120
+/*
121
+ * Routines
122
+ */
123
+
124
+void syscfg_init(void);
125
+
126
+void syscfg_enable_io_compensation(void);
127
+void syscfg_disable_io_compensation(void);
128
+
129
+/**
130
+ * @brief System memory mode
131
+ * These values specify what memory to map to address 0x00000000.
132
+ * @see syscfg_set_mem_mode
133
+ */
134
+typedef enum syscfg_mem_mode {
135
+    /** Main flash memory is mapped at 0x0. */
136
+    SYCFG_MEM_MODE_FLASH        = SYSCFG_MEMRMP_MEM_MODE_FLASH,
137
+    /** System flash (i.e. ST's baked-in bootloader) is mapped at 0x0. */
138
+    SYCFG_MEM_MODE_SYSTEM_FLASH = SYSCFG_MEMRMP_MEM_MODE_SYS_FLASH,
139
+    /** FSMC bank 1 (NOR/PSRAM 1 and 2) is mapped at 0x0. */
140
+    SYCFG_MEM_MODE_FSMC_BANK_1  = SYSCFG_MEMRMP_MEM_MODE_FSMC_1,
141
+    /** Embedded SRAM (i.e., not backup SRAM) is mapped at 0x0. */
142
+    SYCFG_MEM_MODE_SRAM         = SYSCFG_MEMRMP_MEM_MODE_EMB_SRAM,
143
+} syscfg_mem_mode;
144
+
145
+void syscfg_set_mem_mode(syscfg_mem_mode);
146
+
147
+#ifdef __cplusplus
148
+}
149
+#endif
150
+
151
+#endif

libmaple/systick.h → libmaple/include/libmaple/systick.h 파일 보기

@@ -25,21 +25,20 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file systick.h
29
- *
30
- * @brief Various system timer definitions
28
+ * @file libmaple/include/libmaple/systick.h
29
+ * @brief System timer definitions
31 30
  */
32 31
 
33
-#ifndef _SYSTICK_H_
34
-#define _SYSTICK_H_
35
-
36
-#include "libmaple_types.h"
37
-#include "util.h"
32
+#ifndef _LIBMAPLE_SYSTICK_H_
33
+#define _LIBMAPLE_SYSTICK_H_
38 34
 
39 35
 #ifdef __cplusplus
40 36
 extern "C"{
41 37
 #endif
42 38
 
39
+#include <libmaple/libmaple_types.h>
40
+#include <libmaple/util.h>
41
+
43 42
 /** SysTick register map type */
44 43
 typedef struct systick_reg_map {
45 44
     __io uint32 CSR;            /**< Control and status register */
@@ -114,4 +113,3 @@ static inline uint32 systick_check_underflow(void) {
114 113
 #endif
115 114
 
116 115
 #endif
117
-

libmaple/timer.h → libmaple/include/libmaple/timer.h 파일 보기

@@ -1,7 +1,7 @@
1 1
 /******************************************************************************
2 2
  * The MIT License
3 3
  *
4
- * Copyright (c) 2011 LeafLabs, LLC.
4
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
5 5
  *
6 6
  * Permission is hereby granted, free of charge, to any person
7 7
  * obtaining a copy of this software and associated documentation
@@ -25,27 +25,26 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file   timer.h
28
+ * @file   libmaple/include/libmaple/timer.h
29 29
  * @author Marti Bolivar <mbolivar@leaflabs.com>
30
- * @brief  New-style timer interface.
31
- *
32
- * Replaces old timers.h implementation.
30
+ * @brief  Timer interface.
33 31
  */
34 32
 
35
-#ifndef _TIMERS_H_
36
-#define _TIMERS_H_
37
-
38
-#include "libmaple.h"
39
-#include "rcc.h"
40
-#include "nvic.h"
41
-#include "bitband.h"
33
+#ifndef _LIBMAPLE_TIMER_H_
34
+#define _LIBMAPLE_TIMER_H_
42 35
 
43 36
 #ifdef __cplusplus
44 37
 extern "C"{
45 38
 #endif
46 39
 
40
+#include <series/timer.h>
41
+#include <libmaple/libmaple.h>
42
+#include <libmaple/rcc.h>
43
+#include <libmaple/nvic.h>
44
+#include <libmaple/bitband.h>
45
+
47 46
 /*
48
- * Register maps and devices
47
+ * Register maps
49 48
  */
50 49
 
51 50
 /** Advanced control timer register map type */
@@ -53,7 +52,7 @@ typedef struct timer_adv_reg_map {
53 52
     __io uint32 CR1;            /**< Control register 1 */
54 53
     __io uint32 CR2;            /**< Control register 2 */
55 54
     __io uint32 SMCR;           /**< Slave mode control register */
56
-    __io uint32 DIER;           /**< DMA/Interrupt enable register */
55
+    __io uint32 DIER;           /**< DMA/interrupt enable register */
57 56
     __io uint32 SR;             /**< Status register */
58 57
     __io uint32 EGR;            /**< Event generation register  */
59 58
     __io uint32 CCMR1;          /**< Capture/compare mode register 1 */
@@ -72,36 +71,17 @@ typedef struct timer_adv_reg_map {
72 71
     __io uint32 DMAR;           /**< DMA address for full transfer */
73 72
 } timer_adv_reg_map;
74 73
 
75
-/** General purpose timer register map type */
76
-typedef struct timer_gen_reg_map {
77
-    __io uint32 CR1;            /**< Control register 1 */
78
-    __io uint32 CR2;            /**< Control register 2 */
79
-    __io uint32 SMCR;           /**< Slave mode control register */
80
-    __io uint32 DIER;           /**< DMA/Interrupt enable register */
81
-    __io uint32 SR;             /**< Status register */
82
-    __io uint32 EGR;            /**< Event generation register  */
83
-    __io uint32 CCMR1;          /**< Capture/compare mode register 1 */
84
-    __io uint32 CCMR2;          /**< Capture/compare mode register 2 */
85
-    __io uint32 CCER;           /**< Capture/compare enable register */
86
-    __io uint32 CNT;            /**< Counter */
87
-    __io uint32 PSC;            /**< Prescaler */
88
-    __io uint32 ARR;            /**< Auto-reload register */
89
-    const uint32 RESERVED1;     /**< Reserved */
90
-    __io uint32 CCR1;           /**< Capture/compare register 1 */
91
-    __io uint32 CCR2;           /**< Capture/compare register 2 */
92
-    __io uint32 CCR3;           /**< Capture/compare register 3 */
93
-    __io uint32 CCR4;           /**< Capture/compare register 4 */
94
-    const uint32 RESERVED2;     /**< Reserved */
95
-    __io uint32 DCR;            /**< DMA control register */
96
-    __io uint32 DMAR;           /**< DMA address for full transfer */
97
-} timer_gen_reg_map;
74
+/* General purpose timer register map type: intentionally omitted.
75
+ *
76
+ * General purpose timers differ slightly across series, so leave it
77
+ * up to the series header to define struct timer_gen_reg_map. */
98 78
 
99 79
 /** Basic timer register map type */
100 80
 typedef struct timer_bas_reg_map {
101 81
     __io uint32 CR1;            /**< Control register 1 */
102 82
     __io uint32 CR2;            /**< Control register 2 */
103 83
     const uint32 RESERVED1;     /**< Reserved */
104
-    __io uint32 DIER;           /**< DMA/Interrupt enable register */
84
+    __io uint32 DIER;           /**< DMA/interrupt enable register */
105 85
     __io uint32 SR;             /**< Status register */
106 86
     __io uint32 EGR;            /**< Event generation register  */
107 87
     const uint32 RESERVED2;     /**< Reserved */
@@ -112,25 +92,6 @@ typedef struct timer_bas_reg_map {
112 92
     __io uint32 ARR;            /**< Auto-reload register */
113 93
 } timer_bas_reg_map;
114 94
 
115
-/** Timer 1 register map base pointer */
116
-#define TIMER1_BASE        ((struct timer_adv_reg_map*)0x40012C00)
117
-/** Timer 2 register map base pointer */
118
-#define TIMER2_BASE        ((struct timer_gen_reg_map*)0x40000000)
119
-/** Timer 3 register map base pointer */
120
-#define TIMER3_BASE        ((struct timer_gen_reg_map*)0x40000400)
121
-/** Timer 4 register map base pointer */
122
-#define TIMER4_BASE        ((struct timer_gen_reg_map*)0x40000800)
123
-#ifdef STM32_HIGH_DENSITY
124
-/** Timer 5 register map base pointer */
125
-#define TIMER5_BASE        ((struct timer_gen_reg_map*)0x40000C00)
126
-/** Timer 6 register map base pointer */
127
-#define TIMER6_BASE        ((struct timer_bas_reg_map*)0x40001000)
128
-/** Timer 7 register map base pointer */
129
-#define TIMER7_BASE        ((struct timer_bas_reg_map*)0x40001400)
130
-/** Timer 8 register map base pointer */
131
-#define TIMER8_BASE        ((struct timer_adv_reg_map*)0x40013400)
132
-#endif
133
-
134 95
 /*
135 96
  * Timer devices
136 97
  */
@@ -157,7 +118,7 @@ typedef union timer_reg_map {
157 118
 typedef enum timer_type {
158 119
     TIMER_ADVANCED,             /**< Advanced type */
159 120
     TIMER_GENERAL,              /**< General purpose type */
160
-    TIMER_BASIC                 /**< Basic type */
121
+    TIMER_BASIC,                /**< Basic type */
161 122
 } timer_type;
162 123
 
163 124
 /** Timer device type */
@@ -165,19 +126,54 @@ typedef struct timer_dev {
165 126
     timer_reg_map regs;         /**< Register map */
166 127
     rcc_clk_id clk_id;          /**< RCC clock information */
167 128
     timer_type type;            /**< Timer's type */
168
-    voidFuncPtr handlers[];     /**< User IRQ handlers */
129
+    voidFuncPtr handlers[];     /**<
130
+                                 * Don't touch these. Use these instead:
131
+                                 * @see timer_attach_interrupt()
132
+                                 * @see timer_detach_interrupt() */
169 133
 } timer_dev;
170 134
 
135
+#if STM32_HAVE_TIMER(1)
171 136
 extern timer_dev *TIMER1;
137
+#endif
138
+#if STM32_HAVE_TIMER(2)
172 139
 extern timer_dev *TIMER2;
140
+#endif
141
+#if STM32_HAVE_TIMER(3)
173 142
 extern timer_dev *TIMER3;
143
+#endif
144
+#if STM32_HAVE_TIMER(4)
174 145
 extern timer_dev *TIMER4;
175
-#ifdef STM32_HIGH_DENSITY
146
+#endif
147
+#if STM32_HAVE_TIMER(5)
176 148
 extern timer_dev *TIMER5;
149
+#endif
150
+#if STM32_HAVE_TIMER(6)
177 151
 extern timer_dev *TIMER6;
152
+#endif
153
+#if STM32_HAVE_TIMER(7)
178 154
 extern timer_dev *TIMER7;
155
+#endif
156
+#if STM32_HAVE_TIMER(8)
179 157
 extern timer_dev *TIMER8;
180 158
 #endif
159
+#if STM32_HAVE_TIMER(9)
160
+extern timer_dev *TIMER9;
161
+#endif
162
+#if STM32_HAVE_TIMER(10)
163
+extern timer_dev *TIMER10;
164
+#endif
165
+#if STM32_HAVE_TIMER(11)
166
+extern timer_dev *TIMER11;
167
+#endif
168
+#if STM32_HAVE_TIMER(12)
169
+extern timer_dev *TIMER12;
170
+#endif
171
+#if STM32_HAVE_TIMER(13)
172
+extern timer_dev *TIMER13;
173
+#endif
174
+#if STM32_HAVE_TIMER(14)
175
+extern timer_dev *TIMER14;
176
+#endif
181 177
 
182 178
 /*
183 179
  * Register bit definitions
@@ -196,17 +192,17 @@ extern timer_dev *TIMER8;
196 192
 #define TIMER_CR1_CKD_1TCKINT           (0x0 << 8)
197 193
 #define TIMER_CR1_CKD_2TCKINT           (0x1 << 8)
198 194
 #define TIMER_CR1_CKD_4TICKINT          (0x2 << 8)
199
-#define TIMER_CR1_ARPE                  BIT(TIMER_CR1_ARPE_BIT)
195
+#define TIMER_CR1_ARPE                  (1U << TIMER_CR1_ARPE_BIT)
200 196
 #define TIMER_CR1_CKD_CMS               (0x3 << 5)
201 197
 #define TIMER_CR1_CKD_CMS_EDGE          (0x0 << 5)
202 198
 #define TIMER_CR1_CKD_CMS_CENTER1       (0x1 << 5)
203 199
 #define TIMER_CR1_CKD_CMS_CENTER2       (0x2 << 5)
204 200
 #define TIMER_CR1_CKD_CMS_CENTER3       (0x3 << 5)
205
-#define TIMER_CR1_DIR                   BIT(TIMER_CR1_DIR_BIT)
206
-#define TIMER_CR1_OPM                   BIT(TIMER_CR1_OPM_BIT)
207
-#define TIMER_CR1_URS                   BIT(TIMER_CR1_URS_BIT)
208
-#define TIMER_CR1_UDIS                  BIT(TIMER_CR1_UDIS_BIT)
209
-#define TIMER_CR1_CEN                   BIT(TIMER_CR1_CEN_BIT)
201
+#define TIMER_CR1_DIR                   (1U << TIMER_CR1_DIR_BIT)
202
+#define TIMER_CR1_OPM                   (1U << TIMER_CR1_OPM_BIT)
203
+#define TIMER_CR1_URS                   (1U << TIMER_CR1_URS_BIT)
204
+#define TIMER_CR1_UDIS                  (1U << TIMER_CR1_UDIS_BIT)
205
+#define TIMER_CR1_CEN                   (1U << TIMER_CR1_CEN_BIT)
210 206
 
211 207
 /* Control register 2 (CR2) */
212 208
 
@@ -217,19 +213,19 @@ extern timer_dev *TIMER8;
217 213
 #define TIMER_CR2_OIS2_BIT              10
218 214
 #define TIMER_CR2_OIS1N_BIT             9
219 215
 #define TIMER_CR2_OIS1_BIT              8
220
-#define TIMER_CR2_TI1S_BIT              7 /* tills? yikes */
216
+#define TIMER_CR2_TI1S_BIT              7
221 217
 #define TIMER_CR2_CCDS_BIT              3
222 218
 #define TIMER_CR2_CCUS_BIT              2
223 219
 #define TIMER_CR2_CCPC_BIT              0
224 220
 
225
-#define TIMER_CR2_OIS4                  BIT(TIMER_CR2_OIS4_BIT)
226
-#define TIMER_CR2_OIS3N                 BIT(TIMER_CR2_OIS3N_BIT)
227
-#define TIMER_CR2_OIS3                  BIT(TIMER_CR2_OIS3_BIT)
228
-#define TIMER_CR2_OIS2N                 BIT(TIMER_CR2_OIS2N_BIT)
229
-#define TIMER_CR2_OIS2                  BIT(TIMER_CR2_OIS2_BIT)
230
-#define TIMER_CR2_OIS1N                 BIT(TIMER_CR2_OIS1N_BIT)
231
-#define TIMER_CR2_OIS1                  BIT(TIMER_CR2_OIS1_BIT)
232
-#define TIMER_CR2_TI1S                  BIT(TIMER_CR2_TI1S_BIT)
221
+#define TIMER_CR2_OIS4                  (1U << TIMER_CR2_OIS4_BIT)
222
+#define TIMER_CR2_OIS3N                 (1U << TIMER_CR2_OIS3N_BIT)
223
+#define TIMER_CR2_OIS3                  (1U << TIMER_CR2_OIS3_BIT)
224
+#define TIMER_CR2_OIS2N                 (1U << TIMER_CR2_OIS2N_BIT)
225
+#define TIMER_CR2_OIS2                  (1U << TIMER_CR2_OIS2_BIT)
226
+#define TIMER_CR2_OIS1N                 (1U << TIMER_CR2_OIS1N_BIT)
227
+#define TIMER_CR2_OIS1                  (1U << TIMER_CR2_OIS1_BIT)
228
+#define TIMER_CR2_TI1S                  (1U << TIMER_CR2_TI1S_BIT)
233 229
 #define TIMER_CR2_MMS                   (0x7 << 4)
234 230
 #define TIMER_CR2_MMS_RESET             (0x0 << 4)
235 231
 #define TIMER_CR2_MMS_ENABLE            (0x1 << 4)
@@ -239,9 +235,9 @@ extern timer_dev *TIMER8;
239 235
 #define TIMER_CR2_MMS_COMPARE_OC2REF    (0x5 << 4)
240 236
 #define TIMER_CR2_MMS_COMPARE_OC3REF    (0x6 << 4)
241 237
 #define TIMER_CR2_MMS_COMPARE_OC4REF    (0x7 << 4)
242
-#define TIMER_CR2_CCDS                  BIT(TIMER_CR2_CCDS_BIT)
243
-#define TIMER_CR2_CCUS                  BIT(TIMER_CR2_CCUS_BIT)
244
-#define TIMER_CR2_CCPC                  BIT(TIMER_CR2_CCPC_BIT)
238
+#define TIMER_CR2_CCDS                  (1U << TIMER_CR2_CCDS_BIT)
239
+#define TIMER_CR2_CCUS                  (1U << TIMER_CR2_CCUS_BIT)
240
+#define TIMER_CR2_CCPC                  (1U << TIMER_CR2_CCPC_BIT)
245 241
 
246 242
 /* Slave mode control register (SMCR) */
247 243
 
@@ -249,15 +245,15 @@ extern timer_dev *TIMER8;
249 245
 #define TIMER_SMCR_ECE_BIT              14
250 246
 #define TIMER_SMCR_MSM_BIT              7
251 247
 
252
-#define TIMER_SMCR_ETP                  BIT(TIMER_SMCR_ETP_BIT)
253
-#define TIMER_SMCR_ECE                  BIT(TIMER_SMCR_ECE_BIT)
248
+#define TIMER_SMCR_ETP                  (1U << TIMER_SMCR_ETP_BIT)
249
+#define TIMER_SMCR_ECE                  (1U << TIMER_SMCR_ECE_BIT)
254 250
 #define TIMER_SMCR_ETPS                 (0x3 << 12)
255 251
 #define TIMER_SMCR_ETPS_OFF             (0x0 << 12)
256 252
 #define TIMER_SMCR_ETPS_DIV2            (0x1 << 12)
257 253
 #define TIMER_SMCR_ETPS_DIV4            (0x2 << 12)
258 254
 #define TIMER_SMCR_ETPS_DIV8            (0x3 << 12)
259 255
 #define TIMER_SMCR_ETF                  (0xF << 12)
260
-#define TIMER_SMCR_MSM                  BIT(TIMER_SMCR_MSM_BIT)
256
+#define TIMER_SMCR_MSM                  (1U << TIMER_SMCR_MSM_BIT)
261 257
 #define TIMER_SMCR_TS                   (0x3 << 4)
262 258
 #define TIMER_SMCR_TS_ITR0              (0x0 << 4)
263 259
 #define TIMER_SMCR_TS_ITR1              (0x1 << 4)
@@ -280,30 +276,36 @@ extern timer_dev *TIMER8;
280 276
 /* DMA/Interrupt enable register (DIER) */
281 277
 
282 278
 #define TIMER_DIER_TDE_BIT              14
279
+#define TIMER_DIER_COMDE_BIT            13
283 280
 #define TIMER_DIER_CC4DE_BIT            12
284 281
 #define TIMER_DIER_CC3DE_BIT            11
285 282
 #define TIMER_DIER_CC2DE_BIT            10
286 283
 #define TIMER_DIER_CC1DE_BIT            9
287 284
 #define TIMER_DIER_UDE_BIT              8
285
+#define TIMER_DIER_BIE_BIT              7
288 286
 #define TIMER_DIER_TIE_BIT              6
287
+#define TIMER_DIER_COMIE_BIT            5
289 288
 #define TIMER_DIER_CC4IE_BIT            4
290 289
 #define TIMER_DIER_CC3IE_BIT            3
291 290
 #define TIMER_DIER_CC2IE_BIT            2
292 291
 #define TIMER_DIER_CC1IE_BIT            1
293 292
 #define TIMER_DIER_UIE_BIT              0
294 293
 
295
-#define TIMER_DIER_TDE                  BIT(TIMER_DIER_TDE_BIT)
296
-#define TIMER_DIER_CC4DE                BIT(TIMER_DIER_CC4DE_BIT)
297
-#define TIMER_DIER_CC3DE                BIT(TIMER_DIER_CC3DE_BIT)
298
-#define TIMER_DIER_CC2DE                BIT(TIMER_DIER_CC2DE_BIT)
299
-#define TIMER_DIER_CC1DE                BIT(TIMER_DIER_CC1DE_BIT)
300
-#define TIMER_DIER_UDE                  BIT(TIMER_DIER_UDE_BIT)
301
-#define TIMER_DIER_TIE                  BIT(TIMER_DIER_TIE_BIT)
302
-#define TIMER_DIER_CC4IE                BIT(TIMER_DIER_CC4IE_BIT)
303
-#define TIMER_DIER_CC3IE                BIT(TIMER_DIER_CC3IE_BIT)
304
-#define TIMER_DIER_CC2IE                BIT(TIMER_DIER_CC2IE_BIT)
305
-#define TIMER_DIER_CC1IE                BIT(TIMER_DIER_CC1IE_BIT)
306
-#define TIMER_DIER_UIE                  BIT(TIMER_DIER_UIE_BIT)
294
+#define TIMER_DIER_TDE                  (1U << TIMER_DIER_TDE_BIT)
295
+#define TIMER_DIER_COMDE                (1U << TIMER_DIER_COMDE_BIT)
296
+#define TIMER_DIER_CC4DE                (1U << TIMER_DIER_CC4DE_BIT)
297
+#define TIMER_DIER_CC3DE                (1U << TIMER_DIER_CC3DE_BIT)
298
+#define TIMER_DIER_CC2DE                (1U << TIMER_DIER_CC2DE_BIT)
299
+#define TIMER_DIER_CC1DE                (1U << TIMER_DIER_CC1DE_BIT)
300
+#define TIMER_DIER_UDE                  (1U << TIMER_DIER_UDE_BIT)
301
+#define TIMER_DIER_BIE                  (1U << TIMER_DIER_BIE_BIT)
302
+#define TIMER_DIER_TIE                  (1U << TIMER_DIER_TIE_BIT)
303
+#define TIMER_DIER_COMIE                (1U << TIMER_DIER_COMIE_BIT)
304
+#define TIMER_DIER_CC4IE                (1U << TIMER_DIER_CC4IE_BIT)
305
+#define TIMER_DIER_CC3IE                (1U << TIMER_DIER_CC3IE_BIT)
306
+#define TIMER_DIER_CC2IE                (1U << TIMER_DIER_CC2IE_BIT)
307
+#define TIMER_DIER_CC1IE                (1U << TIMER_DIER_CC1IE_BIT)
308
+#define TIMER_DIER_UIE                  (1U << TIMER_DIER_UIE_BIT)
307 309
 
308 310
 /* Status register (SR) */
309 311
 
@@ -320,34 +322,38 @@ extern timer_dev *TIMER8;
320 322
 #define TIMER_SR_CC1IF_BIT              1
321 323
 #define TIMER_SR_UIF_BIT                0
322 324
 
323
-#define TIMER_SR_CC4OF                  BIT(TIMER_SR_CC4OF_BIT)
324
-#define TIMER_SR_CC3OF                  BIT(TIMER_SR_CC3OF_BIT)
325
-#define TIMER_SR_CC2OF                  BIT(TIMER_SR_CC2OF_BIT)
326
-#define TIMER_SR_CC1OF                  BIT(TIMER_SR_CC1OF_BIT)
327
-#define TIMER_SR_BIF                    BIT(TIMER_SR_BIF_BIT)
328
-#define TIMER_SR_TIF                    BIT(TIMER_SR_TIF_BIT)
329
-#define TIMER_SR_COMIF                  BIT(TIMER_SR_COMIF_BIT)
330
-#define TIMER_SR_CC4IF                  BIT(TIMER_SR_CC4IF_BIT)
331
-#define TIMER_SR_CC3IF                  BIT(TIMER_SR_CC3IF_BIT)
332
-#define TIMER_SR_CC2IF                  BIT(TIMER_SR_CC2IF_BIT)
333
-#define TIMER_SR_CC1IF                  BIT(TIMER_SR_CC1IF_BIT)
334
-#define TIMER_SR_UIF                    BIT(TIMER_SR_UIF_BIT)
325
+#define TIMER_SR_CC4OF                  (1U << TIMER_SR_CC4OF_BIT)
326
+#define TIMER_SR_CC3OF                  (1U << TIMER_SR_CC3OF_BIT)
327
+#define TIMER_SR_CC2OF                  (1U << TIMER_SR_CC2OF_BIT)
328
+#define TIMER_SR_CC1OF                  (1U << TIMER_SR_CC1OF_BIT)
329
+#define TIMER_SR_BIF                    (1U << TIMER_SR_BIF_BIT)
330
+#define TIMER_SR_TIF                    (1U << TIMER_SR_TIF_BIT)
331
+#define TIMER_SR_COMIF                  (1U << TIMER_SR_COMIF_BIT)
332
+#define TIMER_SR_CC4IF                  (1U << TIMER_SR_CC4IF_BIT)
333
+#define TIMER_SR_CC3IF                  (1U << TIMER_SR_CC3IF_BIT)
334
+#define TIMER_SR_CC2IF                  (1U << TIMER_SR_CC2IF_BIT)
335
+#define TIMER_SR_CC1IF                  (1U << TIMER_SR_CC1IF_BIT)
336
+#define TIMER_SR_UIF                    (1U << TIMER_SR_UIF_BIT)
335 337
 
336 338
 /* Event generation register (EGR) */
337 339
 
340
+#define TIMER_EGR_BG_BIT                7
338 341
 #define TIMER_EGR_TG_BIT                6
342
+#define TIMER_EGR_COMG_BIT              5
339 343
 #define TIMER_EGR_CC4G_BIT              4
340 344
 #define TIMER_EGR_CC3G_BIT              3
341 345
 #define TIMER_EGR_CC2G_BIT              2
342 346
 #define TIMER_EGR_CC1G_BIT              1
343 347
 #define TIMER_EGR_UG_BIT                0
344 348
 
345
-#define TIMER_EGR_TG                    BIT(TIMER_EGR_TG_BIT)
346
-#define TIMER_EGR_CC4G                  BIT(TIMER_EGR_CC4G_BIT)
347
-#define TIMER_EGR_CC3G                  BIT(TIMER_EGR_CC3G_BIT)
348
-#define TIMER_EGR_CC2G                  BIT(TIMER_EGR_CC2G_BIT)
349
-#define TIMER_EGR_CC1G                  BIT(TIMER_EGR_CC1G_BIT)
350
-#define TIMER_EGR_UG                    BIT(TIMER_EGR_UG_BIT)
349
+#define TIMER_EGR_BG                    (1U << TIMER_EGR_BG_BIT)
350
+#define TIMER_EGR_TG                    (1U << TIMER_EGR_TG_BIT)
351
+#define TIMER_EGR_COMG                  (1U << TIMER_EGR_COMG_BIT)
352
+#define TIMER_EGR_CC4G                  (1U << TIMER_EGR_CC4G_BIT)
353
+#define TIMER_EGR_CC3G                  (1U << TIMER_EGR_CC3G_BIT)
354
+#define TIMER_EGR_CC2G                  (1U << TIMER_EGR_CC2G_BIT)
355
+#define TIMER_EGR_CC1G                  (1U << TIMER_EGR_CC1G_BIT)
356
+#define TIMER_EGR_UG                    (1U << TIMER_EGR_UG_BIT)
351 357
 
352 358
 /* Capture/compare mode registers, common values */
353 359
 
@@ -365,22 +371,22 @@ extern timer_dev *TIMER8;
365 371
 #define TIMER_CCMR1_OC1PE_BIT           3
366 372
 #define TIMER_CCMR1_OC1FE_BIT           2
367 373
 
368
-#define TIMER_CCMR1_OC2CE               BIT(TIMER_CCMR1_OC2CE_BIT)
374
+#define TIMER_CCMR1_OC2CE               (1U << TIMER_CCMR1_OC2CE_BIT)
369 375
 #define TIMER_CCMR1_OC2M                (0x3 << 12)
370 376
 #define TIMER_CCMR1_IC2F                (0xF << 12)
371
-#define TIMER_CCMR1_OC2PE               BIT(TIMER_CCMR1_OC2PE_BIT)
372
-#define TIMER_CCMR1_OC2FE               BIT(TIMER_CCMR1_OC2FE_BIT)
377
+#define TIMER_CCMR1_OC2PE               (1U << TIMER_CCMR1_OC2PE_BIT)
378
+#define TIMER_CCMR1_OC2FE               (1U << TIMER_CCMR1_OC2FE_BIT)
373 379
 #define TIMER_CCMR1_IC2PSC              (0x3 << 10)
374 380
 #define TIMER_CCMR1_CC2S                (0x3 << 8)
375 381
 #define TIMER_CCMR1_CC2S_OUTPUT         (TIMER_CCMR_CCS_OUTPUT << 8)
376 382
 #define TIMER_CCMR1_CC2S_INPUT_TI1      (TIMER_CCMR_CCS_INPUT_TI1 << 8)
377 383
 #define TIMER_CCMR1_CC2S_INPUT_TI2      (TIMER_CCMR_CCS_INPUT_TI2 << 8)
378 384
 #define TIMER_CCMR1_CC2S_INPUT_TRC      (TIMER_CCMR_CCS_INPUT_TRC << 8)
379
-#define TIMER_CCMR1_OC1CE               BIT(TIMER_CCMR1_OC1CE_BIT)
385
+#define TIMER_CCMR1_OC1CE               (1U << TIMER_CCMR1_OC1CE_BIT)
380 386
 #define TIMER_CCMR1_OC1M                (0x3 << 4)
381 387
 #define TIMER_CCMR1_IC1F                (0xF << 4)
382
-#define TIMER_CCMR1_OC1PE               BIT(TIMER_CCMR1_OC1PE_BIT)
383
-#define TIMER_CCMR1_OC1FE               BIT(TIMER_CCMR1_OC1FE_BIT)
388
+#define TIMER_CCMR1_OC1PE               (1U << TIMER_CCMR1_OC1PE_BIT)
389
+#define TIMER_CCMR1_OC1FE               (1U << TIMER_CCMR1_OC1FE_BIT)
384 390
 #define TIMER_CCMR1_IC1PSC              (0x3 << 2)
385 391
 #define TIMER_CCMR1_CC1S                0x3
386 392
 #define TIMER_CCMR1_CC1S_OUTPUT         TIMER_CCMR_CCS_OUTPUT
@@ -397,48 +403,60 @@ extern timer_dev *TIMER8;
397 403
 #define TIMER_CCMR2_OC3PE_BIT           3
398 404
 #define TIMER_CCMR2_OC3FE_BIT           2
399 405
 
400
-#define TIMER_CCMR2_OC4CE               BIT(TIMER_CCMR2_OC4CE_BIT)
406
+#define TIMER_CCMR2_OC4CE               (1U << TIMER_CCMR2_OC4CE_BIT)
401 407
 #define TIMER_CCMR2_OC4M                (0x3 << 12)
402
-#define TIMER_CCMR2_IC2F                (0xF << 12)
403
-#define TIMER_CCMR2_OC4PE               BIT(TIMER_CCMR2_OC4PE_BIT)
404
-#define TIMER_CCMR2_OC4FE               BIT(TIMER_CCMR2_OC4FE_BIT)
405
-#define TIMER_CCMR2_IC2PSC              (0x3 << 10)
408
+#define TIMER_CCMR2_IC4F                (0xF << 12)
409
+#define TIMER_CCMR2_OC4PE               (1U << TIMER_CCMR2_OC4PE_BIT)
410
+#define TIMER_CCMR2_OC4FE               (1U << TIMER_CCMR2_OC4FE_BIT)
411
+#define TIMER_CCMR2_IC4PSC              (0x3 << 10)
406 412
 #define TIMER_CCMR2_CC4S                (0x3 << 8)
407
-#define TIMER_CCMR1_CC4S_OUTPUT         (TIMER_CCMR_CCS_OUTPUT << 8)
408
-#define TIMER_CCMR1_CC4S_INPUT_TI1      (TIMER_CCMR_CCS_INPUT_TI1 << 8)
409
-#define TIMER_CCMR1_CC4S_INPUT_TI2      (TIMER_CCMR_CCS_INPUT_TI2 << 8)
410
-#define TIMER_CCMR1_CC4S_INPUT_TRC      (TIMER_CCMR_CCS_INPUT_TRC << 8)
411
-#define TIMER_CCMR2_OC3CE               BIT(TIMER_CCMR2_OC3CE_BIT)
413
+#define TIMER_CCMR2_CC4S_OUTPUT         (TIMER_CCMR_CCS_OUTPUT << 8)
414
+#define TIMER_CCMR2_CC4S_INPUT_TI1      (TIMER_CCMR_CCS_INPUT_TI1 << 8)
415
+#define TIMER_CCMR2_CC4S_INPUT_TI2      (TIMER_CCMR_CCS_INPUT_TI2 << 8)
416
+#define TIMER_CCMR2_CC4S_INPUT_TRC      (TIMER_CCMR_CCS_INPUT_TRC << 8)
417
+#define TIMER_CCMR2_OC3CE               (1U << TIMER_CCMR2_OC3CE_BIT)
412 418
 #define TIMER_CCMR2_OC3M                (0x3 << 4)
413
-#define TIMER_CCMR2_IC1F                (0xF << 4)
414
-#define TIMER_CCMR2_OC3PE               BIT(TIMER_CCMR2_OC3PE_BIT)
415
-#define TIMER_CCMR2_OC3FE               BIT(TIMER_CCMR2_OC3FE_BIT)
416
-#define TIMER_CCMR2_IC1PSC              (0x3 << 2)
419
+#define TIMER_CCMR2_IC3F                (0xF << 4)
420
+#define TIMER_CCMR2_OC3PE               (1U << TIMER_CCMR2_OC3PE_BIT)
421
+#define TIMER_CCMR2_OC3FE               (1U << TIMER_CCMR2_OC3FE_BIT)
422
+#define TIMER_CCMR2_IC3PSC              (0x3 << 2)
417 423
 #define TIMER_CCMR2_CC3S                0x3
418
-#define TIMER_CCMR1_CC3S_OUTPUT         TIMER_CCMR_CCS_OUTPUT
419
-#define TIMER_CCMR1_CC3S_INPUT_TI1      TIMER_CCMR_CCS_INPUT_TI1
420
-#define TIMER_CCMR1_CC3S_INPUT_TI2      TIMER_CCMR_CCS_INPUT_TI2
421
-#define TIMER_CCMR1_CC3S_INPUT_TRC      TIMER_CCMR_CCS_INPUT_TRC
424
+#define TIMER_CCMR2_CC3S_OUTPUT         TIMER_CCMR_CCS_OUTPUT
425
+#define TIMER_CCMR2_CC3S_INPUT_TI1      TIMER_CCMR_CCS_INPUT_TI1
426
+#define TIMER_CCMR2_CC3S_INPUT_TI2      TIMER_CCMR_CCS_INPUT_TI2
427
+#define TIMER_CCMR2_CC3S_INPUT_TRC      TIMER_CCMR_CCS_INPUT_TRC
422 428
 
423 429
 /* Capture/compare enable register (CCER) */
424 430
 
425 431
 #define TIMER_CCER_CC4P_BIT             13
426 432
 #define TIMER_CCER_CC4E_BIT             12
433
+#define TIMER_CCER_CC3NP_BIT            11
434
+#define TIMER_CCER_CC3NE_BIT            10
427 435
 #define TIMER_CCER_CC3P_BIT             9
428 436
 #define TIMER_CCER_CC3E_BIT             8
437
+#define TIMER_CCER_CC2NP_BIT            7
438
+#define TIMER_CCER_CC2NE_BIT            6
429 439
 #define TIMER_CCER_CC2P_BIT             5
430 440
 #define TIMER_CCER_CC2E_BIT             4
441
+#define TIMER_CCER_CC1NP_BIT            3
442
+#define TIMER_CCER_CC1NE_BIT            2
431 443
 #define TIMER_CCER_CC1P_BIT             1
432 444
 #define TIMER_CCER_CC1E_BIT             0
433 445
 
434
-#define TIMER_CCER_CC4P                 BIT(TIMER_CCER_CC4P_BIT)
435
-#define TIMER_CCER_CC4E                 BIT(TIMER_CCER_CC4E_BIT)
436
-#define TIMER_CCER_CC3P                 BIT(TIMER_CCER_CC3P_BIT)
437
-#define TIMER_CCER_CC3E                 BIT(TIMER_CCER_CC3E_BIT)
438
-#define TIMER_CCER_CC2P                 BIT(TIMER_CCER_CC2P_BIT)
439
-#define TIMER_CCER_CC2E                 BIT(TIMER_CCER_CC2E_BIT)
440
-#define TIMER_CCER_CC1P                 BIT(TIMER_CCER_CC1P_BIT)
441
-#define TIMER_CCER_CC1E                 BIT(TIMER_CCER_CC1E_BIT)
446
+#define TIMER_CCER_CC4P                 (1U << TIMER_CCER_CC4P_BIT)
447
+#define TIMER_CCER_CC4E                 (1U << TIMER_CCER_CC4E_BIT)
448
+#define TIMER_CCER_CC3NP                (1U << TIMER_CCER_CC3NP_BIT)
449
+#define TIMER_CCER_CC3NE                (1U << TIMER_CCER_CC3NE_BIT)
450
+#define TIMER_CCER_CC3P                 (1U << TIMER_CCER_CC3P_BIT)
451
+#define TIMER_CCER_CC3E                 (1U << TIMER_CCER_CC3E_BIT)
452
+#define TIMER_CCER_CC2NP                (1U << TIMER_CCER_CC2NP_BIT)
453
+#define TIMER_CCER_CC2NE                (1U << TIMER_CCER_CC2NE_BIT)
454
+#define TIMER_CCER_CC2P                 (1U << TIMER_CCER_CC2P_BIT)
455
+#define TIMER_CCER_CC2E                 (1U << TIMER_CCER_CC2E_BIT)
456
+#define TIMER_CCER_CC1NP                (1U << TIMER_CCER_CC1NP_BIT)
457
+#define TIMER_CCER_CC1NE                (1U << TIMER_CCER_CC1NE_BIT)
458
+#define TIMER_CCER_CC1P                 (1U << TIMER_CCER_CC1P_BIT)
459
+#define TIMER_CCER_CC1E                 (1U << TIMER_CCER_CC1E_BIT)
442 460
 
443 461
 /* Break and dead-time register (BDTR) */
444 462
 
@@ -449,12 +467,12 @@ extern timer_dev *TIMER8;
449 467
 #define TIMER_BDTR_OSSR_BIT             11
450 468
 #define TIMER_BDTR_OSSI_BIT             10
451 469
 
452
-#define TIMER_BDTR_MOE                  BIT(TIMER_BDTR_MOE_BIT)
453
-#define TIMER_BDTR_AOE                  BIT(TIMER_BDTR_AOE_BIT)
454
-#define TIMER_BDTR_BKP                  BIT(TIMER_BDTR_BKP_BIT)
455
-#define TIMER_BDTR_BKE                  BIT(TIMER_BDTR_BKE_BIT)
456
-#define TIMER_BDTR_OSSR                 BIT(TIMER_BDTR_OSSR_BIT)
457
-#define TIMER_BDTR_OSSI                 BIT(TIMER_BDTR_OSSI_BIT)
470
+#define TIMER_BDTR_MOE                  (1U << TIMER_BDTR_MOE_BIT)
471
+#define TIMER_BDTR_AOE                  (1U << TIMER_BDTR_AOE_BIT)
472
+#define TIMER_BDTR_BKP                  (1U << TIMER_BDTR_BKP_BIT)
473
+#define TIMER_BDTR_BKE                  (1U << TIMER_BDTR_BKE_BIT)
474
+#define TIMER_BDTR_OSSR                 (1U << TIMER_BDTR_OSSR_BIT)
475
+#define TIMER_BDTR_OSSI                 (1U << TIMER_BDTR_OSSI_BIT)
458 476
 #define TIMER_BDTR_LOCK                 (0x3 << 8)
459 477
 #define TIMER_BDTR_LOCK_OFF             (0x0 << 8)
460 478
 #define TIMER_BDTR_LOCK_LEVEL1          (0x1 << 8)
@@ -465,24 +483,24 @@ extern timer_dev *TIMER8;
465 483
 /* DMA control register (DCR) */
466 484
 
467 485
 #define TIMER_DCR_DBL                   (0x1F << 8)
468
-#define TIMER_DCR_DBL_1BYTE             (0x0 << 8)
469
-#define TIMER_DCR_DBL_2BYTE             (0x1 << 8)
470
-#define TIMER_DCR_DBL_3BYTE             (0x2 << 8)
471
-#define TIMER_DCR_DBL_4BYTE             (0x3 << 8)
472
-#define TIMER_DCR_DBL_5BYTE             (0x4 << 8)
473
-#define TIMER_DCR_DBL_6BYTE             (0x5 << 8)
474
-#define TIMER_DCR_DBL_7BYTE             (0x6 << 8)
475
-#define TIMER_DCR_DBL_8BYTE             (0x7 << 8)
476
-#define TIMER_DCR_DBL_9BYTE             (0x8 << 8)
477
-#define TIMER_DCR_DBL_10BYTE            (0x9 << 8)
478
-#define TIMER_DCR_DBL_11BYTE            (0xA << 8)
479
-#define TIMER_DCR_DBL_12BYTE            (0xB << 8)
480
-#define TIMER_DCR_DBL_13BYTE            (0xC << 8)
481
-#define TIMER_DCR_DBL_14BYTE            (0xD << 8)
482
-#define TIMER_DCR_DBL_15BYTE            (0xE << 8)
483
-#define TIMER_DCR_DBL_16BYTE            (0xF << 8)
484
-#define TIMER_DCR_DBL_17BYTE            (0x10 << 8)
485
-#define TIMER_DCR_DBL_18BYTE            (0x11 << 8)
486
+#define TIMER_DCR_DBL_1_XFER            (0x0 << 8)
487
+#define TIMER_DCR_DBL_2_XFER            (0x1 << 8)
488
+#define TIMER_DCR_DBL_3_XFER            (0x2 << 8)
489
+#define TIMER_DCR_DBL_4_XFER            (0x3 << 8)
490
+#define TIMER_DCR_DBL_5_XFER            (0x4 << 8)
491
+#define TIMER_DCR_DBL_6_XFER            (0x5 << 8)
492
+#define TIMER_DCR_DBL_7_XFER            (0x6 << 8)
493
+#define TIMER_DCR_DBL_8_XFER            (0x7 << 8)
494
+#define TIMER_DCR_DBL_9_XFER            (0x8 << 8)
495
+#define TIMER_DCR_DBL_10_XFER           (0x9 << 8)
496
+#define TIMER_DCR_DBL_11_XFER           (0xA << 8)
497
+#define TIMER_DCR_DBL_12_XFER           (0xB << 8)
498
+#define TIMER_DCR_DBL_13_XFER           (0xC << 8)
499
+#define TIMER_DCR_DBL_14_XFER           (0xD << 8)
500
+#define TIMER_DCR_DBL_15_XFER           (0xE << 8)
501
+#define TIMER_DCR_DBL_16_XFER           (0xF << 8)
502
+#define TIMER_DCR_DBL_17_XFER           (0x10 << 8)
503
+#define TIMER_DCR_DBL_18_XFER           (0x11 << 8)
486 504
 #define TIMER_DCR_DBA                   0x1F
487 505
 #define TIMER_DCR_DBA_CR1               0x0
488 506
 #define TIMER_DCR_DBA_CR2               0x1
@@ -510,27 +528,32 @@ extern timer_dev *TIMER8;
510 528
  */
511 529
 
512 530
 /**
513
- * Used to configure the behavior of a timer channel.  Note that not
514
- * all timers can be configured in every mode.
531
+ * @brief Used to configure the behavior of a timer channel.
532
+ *
533
+ * Be careful: not all timers can be configured in every mode.
515 534
  */
516
-/* TODO TIMER_PWM_CENTER_ALIGNED, TIMER_INPUT_CAPTURE, TIMER_ONE_PULSE */
517 535
 typedef enum timer_mode {
518
-    TIMER_DISABLED, /**< In this mode, the timer stops counting,
519
-                         channel interrupts are detached, and no state
520
-                         changes are output. */
521
-    TIMER_PWM, /**< PWM output mode. This is the default mode for pins
522
-                    after initialization. */
523
-    /* TIMER_PWM_CENTER_ALIGNED, /\**< Center-aligned PWM output mode. *\/ */
524
-    TIMER_OUTPUT_COMPARE, /**< In this mode, the timer counts from 0
525
-                               to its reload value repeatedly; every
526
-                               time the counter value reaches one of
527
-                               the channel compare values, the
528
-                               corresponding interrupt is fired. */
529
-    /* TIMER_INPUT_CAPTURE, /\**< In this mode, the timer can measure the */
530
-    /*                           pulse lengths of input signals. *\/ */
531
-    /* TIMER_ONE_PULSE /\**< In this mode, the timer can generate a single */
532
-    /*                      pulse on a GPIO pin for a specified amount of */
533
-    /*                      time. *\/ */
536
+    /**
537
+     * The timer stops counting, channel interrupts are detached, and
538
+     * no state changes are output. */
539
+    TIMER_DISABLED,
540
+
541
+    /** PWM output. */
542
+    TIMER_PWM,
543
+
544
+    /* TIMER_PWM_CENTER_ALIGNED, TODO: Center-aligned PWM output mode. */
545
+
546
+    /**
547
+     * The timer counts from 0 to its reload value repeatedly; every
548
+     * time the counter value reaches one of the channel compare
549
+     * values, the corresponding interrupt is fired. */
550
+    TIMER_OUTPUT_COMPARE,
551
+
552
+    /* TIMER_INPUT_CAPTURE, TODO: In this mode, the timer can measure the
553
+     *                            pulse lengths of input signals */
554
+    /* TIMER_ONE_PULSE, TODO: In this mode, the timer can generate a single
555
+     *                        pulse on a GPIO pin for a specified amount of
556
+     *                        time. */
534 557
 } timer_mode;
535 558
 
536 559
 /** Timer channel numbers */
@@ -555,27 +578,26 @@ void timer_init(timer_dev *dev);
555 578
 void timer_disable(timer_dev *dev);
556 579
 void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode);
557 580
 void timer_foreach(void (*fn)(timer_dev*));
581
+int timer_has_cc_channel(timer_dev *dev, uint8 channel);
558 582
 
559 583
 /**
560 584
  * @brief Timer interrupt number.
561 585
  *
562
- * Not all timers support all of these values; see the descriptions
563
- * for each value.
586
+ * Not all timers support all of these values. All timers support
587
+ * TIMER_UPDATE_INTERRUPT. "General purpose" timers can be a special
588
+ * nuisance in this regard, as they individually support different
589
+ * subsets of the available interupts. Consult your target's reference
590
+ * manual for the details.
564 591
  */
565 592
 typedef enum timer_interrupt_id {
566
-    TIMER_UPDATE_INTERRUPT, /**< Update interrupt, available on all timers. */
567
-    TIMER_CC1_INTERRUPT, /**< Capture/compare 1 interrupt, available
568
-                              on general and advanced timers only. */
569
-    TIMER_CC2_INTERRUPT, /**< Capture/compare 2 interrupt, general and
570
-                              advanced timers only. */
571
-    TIMER_CC3_INTERRUPT, /**< Capture/compare 3 interrupt, general and
572
-                              advanced timers only. */
573
-    TIMER_CC4_INTERRUPT, /**< Capture/compare 4 interrupt, general and
574
-                              advanced timers only. */
575
-    TIMER_COM_INTERRUPT, /**< COM interrupt, advanced timers only */
576
-    TIMER_TRG_INTERRUPT, /**< Trigger interrupt, general and advanced
577
-                              timers only */
578
-    TIMER_BREAK_INTERRUPT /**< Break interrupt, advanced timers only. */
593
+    TIMER_UPDATE_INTERRUPT,     /**< Update interrupt. */
594
+    TIMER_CC1_INTERRUPT,        /**< Capture/compare 1 interrupt. */
595
+    TIMER_CC2_INTERRUPT,        /**< Capture/compare 2 interrupt. */
596
+    TIMER_CC3_INTERRUPT,        /**< Capture/compare 3 interrupt. */
597
+    TIMER_CC4_INTERRUPT,        /**< Capture/compare 4 interrupt. */
598
+    TIMER_COM_INTERRUPT,        /**< COM interrupt. */
599
+    TIMER_TRG_INTERRUPT,        /**< Trigger interrupt. */
600
+    TIMER_BREAK_INTERRUPT,      /**< Break interrupt. */
579 601
 } timer_interrupt_id;
580 602
 
581 603
 void timer_attach_interrupt(timer_dev *dev,
@@ -843,18 +865,19 @@ static inline void timer_cc_set_pol(timer_dev *dev, uint8 channel, uint8 pol) {
843 865
 /**
844 866
  * @brief Get a timer's DMA burst length.
845 867
  * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL.
846
- * @return Number of bytes to be transferred per DMA request, from 1 to 18.
868
+ * @return Number of transfers per read or write to timer DMA register,
869
+ *         from 1 to 18.
847 870
  */
848 871
 static inline uint8 timer_dma_get_burst_len(timer_dev *dev) {
849 872
     uint32 dbl = ((dev->regs).gen->DCR & TIMER_DCR_DBL) >> 8;
850
-    return dbl + 1;             /* 0 means 1 byte, etc. */
873
+    return dbl + 1;             /* 0 means 1 transfer, etc. */
851 874
 }
852 875
 
853 876
 /**
854 877
  * @brief Set a timer's DMA burst length.
855 878
  * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL.
856
- * @param length DMA burst length; i.e., number of bytes to transfer
857
- *               per DMA request, from 1 to 18.
879
+ * @param length DMA burst length; i.e., number of DMA transfers per
880
+ *               read/write to timer DMA register, from 1 to 18.
858 881
  */
859 882
 static inline void timer_dma_set_burst_len(timer_dev *dev, uint8 length) {
860 883
     uint32 tmp = (dev->regs).gen->DCR;
@@ -869,47 +892,52 @@ static inline void timer_dma_set_burst_len(timer_dev *dev, uint8 length) {
869 892
  * Defines the base address for DMA transfers.
870 893
  */
871 894
 typedef enum timer_dma_base_addr {
872
-    TIMER_DMA_BASE_CR1 = TIMER_DCR_DBA_CR1, /**< Base is control register 1 */
873
-    TIMER_DMA_BASE_CR2 = TIMER_DCR_DBA_CR2, /**< Base is control register 2 */
874
-    TIMER_DMA_BASE_SMCR = TIMER_DCR_DBA_SMCR, /**< Base is slave mode
875
-                                                   control register */
876
-    TIMER_DMA_BASE_DIER = TIMER_DCR_DBA_DIER, /**< Base is DMA interrupt enable
877
-                                                   register */
878
-    TIMER_DMA_BASE_SR = TIMER_DCR_DBA_SR, /**< Base is status register */
879
-    TIMER_DMA_BASE_EGR = TIMER_DCR_DBA_EGR, /**< Base is event generation
880
-                                                 register */
881
-    TIMER_DMA_BASE_CCMR1 = TIMER_DCR_DBA_CCMR1, /**< Base is capture/compare
882
-                                                     mode register 1 */
883
-    TIMER_DMA_BASE_CCMR2 = TIMER_DCR_DBA_CCMR2, /**< Base is capture/compare
884
-                                                     mode register 2 */
885
-    TIMER_DMA_BASE_CCER = TIMER_DCR_DBA_CCER,   /**< Base is capture/compare
886
-                                                     enable register */
887
-    TIMER_DMA_BASE_CNT = TIMER_DCR_DBA_CNT,     /**< Base is counter */
888
-    TIMER_DMA_BASE_PSC = TIMER_DCR_DBA_PSC,     /**< Base is prescaler */
889
-    TIMER_DMA_BASE_ARR = TIMER_DCR_DBA_ARR,     /**< Base is auto-reload
890
-                                                     register */
891
-    TIMER_DMA_BASE_RCR = TIMER_DCR_DBA_RCR,     /**< Base is repetition
892
-                                                     counter register */
893
-    TIMER_DMA_BASE_CCR1 = TIMER_DCR_DBA_CCR1,   /**< Base is capture/compare
894
-                                                     register 1 */
895
-    TIMER_DMA_BASE_CCR2 = TIMER_DCR_DBA_CCR2,   /**< Base is capture/compare
896
-                                                     register 2 */
897
-    TIMER_DMA_BASE_CCR3 = TIMER_DCR_DBA_CCR3,   /**< Base is capture/compare
898
-                                                     register 3 */
899
-    TIMER_DMA_BASE_CCR4 = TIMER_DCR_DBA_CCR4,   /**< Base is capture/compare
900
-                                                     register 4 */
901
-    TIMER_DMA_BASE_BDTR = TIMER_DCR_DBA_BDTR,   /**< Base is break and
902
-                                                     dead-time register */
903
-    TIMER_DMA_BASE_DCR = TIMER_DCR_DBA_DCR,     /**< Base is DMA control
904
-                                                     register */
905
-    TIMER_DMA_BASE_DMAR = TIMER_DCR_DBA_DMAR    /**< Base is DMA address for
906
-                                                     full transfer */
895
+    /** Base is control register 1 */
896
+    TIMER_DMA_BASE_CR1 = TIMER_DCR_DBA_CR1,
897
+    /** Base is control register 2 */
898
+    TIMER_DMA_BASE_CR2 = TIMER_DCR_DBA_CR2,
899
+    /** Base is slave mode control register */
900
+    TIMER_DMA_BASE_SMCR = TIMER_DCR_DBA_SMCR,
901
+    /** Base is DMA interrupt enable register */
902
+    TIMER_DMA_BASE_DIER  = TIMER_DCR_DBA_DIER,
903
+    /** Base is status register */
904
+    TIMER_DMA_BASE_SR = TIMER_DCR_DBA_SR,
905
+    /** Base is event generation register */
906
+    TIMER_DMA_BASE_EGR = TIMER_DCR_DBA_EGR,
907
+    /** Base is capture/compare mode register 1 */
908
+    TIMER_DMA_BASE_CCMR1 = TIMER_DCR_DBA_CCMR1,
909
+    /** Base is capture/compare mode register 2 */
910
+    TIMER_DMA_BASE_CCMR2 = TIMER_DCR_DBA_CCMR2,
911
+    /** Base is capture/compare enable register */
912
+    TIMER_DMA_BASE_CCER = TIMER_DCR_DBA_CCER,
913
+    /** Base is counter */
914
+    TIMER_DMA_BASE_CNT = TIMER_DCR_DBA_CNT,
915
+    /** Base is prescaler */
916
+    TIMER_DMA_BASE_PSC = TIMER_DCR_DBA_PSC,
917
+    /** Base is auto-reload register */
918
+    TIMER_DMA_BASE_ARR = TIMER_DCR_DBA_ARR,
919
+    /** Base is repetition counter register */
920
+    TIMER_DMA_BASE_RCR = TIMER_DCR_DBA_RCR,
921
+    /** Base is capture/compare register 1 */
922
+    TIMER_DMA_BASE_CCR1 = TIMER_DCR_DBA_CCR1,
923
+    /** Base is capture/compare register 2 */
924
+    TIMER_DMA_BASE_CCR2 = TIMER_DCR_DBA_CCR2,
925
+    /** Base is capture/compare register 3 */
926
+    TIMER_DMA_BASE_CCR3 = TIMER_DCR_DBA_CCR3,
927
+    /** Base is capture/compare register 4 */
928
+    TIMER_DMA_BASE_CCR4 = TIMER_DCR_DBA_CCR4,
929
+    /** Base is break and dead-time register */
930
+    TIMER_DMA_BASE_BDTR = TIMER_DCR_DBA_BDTR,
931
+    /** Base is DMA control register */
932
+    TIMER_DMA_BASE_DCR = TIMER_DCR_DBA_DCR,
933
+    /** Base is DMA address for full transfer */
934
+    TIMER_DMA_BASE_DMAR = TIMER_DCR_DBA_DMAR,
907 935
 } timer_dma_base_addr;
908 936
 
909 937
 /**
910 938
  * @brief Get the timer's DMA base address.
911 939
  *
912
- * Some restrictions apply; see ST RM0008.
940
+ * Some restrictions apply; see the reference manual for your chip.
913 941
  *
914 942
  * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL.
915 943
  * @return DMA base address
@@ -922,7 +950,7 @@ static inline timer_dma_base_addr timer_dma_get_base_addr(timer_dev *dev) {
922 950
 /**
923 951
  * @brief Set the timer's DMA base address.
924 952
  *
925
- * Some restrictions apply; see ST RM0008.
953
+ * Some restrictions apply; see the reference manual for your chip.
926 954
  *
927 955
  * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL.
928 956
  * @param dma_base DMA base address.
@@ -939,35 +967,38 @@ static inline void timer_dma_set_base_addr(timer_dev *dev,
939 967
  * Timer output compare modes.
940 968
  */
941 969
 typedef enum timer_oc_mode {
942
-    TIMER_OC_MODE_FROZEN = 0 << 4, /**< Frozen: comparison between output
943
-                                      compare register and counter has no
944
-                                      effect on the outputs. */
945
-    TIMER_OC_MODE_ACTIVE_ON_MATCH = 1 << 4, /**< OCxREF signal is forced
946
-                                               high when the count matches
947
-                                               the channel capture/compare
948
-                                               register. */
949
-    TIMER_OC_MODE_INACTIVE_ON_MATCH = 2 << 4, /**< OCxREF signal is forced
950
-                                                 low when the counter matches
951
-                                                 the channel capture/compare
952
-                                                 register. */
953
-    TIMER_OC_MODE_TOGGLE = 3 << 4, /**< OCxREF toggles when counter
954
-                                      matches the cannel capture/compare
955
-                                      register. */
956
-    TIMER_OC_MODE_FORCE_INACTIVE = 4 << 4, /**< OCxREF is forced low. */
957
-    TIMER_OC_MODE_FORCE_ACTIVE = 5 << 4, /**< OCxREF is forced high. */
958
-    TIMER_OC_MODE_PWM_1 = 6 << 4, /**< PWM mode 1.  In upcounting, channel is
959
-                                     active as long as count is less than
960
-                                     channel capture/compare register, else
961
-                                     inactive.  In downcounting, channel is
962
-                                     inactive as long as count exceeds
963
-                                     capture/compare register, else
964
-                                     active. */
965
-    TIMER_OC_MODE_PWM_2 = 7 << 4  /**< PWM mode 2. In upcounting, channel is
966
-                                     inactive as long as count is less than
967
-                                     capture/compare register, else active.
968
-                                     In downcounting, channel is active as
969
-                                     long as count exceeds capture/compare
970
-                                     register, else inactive. */
970
+    /**
971
+     * Frozen: comparison between output compare register and counter
972
+     * has no effect on the outputs. */
973
+    TIMER_OC_MODE_FROZEN = 0 << 4,
974
+    /**
975
+     * OCxREF signal is forced high when the count matches the channel
976
+     * capture/compare register. */
977
+    TIMER_OC_MODE_ACTIVE_ON_MATCH = 1 << 4,
978
+    /**
979
+     * OCxREF signal is forced low when the counter matches the
980
+     * channel capture/compare register. */
981
+    TIMER_OC_MODE_INACTIVE_ON_MATCH = 2 << 4,
982
+    /**
983
+     * OCxREF toggles when counter matches the channel capture/compare
984
+     * register. */
985
+    TIMER_OC_MODE_TOGGLE = 3 << 4,
986
+    /** OCxREF is forced low. */
987
+    TIMER_OC_MODE_FORCE_INACTIVE = 4 << 4,
988
+    /** OCxREF is forced high. */
989
+    TIMER_OC_MODE_FORCE_ACTIVE = 5 << 4,
990
+    /**
991
+     * PWM mode 1.  In upcounting, channel is active as long as count
992
+     * is less than channel capture/compare register, else inactive.
993
+     * In downcounting, channel is inactive as long as count exceeds
994
+     * capture/compare register, else active. */
995
+    TIMER_OC_MODE_PWM_1 = 6 << 4,
996
+    /**
997
+     * PWM mode 2. In upcounting, channel is inactive as long as count
998
+     * is less than capture/compare register, else active.  In
999
+     * downcounting, channel is active as long as count exceeds
1000
+     * capture/compare register, else inactive. */
1001
+    TIMER_OC_MODE_PWM_2 = 7 << 4,
971 1002
 } timer_oc_mode;
972 1003
 
973 1004
 /**
@@ -975,9 +1006,9 @@ typedef enum timer_oc_mode {
975 1006
  * @see timer_oc_set_mode()
976 1007
  */
977 1008
 typedef enum timer_oc_mode_flags {
978
-    TIMER_OC_CE = BIT(7),       /**< Output compare clear enable. */
979
-    TIMER_OC_PE = BIT(3),       /**< Output compare preload enable. */
980
-    TIMER_OC_FE = BIT(2)        /**< Output compare fast enable. */
1009
+    TIMER_OC_CE = 1U << 7,       /**< Output compare clear enable. */
1010
+    TIMER_OC_PE = 1U << 3,       /**< Output compare preload enable. */
1011
+    TIMER_OC_FE = 1U << 2,       /**< Output compare fast enable. */
981 1012
 } timer_oc_mode_flags;
982 1013
 
983 1014
 /**
@@ -1005,6 +1036,73 @@ static inline void timer_oc_set_mode(timer_dev *dev,
1005 1036
     *ccmr = tmp;
1006 1037
 }
1007 1038
 
1039
+/*
1040
+ * Old, erroneous bit definitions from previous releases, kept for
1041
+ * backwards compatibility:
1042
+ */
1043
+
1044
+/** Deprecated. Use TIMER_CCMR1_CC4S_OUTPUT instead. */
1045
+#define TIMER_CCMR1_CC4S_OUTPUT    TIMER_CCMR2_CC4S_OUTPUT
1046
+/** Deprecated. Use TIMER_CCMR1_CC4S_INPUT_TI1 instead. */
1047
+#define TIMER_CCMR1_CC4S_INPUT_TI1 TIMER_CCMR2_CC4S_INPUT_TI1
1048
+/** Deprecated. Use TIMER_CCMR1_CC4S_INPUT_TI2 instead. */
1049
+#define TIMER_CCMR1_CC4S_INPUT_TI2 TIMER_CCMR2_CC4S_INPUT_TI2
1050
+/** Deprecated. Use TIMER_CCMR1_CC4S_INPUT_TRC instead. */
1051
+#define TIMER_CCMR1_CC4S_INPUT_TRC TIMER_CCMR2_CC4S_INPUT_TRC
1052
+/** Deprecated. Use TIMER_CCMR2_IC4F instead. */
1053
+#define TIMER_CCMR2_IC2F           TIMER_CCMR2_IC4F
1054
+/** Deprecated. Use TIMER_CCMR2_IC4PSC instead. */
1055
+#define TIMER_CCMR2_IC2PSC         TIMER_CCMR2_IC4PSC
1056
+/** Deprecated. Use TIMER_CCMR2_IC3F instead. */
1057
+#define TIMER_CCMR2_IC1F           TIMER_CCMR2_IC3F
1058
+/** Deprecated. Use TIMER_CCMR2_IC3PSC instead. */
1059
+#define TIMER_CCMR2_IC1PSC         TIMER_CCMR2_IC3PSC
1060
+/** Deprecated. Use TIMER_CCMR1_CC3S_OUTPUT instead. */
1061
+#define TIMER_CCMR1_CC3S_OUTPUT    TIMER_CCMR2_CC3S_OUTPUT
1062
+/** Deprecated. Use TIMER_CCMR1_CC3S_INPUT_TI1 instead. */
1063
+#define TIMER_CCMR1_CC3S_INPUT_TI1 TIMER_CCMR2_CC3S_INPUT_TI1
1064
+/** Deprecated. Use TIMER_CCMR1_CC3S_INPUT_TI2 instead. */
1065
+#define TIMER_CCMR1_CC3S_INPUT_TI2 TIMER_CCMR2_CC3S_INPUT_TI2
1066
+/** Deprecated. Use TIMER_CCMR1_CC3S_INPUT_TRC instead. */
1067
+#define TIMER_CCMR1_CC3S_INPUT_TRC TIMER_CCMR2_CC3S_INPUT_TRC
1068
+
1069
+/** Deprecated. Use TIMER_DCR_DBL_1_XFER instead. */
1070
+#define TIMER_DCR_DBL_1BYTE  TIMER_DCR_DBL_1_XFER
1071
+/** Deprecated. Use TIMER_DCR_DBL_2_XFER instead. */
1072
+#define TIMER_DCR_DBL_2BYTE  TIMER_DCR_DBL_2_XFER
1073
+/** Deprecated. Use TIMER_DCR_DBL_3_XFER instead. */
1074
+#define TIMER_DCR_DBL_3BYTE  TIMER_DCR_DBL_3_XFER
1075
+/** Deprecated. Use TIMER_DCR_DBL_4_XFER instead. */
1076
+#define TIMER_DCR_DBL_4BYTE  TIMER_DCR_DBL_4_XFER
1077
+/** Deprecated. Use TIMER_DCR_DBL_5_XFER instead. */
1078
+#define TIMER_DCR_DBL_5BYTE  TIMER_DCR_DBL_5_XFER
1079
+/** Deprecated. Use TIMER_DCR_DBL_6_XFER instead. */
1080
+#define TIMER_DCR_DBL_6BYTE  TIMER_DCR_DBL_6_XFER
1081
+/** Deprecated. Use TIMER_DCR_DBL_7_XFER instead. */
1082
+#define TIMER_DCR_DBL_7BYTE  TIMER_DCR_DBL_7_XFER
1083
+/** Deprecated. Use TIMER_DCR_DBL_8_XFER instead. */
1084
+#define TIMER_DCR_DBL_8BYTE  TIMER_DCR_DBL_8_XFER
1085
+/** Deprecated. Use TIMER_DCR_DBL_9_XFER instead. */
1086
+#define TIMER_DCR_DBL_9BYTE  TIMER_DCR_DBL_9_XFER
1087
+/** Deprecated. Use TIMER_DCR_DBL_10_XFER instead. */
1088
+#define TIMER_DCR_DBL_10BYTE TIMER_DCR_DBL_10_XFER
1089
+/** Deprecated. Use TIMER_DCR_DBL_11_XFER instead. */
1090
+#define TIMER_DCR_DBL_11BYTE TIMER_DCR_DBL_11_XFER
1091
+/** Deprecated. Use TIMER_DCR_DBL_12_XFER instead. */
1092
+#define TIMER_DCR_DBL_12BYTE TIMER_DCR_DBL_12_XFER
1093
+/** Deprecated. Use TIMER_DCR_DBL_13_XFER instead. */
1094
+#define TIMER_DCR_DBL_13BYTE TIMER_DCR_DBL_13_XFER
1095
+/** Deprecated. Use TIMER_DCR_DBL_14_XFER instead. */
1096
+#define TIMER_DCR_DBL_14BYTE TIMER_DCR_DBL_14_XFER
1097
+/** Deprecated. Use TIMER_DCR_DBL_15_XFER instead. */
1098
+#define TIMER_DCR_DBL_15BYTE TIMER_DCR_DBL_15_XFER
1099
+/** Deprecated. Use TIMER_DCR_DBL_16_XFER instead. */
1100
+#define TIMER_DCR_DBL_16BYTE TIMER_DCR_DBL_16_XFER
1101
+/** Deprecated. Use TIMER_DCR_DBL_17_XFER instead. */
1102
+#define TIMER_DCR_DBL_17BYTE TIMER_DCR_DBL_17_XFER
1103
+/** Deprecated. Use TIMER_DCR_DBL_18_XFER instead. */
1104
+#define TIMER_DCR_DBL_18BYTE TIMER_DCR_DBL_18_XFER
1105
+
1008 1106
 #ifdef __cplusplus
1009 1107
 } // extern "C"
1010 1108
 #endif

libmaple/usart.h → libmaple/include/libmaple/usart.h 파일 보기

@@ -25,27 +25,28 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file usart.h
28
+ * @file libmaple/include/libmaple/usart.h
29 29
  * @author Marti Bolivar <mbolivar@leaflabs.com>,
30 30
  *         Perry Hung <perry@leaflabs.com>
31 31
  * @brief USART definitions and prototypes
32 32
  */
33 33
 
34
-#ifndef _USART_H_
35
-#define _USART_H_
36
-
37
-#include "libmaple_types.h"
38
-#include "util.h"
39
-#include "rcc.h"
40
-#include "nvic.h"
41
-#include "ring_buffer.h"
34
+#ifndef _LIBMAPLE_USART_H_
35
+#define _LIBMAPLE_USART_H_
42 36
 
43 37
 #ifdef __cplusplus
44 38
 extern "C"{
45 39
 #endif
46 40
 
41
+#include <libmaple/libmaple_types.h>
42
+#include <libmaple/util.h>
43
+#include <libmaple/rcc.h>
44
+#include <libmaple/nvic.h>
45
+#include <libmaple/ring_buffer.h>
46
+#include <series/usart.h>
47
+
47 48
 /*
48
- * Register maps and devices
49
+ * Register map (common across supported STM32 series).
49 50
  */
50 51
 
51 52
 /** USART register map type */
@@ -59,169 +60,315 @@ typedef struct usart_reg_map {
59 60
     __io uint32 GTPR;           /**< Guard time and prescaler register */
60 61
 } usart_reg_map;
61 62
 
62
-/** USART1 register map base pointer */
63
-#define USART1_BASE                     ((struct usart_reg_map*)0x40013800)
64
-/** USART2 register map base pointer */
65
-#define USART2_BASE                     ((struct usart_reg_map*)0x40004400)
66
-/** USART3 register map base pointer */
67
-#define USART3_BASE                     ((struct usart_reg_map*)0x40004800)
68
-#ifdef STM32_HIGH_DENSITY
69
-/** UART4 register map base pointer */
70
-#define UART4_BASE                      ((struct usart_reg_map*)0x40004C00)
71
-/** UART5 register map base pointer */
72
-#define UART5_BASE                      ((struct usart_reg_map*)0x40005000)
73
-#endif
74
-
75 63
 /*
76 64
  * Register bit definitions
77 65
  */
78 66
 
79 67
 /* Status register */
80 68
 
69
+/** Clear to send bit */
81 70
 #define USART_SR_CTS_BIT                9
71
+/** Line break detection bit */
82 72
 #define USART_SR_LBD_BIT                8
73
+/** Transmit data register empty bit */
83 74
 #define USART_SR_TXE_BIT                7
75
+/** Transmission complete bit */
84 76
 #define USART_SR_TC_BIT                 6
77
+/** Read data register not empty bit */
85 78
 #define USART_SR_RXNE_BIT               5
79
+/** IDLE line detected bit */
86 80
 #define USART_SR_IDLE_BIT               4
81
+/** Overrun error bit */
87 82
 #define USART_SR_ORE_BIT                3
83
+/** Noise error bit */
88 84
 #define USART_SR_NE_BIT                 2
85
+/**
86
+ * @brief Synonym for USART_SR_NE_BIT.
87
+ *
88
+ * Some series (e.g. STM32F2) use "NF" for "noise flag" instead of the
89
+ * original "NE" for "noise error". The meaning of the bit is
90
+ * unchanged, but the NF flag can be disabled when the line is
91
+ * noise-free.
92
+ *
93
+ * @see USART_SR_NE_BIT
94
+ */
95
+#define USART_SR_NF_BIT                 USART_SR_NE_BIT
96
+/** Framing error bit */
89 97
 #define USART_SR_FE_BIT                 1
98
+/** Parity error bit */
90 99
 #define USART_SR_PE_BIT                 0
91 100
 
101
+/** Clear to send mask */
92 102
 #define USART_SR_CTS                    BIT(USART_SR_CTS_BIT)
103
+/** Line break detected mask */
93 104
 #define USART_SR_LBD                    BIT(USART_SR_LBD_BIT)
105
+/** Transmit data register empty mask */
94 106
 #define USART_SR_TXE                    BIT(USART_SR_TXE_BIT)
107
+/** Transmission complete mask */
95 108
 #define USART_SR_TC                     BIT(USART_SR_TC_BIT)
109
+/** Read data register not empty mask */
96 110
 #define USART_SR_RXNE                   BIT(USART_SR_RXNE_BIT)
111
+/** IDLE line detected mask */
97 112
 #define USART_SR_IDLE                   BIT(USART_SR_IDLE_BIT)
113
+/** Overrun error mask */
98 114
 #define USART_SR_ORE                    BIT(USART_SR_ORE_BIT)
115
+/** Noise error mask */
99 116
 #define USART_SR_NE                     BIT(USART_SR_NE_BIT)
117
+/**
118
+ * @brief Synonym for USART_SR_NE.
119
+ * @see USART_SR_NF_BIT
120
+ */
121
+#define USART_SR_NF                     USART_SR_NE
122
+/** Framing error mask */
100 123
 #define USART_SR_FE                     BIT(USART_SR_FE_BIT)
124
+/** Parity error mask */
101 125
 #define USART_SR_PE                     BIT(USART_SR_PE_BIT)
102 126
 
103 127
 /* Data register */
104 128
 
129
+/** Data register data value mask */
105 130
 #define USART_DR_DR                     0xFF
106 131
 
107 132
 /* Baud rate register */
108 133
 
134
+/** Mantissa of USARTDIV mask */
109 135
 #define USART_BRR_DIV_MANTISSA          (0xFFF << 4)
136
+/** Fraction of USARTDIV mask */
110 137
 #define USART_BRR_DIV_FRACTION          0xF
111 138
 
112 139
 /* Control register 1 */
113 140
 
141
+/** USART enable bit */
114 142
 #define USART_CR1_UE_BIT                13
143
+/** Word length bit */
115 144
 #define USART_CR1_M_BIT                 12
145
+/** Wakeup method bit */
116 146
 #define USART_CR1_WAKE_BIT              11
147
+/** Parity control enable bit */
117 148
 #define USART_CR1_PCE_BIT               10
149
+/** Parity selection bit */
118 150
 #define USART_CR1_PS_BIT                9
151
+/** Parity error interrupt enable bit */
119 152
 #define USART_CR1_PEIE_BIT              8
153
+/** Transmit data regsiter not empty interrupt enable bit */
120 154
 #define USART_CR1_TXEIE_BIT             7
155
+/** Transmission complete interrupt enable bit */
121 156
 #define USART_CR1_TCIE_BIT              6
157
+/** RXNE interrupt enable bit */
122 158
 #define USART_CR1_RXNEIE_BIT            5
159
+/** IDLE interrupt enable bit */
123 160
 #define USART_CR1_IDLEIE_BIT            4
161
+/** Transmitter enable bit */
124 162
 #define USART_CR1_TE_BIT                3
163
+/** Receiver enable bit */
125 164
 #define USART_CR1_RE_BIT                2
165
+/** Receiver wakeup bit */
126 166
 #define USART_CR1_RWU_BIT               1
167
+/** Send break bit */
127 168
 #define USART_CR1_SBK_BIT               0
128 169
 
170
+/** USART enable mask */
129 171
 #define USART_CR1_UE                    BIT(USART_CR1_UE_BIT)
172
+/** Word length mask */
130 173
 #define USART_CR1_M                     BIT(USART_CR1_M_BIT)
174
+/** Word length: 1 start bit, 8 data bits, n stop bit */
175
+#define USART_CR1_M_8N1                 (0 << USART_CR1_M_BIT)
176
+/** Word length: 1 start bit, 9 data bits, n stop bit */
177
+#define USART_CR1_M_9N1                 (1 << USART_CR1_M_BIT)
178
+/** Wakeup method mask */
131 179
 #define USART_CR1_WAKE                  BIT(USART_CR1_WAKE_BIT)
180
+/** Wakeup on idle line */
132 181
 #define USART_CR1_WAKE_IDLE             (0 << USART_CR1_WAKE_BIT)
182
+/** Wakeup on address mark */
133 183
 #define USART_CR1_WAKE_ADDR             (1 << USART_CR1_WAKE_BIT)
184
+/** Parity control enable mask */
134 185
 #define USART_CR1_PCE                   BIT(USART_CR1_PCE_BIT)
186
+/** Parity selection mask */
135 187
 #define USART_CR1_PS                    BIT(USART_CR1_PS_BIT)
188
+/** Parity selection: even parity */
136 189
 #define USART_CR1_PS_EVEN               (0 << USART_CR1_PS_BIT)
190
+/** Parity selection: odd parity */
137 191
 #define USART_CR1_PS_ODD                (1 << USART_CR1_PS_BIT)
192
+/** Parity error interrupt enable mask */
138 193
 #define USART_CR1_PEIE                  BIT(USART_CR1_PEIE_BIT)
194
+/** Transmit data register empty interrupt enable mask */
139 195
 #define USART_CR1_TXEIE                 BIT(USART_CR1_TXEIE_BIT)
196
+/** Transmission complete interrupt enable mask */
140 197
 #define USART_CR1_TCIE                  BIT(USART_CR1_TCIE_BIT)
198
+/** RXNE interrupt enable mask */
141 199
 #define USART_CR1_RXNEIE                BIT(USART_CR1_RXNEIE_BIT)
200
+/** IDLE line interrupt enable mask */
142 201
 #define USART_CR1_IDLEIE                BIT(USART_CR1_IDLEIE_BIT)
202
+/** Transmitter enable mask */
143 203
 #define USART_CR1_TE                    BIT(USART_CR1_TE_BIT)
204
+/** Receiver enable mask */
144 205
 #define USART_CR1_RE                    BIT(USART_CR1_RE_BIT)
206
+/** Receiver wakeup mask */
145 207
 #define USART_CR1_RWU                   BIT(USART_CR1_RWU_BIT)
208
+/** Receiver wakeup: receiver in active mode */
146 209
 #define USART_CR1_RWU_ACTIVE            (0 << USART_CR1_RWU_BIT)
210
+/** Receiver wakeup: receiver in mute mode */
147 211
 #define USART_CR1_RWU_MUTE              (1 << USART_CR1_RWU_BIT)
212
+/** Send break */
148 213
 #define USART_CR1_SBK                   BIT(USART_CR1_SBK_BIT)
149 214
 
150 215
 /* Control register 2 */
151 216
 
217
+/** LIN mode enable bit */
152 218
 #define USART_CR2_LINEN_BIT             14
219
+/** Clock enable bit */
153 220
 #define USART_CR2_CLKEN_BIT             11
221
+/** Clock polarity bit */
154 222
 #define USART_CR2_CPOL_BIT              10
223
+/** Clock phase bit */
155 224
 #define USART_CR2_CPHA_BIT              9
225
+/** Last bit clock pulse bit */
156 226
 #define USART_CR2_LBCL_BIT              8
227
+/** LIN break detection interrupt enable bit */
157 228
 #define USART_CR2_LBDIE_BIT             6
229
+/** LIN break detection length bit */
158 230
 #define USART_CR2_LBDL_BIT              5
159 231
 
232
+/** LIN mode enable mask */
160 233
 #define USART_CR2_LINEN                 BIT(USART_CR2_LINEN_BIT)
234
+/** STOP bits mask */
161 235
 #define USART_CR2_STOP                  (0x3 << 12)
236
+/** STOP bits: 1 stop bit */
162 237
 #define USART_CR2_STOP_BITS_1           (0x0 << 12)
163
-/* Not on UART4, UART5 */
238
+/**
239
+ * @brief STOP bits: 0.5 stop bits
240
+ * Not available  on UART4, UART5. */
164 241
 #define USART_CR2_STOP_BITS_POINT_5     (0x1 << 12)
165
-/* Not on UART4, UART5 */
166
-#define USART_CR2_STOP_BITS_1_POINT_5   (0x3 << 12)
242
+/** STOP bits: 2 stop bits */
167 243
 #define USART_CR2_STOP_BITS_2           (0x2 << 12)
244
+/**
245
+ * @brief STOP bits: 1.5 stop bits
246
+ * Not available  on UART4, UART5. */
247
+#define USART_CR2_STOP_BITS_1_POINT_5   (0x3 << 12)
248
+/**
249
+ * @brief Clock enable.
250
+ * Not available on UART4, UART5 */
168 251
 #define USART_CR2_CLKEN                 BIT(USART_CR2_CLKEN_BIT)
169
-/* Not on UART4, UART5 */
252
+/**
253
+ * @brief Clock polarity mask.
254
+ * Not available on UART4, UART5 */
170 255
 #define USART_CR2_CPOL                  BIT(USART_CR2_CPOL_BIT)
256
+/** Clock polarity: low */
171 257
 #define USART_CR2_CPOL_LOW              (0x0 << USART_CR2_CLKEN_BIT)
258
+/** Clock polarity: high */
172 259
 #define USART_CR2_CPOL_HIGH             (0x1 << USART_CR2_CLKEN_BIT)
173
-/* Not on UART4, UART5 */
260
+/**
261
+ * @brief Clock phase mask.
262
+ * Not available on UART4, UART5 */
174 263
 #define USART_CR2_CPHA                  BIT(USART_CR2_CPHA_BIT)
264
+/**
265
+ * @brief Clock phase: first
266
+ * First clock transition is the first data capture edge. */
175 267
 #define USART_CR2_CPHA_FIRST            (0x0 << USART_CR2_CPHA_BIT)
268
+/**
269
+ * @brief Clock phase: second
270
+ * Second clock transition is the first data capture edge. */
176 271
 #define USART_CR2_CPHA_SECOND           (0x1 << USART_CR2_CPHA_BIT)
177
-/* Not on UART4, UART5 */
272
+/**
273
+ * @brief Last bit clock pulse mask.
274
+ *
275
+ * When set, the last bit transmitted causes a clock pulse in
276
+ * synchronous mode.
277
+ *
278
+ * Not available on UART4, UART5 */
178 279
 #define USART_CR2_LBCL                  BIT(USART_CR2_LBCL_BIT)
280
+/** LIN break detection interrupt enable mask. */
179 281
 #define USART_CR2_LBDIE                 BIT(USART_CR2_LBDIE_BIT)
282
+/** LIN break detection length. */
180 283
 #define USART_CR2_LBDL                  BIT(USART_CR2_LBDL_BIT)
284
+/** LIN break detection length: 10 bits */
181 285
 #define USART_CR2_LBDL_10_BIT           (0 << USART_CR2_LBDL_BIT)
286
+/** LIN break detection length: 11 bits */
182 287
 #define USART_CR2_LBDL_11_BIT           (1 << USART_CR2_LBDL_BIT)
288
+/**
289
+ * @brief Address of the USART node
290
+ * This is useful during multiprocessor communication. */
183 291
 #define USART_CR2_ADD                   0xF
184 292
 
185 293
 /* Control register 3 */
186 294
 
295
+/** Clear to send interrupt enable bit */
187 296
 #define USART_CR3_CTSIE_BIT             10
297
+/** Clear to send enable bit */
188 298
 #define USART_CR3_CTSE_BIT              9
299
+/** Ready to send enable bit */
189 300
 #define USART_CR3_RTSE_BIT              8
301
+/** DMA enable transmitter bit */
190 302
 #define USART_CR3_DMAT_BIT              7
303
+/** DMA enable receiver bit */
191 304
 #define USART_CR3_DMAR_BIT              6
305
+/** Smartcard mode enable bit */
192 306
 #define USART_CR3_SCEN_BIT              5
307
+/** Smartcard NACK enable bit */
193 308
 #define USART_CR3_NACK_BIT              4
309
+/** Half-duplex selection bit */
194 310
 #define USART_CR3_HDSEL_BIT             3
311
+/** IrDA low power bit */
195 312
 #define USART_CR3_IRLP_BIT              2
313
+/** IrDA mode enable bit */
196 314
 #define USART_CR3_IREN_BIT              1
315
+/** Error interrupt enable bit */
197 316
 #define USART_CR3_EIE_BIT               0
198 317
 
199
-/* Not on UART4, UART5 */
318
+/**
319
+ * @brief Clear to send interrupt enable
320
+ * Not available on UART4, UART5. */
200 321
 #define USART_CR3_CTSIE                 BIT(USART_CR3_CTSIE_BIT)
201
-/* Not on UART4, UART5 */
322
+/**
323
+ * @brief Clear to send enable
324
+ * Not available on UART4, UART5. */
202 325
 #define USART_CR3_CTSE                  BIT(USART_CR3_CTSE_BIT)
203
-/* Not on UART4, UART5 */
326
+/**
327
+ * @brief Ready to send enable
328
+ * Not available on UART4, UART5. */
204 329
 #define USART_CR3_RTSE                  BIT(USART_CR3_RTSE_BIT)
205
-/* Not on UART5 */
330
+/**
331
+ * @brief DMA enable transmitter
332
+ * Not available on UART5. */
206 333
 #define USART_CR3_DMAT                  BIT(USART_CR3_DMAT_BIT)
207
-/* Not on UART5 */
334
+/**
335
+ * @brief DMA enable receiver
336
+ * Not available on UART5. */
208 337
 #define USART_CR3_DMAR                  BIT(USART_CR3_DMAR_BIT)
209
-/* Not on UART4, UART5 */
338
+/**
339
+ * @brief Smartcard mode enable
340
+ * Not available on UART4, UART5. */
210 341
 #define USART_CR3_SCEN                  BIT(USART_CR3_SCEN_BIT)
211
-/* Not on UART4, UART5 */
342
+/**
343
+ * @brief Smartcard NACK enable
344
+ * Not available on UART4, UART5. */
212 345
 #define USART_CR3_NACK                  BIT(USART_CR3_NACK_BIT)
346
+/**
347
+ * @brief Half-duplex selection
348
+ * When set, single-wire half duplex mode is selected.
349
+ */
213 350
 #define USART_CR3_HDSEL                 BIT(USART_CR3_HDSEL_BIT)
351
+/** IrDA low power mode */
214 352
 #define USART_CR3_IRLP                  BIT(USART_CR3_IRLP_BIT)
215
-#define USART_CR3_IRLP_NORMAL           (0 << USART_CR3_IRLP_BIT)
216
-#define USART_CR3_IRLP_LOW_POWER        (1 << USART_CR3_IRLP_BIT)
353
+/** IrDA mode: normal */
354
+#define USART_CR3_IRLP_NORMAL           (0U << USART_CR3_IRLP_BIT)
355
+/** IrDA mode: low power */
356
+#define USART_CR3_IRLP_LOW_POWER        (1U << USART_CR3_IRLP_BIT)
357
+/** IrDA mode enable */
217 358
 #define USART_CR3_IREN                  BIT(USART_CR3_IREN_BIT)
359
+/** Error interrupt enable */
218 360
 #define USART_CR3_EIE                   BIT(USART_CR3_EIE_BIT)
219 361
 
220 362
 /* Guard time and prescaler register */
221 363
 
222
-/* Not on UART4, UART5 */
364
+/**
365
+ * @brief Guard time value mask
366
+ * Used in Smartcard mode. Not available on UART4, UART5. */
223 367
 #define USART_GTPR_GT                   (0xFF << 8)
224
-/* Not on UART4, UART5 */
368
+/**
369
+ * @brief Prescaler value mask
370
+ * Restrictions on this value apply, depending on the USART mode. Not
371
+ * available on UART4, UART5. */
225 372
 #define USART_GTPR_PSC                  0xFF
226 373
 
227 374
 /*
@@ -236,7 +383,8 @@ typedef struct usart_reg_map {
236 383
 typedef struct usart_dev {
237 384
     usart_reg_map *regs;             /**< Register map */
238 385
     ring_buffer *rb;                 /**< RX ring buffer */
239
-    uint32 max_baud;                 /**< Maximum baud */
386
+    uint32 max_baud;                 /**< @brief Deprecated.
387
+                                      * Maximum baud rate. */
240 388
     uint8 rx_buf[USART_RX_BUF_SIZE]; /**< @brief Deprecated.
241 389
                                       * Actual RX buffer used by rb.
242 390
                                       * This field will be removed in
@@ -245,16 +393,27 @@ typedef struct usart_dev {
245 393
     nvic_irq_num irq_num;            /**< USART NVIC interrupt */
246 394
 } usart_dev;
247 395
 
248
-extern usart_dev *USART1;
249
-extern usart_dev *USART2;
250
-extern usart_dev *USART3;
251
-#ifdef STM32_HIGH_DENSITY
252
-extern usart_dev *UART4;
253
-extern usart_dev *UART5;
254
-#endif
255
-
256 396
 void usart_init(usart_dev *dev);
397
+
398
+struct gpio_dev;                /* forward declaration */
399
+/* FIXME [PRE 0.0.13] decide if flags are necessary */
400
+/**
401
+ * @brief Configure GPIOs for use as USART TX/RX.
402
+ * @param udev USART device to use
403
+ * @param rx_dev RX pin gpio_dev
404
+ * @param rx     RX pin bit on rx_dev
405
+ * @param tx_dev TX pin gpio_dev
406
+ * @param tx     TX pin bit on tx_dev
407
+ * @param flags  Currently ignored
408
+ */
409
+extern void usart_config_gpios_async(usart_dev *udev,
410
+                                     struct gpio_dev *rx_dev, uint8 rx,
411
+                                     struct gpio_dev *tx_dev, uint8 tx,
412
+                                     unsigned flags);
413
+
414
+#define USART_USE_PCLK 0
257 415
 void usart_set_baud_rate(usart_dev *dev, uint32 clock_speed, uint32 baud);
416
+
258 417
 void usart_enable(usart_dev *dev);
259 418
 void usart_disable(usart_dev *dev);
260 419
 void usart_foreach(void (*fn)(usart_dev *dev));
@@ -333,4 +492,4 @@ static inline void usart_reset_rx(usart_dev *dev) {
333 492
 } // extern "C"
334 493
 #endif
335 494
 
336
-#endif // _USART_H_
495
+#endif

libmaple/usb.h → libmaple/include/libmaple/usb.h 파일 보기

@@ -1,7 +1,7 @@
1 1
 /******************************************************************************
2 2
  * The MIT License
3 3
  *
4
- * Copyright (c) 2010 LeafLabs LLC.
4
+ * Copyright (c) 2010, 2011 LeafLabs LLC.
5 5
  *
6 6
  * Permission is hereby granted, free of charge, to any person
7 7
  * obtaining a copy of this software and associated documentation
@@ -28,16 +28,16 @@
28 28
  * NOTE: This API is _unstable_ and will change drastically over time.
29 29
  */
30 30
 
31
-#ifndef _USB_H_
32
-#define _USB_H_
33
-
34
-#include "libmaple_types.h"
35
-#include "rcc.h"
31
+#ifndef _LIBMAPLE_USB_H_
32
+#define _LIBMAPLE_USB_H_
36 33
 
37 34
 #ifdef __cplusplus
38 35
 extern "C" {
39 36
 #endif
40 37
 
38
+#include <libmaple/libmaple_types.h>
39
+#include <libmaple/rcc.h>
40
+
41 41
 #ifndef USB_ISR_MSK
42 42
 /* Handle CTRM, WKUPM, SUSPM, ERRM, SOFM, ESOFM, RESETM */
43 43
 #define USB_ISR_MSK 0xBF00

libmaple/usb/usb_cdcacm.h → libmaple/include/libmaple/usb_cdcacm.h 파일 보기

@@ -25,15 +25,15 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file usb_cdcacm.h
28
+ * @file libmaple/include/libmaple/usb_cdcacm.h
29 29
  * @brief USB CDC ACM (virtual serial terminal) support
30 30
  */
31 31
 
32
-#ifndef _USB_CDCACM_H_
33
-#define _USB_CDCACM_H_
32
+#ifndef _LIBMAPLE_USB_CDCACM_H_
33
+#define _LIBMAPLE_USB_CDCACM_H_
34 34
 
35
-#include "libmaple_types.h"
36
-#include "gpio.h"
35
+#include <libmaple/libmaple_types.h>
36
+#include <libmaple/gpio.h>
37 37
 
38 38
 #ifdef __cplusplus
39 39
 extern "C" {

libmaple/util.h → libmaple/include/libmaple/util.h 파일 보기

@@ -25,30 +25,30 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file util.h
28
+ * @file libmaple/include/libmaple/util.h
29 29
  * @brief Miscellaneous utility macros and procedures.
30 30
  */
31 31
 
32
-#include "libmaple_types.h"
33
-
34
-#ifndef _UTIL_H_
35
-#define _UTIL_H_
32
+#ifndef _LIBMAPLE_UTIL_H_
33
+#define _LIBMAPLE_UTIL_H_
36 34
 
37 35
 #ifdef __cplusplus
38 36
 extern "C"{
39 37
 #endif
40 38
 
39
+#include <libmaple/libmaple_types.h>
40
+
41 41
 /*
42 42
  * Bit manipulation
43 43
  */
44 44
 
45
-/** 1 << the bit number */
45
+/** 1UL shifted left by 'shift' */
46 46
 #define BIT(shift)                     (1UL << (shift))
47
-/** Mask shifted left by 'shift' */
47
+/** 'Mask' shifted left by 'shift' */
48 48
 #define BIT_MASK_SHIFT(mask, shift)    ((mask) << (shift))
49 49
 /** Bits m to n of x */
50 50
 #define GET_BITS(x, m, n) ((((uint32)x) << (31 - (n))) >> ((31 - (n)) + (m)))
51
-/** True if v is a power of two (1, 2, 4, 8, ...) */
51
+/** True iff v is a power of two (1, 2, 4, 8, ...) */
52 52
 #define IS_POWER_OF_TWO(v)  ((v) && !((v) & ((v) - 1)))
53 53
 
54 54
 /*

+ 2 - 2
libmaple/iwdg.c 파일 보기

@@ -25,11 +25,11 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file iwdg.c
28
+ * @file libmaple/iwdg.c
29 29
  * @brief Independent watchdog (IWDG) support
30 30
  */
31 31
 
32
-#include "iwdg.h"
32
+#include <libmaple/iwdg.h>
33 33
 
34 34
 /**
35 35
  * @brief Initialise and start the watchdog

+ 19 - 15
libmaple/nvic.c 파일 보기

@@ -25,13 +25,13 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file nvic.c
28
+ * @file libmaple/nvic.c
29 29
  * @brief Nested vector interrupt controller support.
30 30
  */
31 31
 
32
-#include "nvic.h"
33
-#include "scb.h"
34
-#include "stm32.h"
32
+#include <libmaple/nvic.h>
33
+#include <libmaple/scb.h>
34
+#include <libmaple/stm32.h>
35 35
 
36 36
 /**
37 37
  * @brief Set interrupt priority for an interrupt line
@@ -46,7 +46,7 @@
46 46
  */
47 47
 void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority) {
48 48
     if (irqn < 0) {
49
-        /* This interrupt is in the system handler block  */
49
+        /* This interrupt is in the system handler block */
50 50
         SCB_BASE->SHP[((uint32)irqn & 0xF) - 4] = (priority & 0xF) << 4;
51 51
     } else {
52 52
         NVIC_BASE->IP[irqn] = (priority & 0xF) << 4;
@@ -54,16 +54,12 @@ void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority) {
54 54
 }
55 55
 
56 56
 /**
57
- * @brief Initialize the NVIC
58
- * @param vector_table_address Vector table base address.
59
- * @param offset Offset from vector_table_address.  Some restrictions
60
- *               apply to the use of nonzero offsets; see ST RM0008
61
- *               and the ARM Cortex M3 Technical Reference Manual.
57
+ * @brief Initialize the NVIC, setting interrupts to a default priority.
62 58
  */
63
-void nvic_init(uint32 vector_table_address, uint32 offset) {
59
+void nvic_init(uint32 address, uint32 offset) {
64 60
     uint32 i;
65 61
 
66
-    nvic_set_vector_table(vector_table_address, offset);
62
+    nvic_set_vector_table(address, offset);
67 63
 
68 64
     /*
69 65
      * Lower priority level for all peripheral interrupts to lowest
@@ -78,10 +74,18 @@ void nvic_init(uint32 vector_table_address, uint32 offset) {
78 74
 }
79 75
 
80 76
 /**
81
- * Reset the vector table address.
77
+ * @brief Set the vector table base address.
78
+ *
79
+ * For stand-alone products, the vector table base address is normally
80
+ * the start of Flash (0x08000000).
81
+ *
82
+ * @param address Vector table base address.
83
+ * @param offset Offset from address.  Some restrictions apply to the
84
+ *               use of nonzero offsets; see the ARM Cortex M3
85
+ *               Technical Reference Manual.
82 86
  */
83
-void nvic_set_vector_table(uint32 addr, uint32 offset) {
84
-    SCB_BASE->VTOR = addr | (offset & 0x1FFFFF80);
87
+void nvic_set_vector_table(uint32 address, uint32 offset) {
88
+    SCB_BASE->VTOR = address | (offset & 0x1FFFFF80);
85 89
 }
86 90
 
87 91
 /**

+ 3 - 3
libmaple/pwr.c 파일 보기

@@ -25,12 +25,12 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file pwr.c
28
+ * @file libmaple/pwr.c
29 29
  * @brief Power control (PWR) support.
30 30
  */
31 31
 
32
-#include "pwr.h"
33
-#include "rcc.h"
32
+#include <libmaple/pwr.h>
33
+#include <libmaple/rcc.h>
34 34
 
35 35
 /**
36 36
  * Enables the power interface clock, and resets the power device.

+ 116 - 153
libmaple/rcc.c 파일 보기

@@ -2,6 +2,7 @@
2 2
  * The MIT License
3 3
  *
4 4
  * Copyright (c) 2010 Perry Hung.
5
+ * Copyright (c) 2011 LeafLabs, LLC.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
7 8
  * obtaining a copy of this software and associated documentation
@@ -25,182 +26,144 @@
25 26
  *****************************************************************************/
26 27
 
27 28
 /**
28
- * @file rcc.c
29
- * @brief Implements pretty much only the basic clock setup on the
30
- *        stm32, clock enable/disable and peripheral reset commands.
29
+ * @file libmaple/rcc.c
30
+ * @brief Portable RCC routines.
31 31
  */
32 32
 
33
-#include "libmaple.h"
34
-#include "flash.h"
35
-#include "rcc.h"
36
-#include "bitband.h"
37
-
38
-#define APB1                            RCC_APB1
39
-#define APB2                            RCC_APB2
40
-#define AHB                             RCC_AHB
41
-
42
-struct rcc_dev_info {
43
-    const rcc_clk_domain clk_domain;
44
-    const uint8 line_num;
45
-};
46
-
47
-/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset
48
- * register bit numbers. */
49
-static const struct rcc_dev_info rcc_dev_table[] = {
50
-    [RCC_GPIOA]  = { .clk_domain = APB2, .line_num = 2 },
51
-    [RCC_GPIOB]  = { .clk_domain = APB2, .line_num = 3 },
52
-    [RCC_GPIOC]  = { .clk_domain = APB2, .line_num = 4 },
53
-    [RCC_GPIOD]  = { .clk_domain = APB2, .line_num = 5 },
54
-    [RCC_AFIO]   = { .clk_domain = APB2, .line_num = 0 },
55
-    [RCC_ADC1]   = { .clk_domain = APB2, .line_num = 9 },
56
-    [RCC_ADC2]   = { .clk_domain = APB2, .line_num = 10 },
57
-    [RCC_ADC3]   = { .clk_domain = APB2, .line_num = 15 },
58
-    [RCC_USART1] = { .clk_domain = APB2, .line_num = 14 },
59
-    [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 },
60
-    [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 },
61
-    [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 },
62
-    [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 },
63
-    [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 },
64
-    [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 },
65
-    [RCC_SPI1]   = { .clk_domain = APB2, .line_num = 12 },
66
-    [RCC_SPI2]   = { .clk_domain = APB1, .line_num = 14 },
67
-    [RCC_DMA1]   = { .clk_domain = AHB,  .line_num = 0 },
68
-    [RCC_PWR]    = { .clk_domain = APB1, .line_num = 28},
69
-    [RCC_BKP]    = { .clk_domain = APB1, .line_num = 27},
70
-    [RCC_I2C1]   = { .clk_domain = APB1, .line_num = 21 },
71
-    [RCC_I2C2]   = { .clk_domain = APB1, .line_num = 22 },
72
-    [RCC_CRC]    = { .clk_domain = AHB,  .line_num = 6},
73
-    [RCC_FLITF]  = { .clk_domain = AHB,  .line_num = 4},
74
-    [RCC_SRAM]   = { .clk_domain = AHB,  .line_num = 2},
75
-    [RCC_USB]    = { .clk_domain = APB1, .line_num = 23},
76
-#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
77
-    [RCC_GPIOE]  = { .clk_domain = APB2, .line_num = 6 },
78
-    [RCC_GPIOF]  = { .clk_domain = APB2, .line_num = 7 },
79
-    [RCC_GPIOG]  = { .clk_domain = APB2, .line_num = 8 },
80
-    [RCC_UART4]  = { .clk_domain = APB1, .line_num = 19 },
81
-    [RCC_UART5]  = { .clk_domain = APB1, .line_num = 20 },
82
-    [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 },
83
-    [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 },
84
-    [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 },
85
-    [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 },
86
-    [RCC_FSMC]   = { .clk_domain = AHB,  .line_num = 8 },
87
-    [RCC_DAC]    = { .clk_domain = APB1, .line_num = 29 },
88
-    [RCC_DMA2]   = { .clk_domain = AHB,  .line_num = 1 },
89
-    [RCC_SDIO]   = { .clk_domain = AHB,  .line_num = 10 },
90
-    [RCC_SPI3]   = { .clk_domain = APB1, .line_num = 15 },
91
-#endif
92
-#ifdef STM32_XL_DENSITY
93
-    [RCC_TIMER9]  = { .clk_domain = APB2, .line_num = 19 },
94
-    [RCC_TIMER10] = { .clk_domain = APB2, .line_num = 20 },
95
-    [RCC_TIMER11] = { .clk_domain = APB2, .line_num = 21 },
96
-    [RCC_TIMER12] = { .clk_domain = APB1, .line_num = 6 },
97
-    [RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 },
98
-    [RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 },
99
-#endif
100
-};
33
+#include <libmaple/rcc.h>
34
+
35
+#include "rcc_private.h"
101 36
 
102 37
 /**
103
- * @brief Initialize the clock control system. Initializes the system
104
- *        clock source to use the PLL driven by an external oscillator
105
- * @param sysclk_src system clock source, must be PLL
106
- * @param pll_src pll clock source, must be HSE
107
- * @param pll_mul pll multiplier
38
+ * @brief Get a peripheral's clock domain
39
+ * @param id Clock ID of the peripheral whose clock domain to return
40
+ * @return Clock source for the given clock ID
108 41
  */
109
-void rcc_clk_init(rcc_sysclk_src sysclk_src,
110
-                  rcc_pllsrc pll_src,
111
-                  rcc_pll_multiplier pll_mul) {
112
-    uint32 cfgr = 0;
113
-    uint32 cr;
114
-
115
-    /* Assume that we're going to clock the chip off the PLL, fed by
116
-     * the HSE */
117
-    ASSERT(sysclk_src == RCC_CLKSRC_PLL &&
118
-           pll_src    == RCC_PLLSRC_HSE);
119
-
120
-    RCC_BASE->CFGR = pll_src | pll_mul;
121
-
122
-    /* Turn on the HSE */
123
-    cr = RCC_BASE->CR;
124
-    cr |= RCC_CR_HSEON;
125
-    RCC_BASE->CR = cr;
126
-    while (!(RCC_BASE->CR & RCC_CR_HSERDY))
127
-        ;
128
-
129
-    /* Now the PLL */
130
-    cr |= RCC_CR_PLLON;
131
-    RCC_BASE->CR = cr;
132
-    while (!(RCC_BASE->CR & RCC_CR_PLLRDY))
133
-        ;
42
+rcc_clk_domain rcc_dev_clk(rcc_clk_id id) {
43
+    return rcc_dev_table[id].clk_domain;
44
+}
134 45
 
135
-    /* Finally, let's switch over to the PLL */
46
+/**
47
+ * @brief Switch the clock used as the source of the system clock.
48
+ *
49
+ * After switching the source, this function blocks until the new
50
+ * clock source is in use.
51
+ *
52
+ * @param sysclk_src New system clock source.
53
+ * @see rcc_sysclk_src
54
+ */
55
+void rcc_switch_sysclk(rcc_sysclk_src sysclk_src) {
56
+    uint32 cfgr = RCC_BASE->CFGR;
136 57
     cfgr &= ~RCC_CFGR_SW;
137
-    cfgr |= RCC_CFGR_SW_PLL;
58
+    cfgr |= sysclk_src;
59
+
60
+    /* Switch SYSCLK source. */
138 61
     RCC_BASE->CFGR = cfgr;
139
-    while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
62
+
63
+    /* Wait for new source to come into use. */
64
+    while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != (sysclk_src << 2))
140 65
         ;
141 66
 }
142 67
 
143
-/**
144
- * @brief Turn on the clock line on a peripheral
145
- * @param id Clock ID of the peripheral to turn on.
68
+/*
69
+ * Turning clocks off and on, querying their status.
146 70
  */
147
-void rcc_clk_enable(rcc_clk_id id) {
148
-    static const __io uint32* enable_regs[] = {
149
-        [APB1] = &RCC_BASE->APB1ENR,
150
-        [APB2] = &RCC_BASE->APB2ENR,
151
-        [AHB] = &RCC_BASE->AHBENR,
152
-    };
153
-
154
-    rcc_clk_domain clk_domain = rcc_dev_clk(id);
155
-    __io uint32* enr = (__io uint32*)enable_regs[clk_domain];
156
-    uint8 lnum = rcc_dev_table[id].line_num;
157
-
158
-    bb_peri_set_bit(enr, lnum, 1);
71
+
72
+/* IMPORTANT NOTE FOR IMPLEMENTORS:
73
+ *
74
+ * libmaple assumes that enum rcc_clk enumerators are two-byte
75
+ * values, stored in a uint16, in the following way:
76
+ *
77
+ *  - The high-order byte is the byte offset (from RCC_BASE) of the register
78
+ *    to touch when turning on or off the given clock.
79
+ *
80
+ *  - The low-order byte is the bit in that register that turns the
81
+ *    clock on or off.
82
+ *
83
+ * Example for STM32F1: Turning on the high-speed external clock (HSE)
84
+ * involves setting HSEON, bit 16, of RCC_CR. The high-order byte is
85
+ * then offsetof(struct rcc_reg_map, CR) = 0, and the low-order byte
86
+ * is 16.
87
+ *
88
+ * The corresponding value of RCC_CLK_HSE is thus (0 << 8) | 16 = 16.
89
+ *
90
+ * On all known STM32 series, this encoding has the property that
91
+ * adding one to the low byte also gives the bit to check to determine
92
+ * if the clock is ready. For example, on STM32F1, RCC_CR_HSERDY is
93
+ * bit 17. If that's not the case on your series, rcc_is_clk_ready()
94
+ * won't work for you. */
95
+
96
+/* Returns the RCC register which controls the clock source. */
97
+static inline __io uint32* rcc_clk_reg(rcc_clk clock) {
98
+    return (__io uint32*)((__io uint8*)RCC_BASE + (clock >> 8));
99
+}
100
+
101
+/* Returns a mask in rcc_clk_reg(clock) to be used for turning the
102
+ * clock on and off */
103
+static inline uint32 rcc_clk_on_mask(rcc_clk clock) {
104
+    return 1 << (clock & 0xFF);
105
+}
106
+
107
+/* Returns a mask in rcc_clk_reg(clock) to be used when checking the
108
+ * readiness of the clock. */
109
+static inline uint32 rcc_clk_ready_mask(rcc_clk clock) {
110
+    return rcc_clk_on_mask(clock) << 1;
159 111
 }
160 112
 
161 113
 /**
162
- * @brief Reset a peripheral.
163
- * @param id Clock ID of the peripheral to reset.
114
+ * @brief Turn on a clock source.
115
+ *
116
+ * After this routine exits, callers should ensure that the clock
117
+ * source is ready by waiting until rcc_is_clk_ready(clock) returns
118
+ * true.
119
+ *
120
+ * @param clock Clock to turn on.
121
+ * @see rcc_turn_off_clk()
122
+ * @see rcc_is_clk_ready()
164 123
  */
165
-void rcc_reset_dev(rcc_clk_id id) {
166
-    static const __io uint32* reset_regs[] = {
167
-        [APB1] = &RCC_BASE->APB1RSTR,
168
-        [APB2] = &RCC_BASE->APB2RSTR,
169
-    };
170
-
171
-    rcc_clk_domain clk_domain = rcc_dev_clk(id);
172
-    __io void* addr = (__io void*)reset_regs[clk_domain];
173
-    uint8 lnum = rcc_dev_table[id].line_num;
174
-
175
-    bb_peri_set_bit(addr, lnum, 1);
176
-    bb_peri_set_bit(addr, lnum, 0);
124
+void rcc_turn_on_clk(rcc_clk clock) {
125
+    *rcc_clk_reg(clock) |= rcc_clk_on_mask(clock);
177 126
 }
178 127
 
179 128
 /**
180
- * @brief Get a peripheral's clock domain
181
- * @param id Clock ID of the peripheral whose clock domain to return
182
- * @return Clock source for the given clock ID
129
+ * @brief Turn off a clock source.
130
+ *
131
+ * In certain configurations, certain clock sources cannot be safely
132
+ * turned off. (For example, the main PLL on STM32F1 devices cannot be
133
+ * turned off if it has been selected as the SYSCLK source). Consult
134
+ * the reference material for your MCU to ensure it is safe to call
135
+ * this function.
136
+ *
137
+ * @param clock Clock to turn off.
138
+ * @see rcc_turn_on_clk()
139
+ * @see rcc_is_clk_ready()
183 140
  */
184
-rcc_clk_domain rcc_dev_clk(rcc_clk_id id) {
185
-    return rcc_dev_table[id].clk_domain;
141
+void rcc_turn_off_clk(rcc_clk clock) {
142
+    *rcc_clk_reg(clock) &= ~rcc_clk_on_mask(clock);
186 143
 }
187 144
 
188 145
 /**
189
- * @brief Set the divider on a peripheral prescaler
190
- * @param prescaler prescaler to set
191
- * @param divider prescaler divider
146
+ * @brief Check if a clock is on.
147
+ * @param clock Clock to check.
148
+ * @return 1 if the clock is on, 0 if the clock is off.
192 149
  */
193
-void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) {
194
-    static const uint32 masks[] = {
195
-        [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE,
196
-        [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1,
197
-        [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2,
198
-        [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE,
199
-        [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE,
200
-    };
150
+int rcc_is_clk_on(rcc_clk clock) {
151
+    return !!(*rcc_clk_reg(clock) & rcc_clk_on_mask(clock));
152
+}
201 153
 
202
-    uint32 cfgr = RCC_BASE->CFGR;
203
-    cfgr &= ~masks[prescaler];
204
-    cfgr |= divider;
205
-    RCC_BASE->CFGR = cfgr;
154
+/**
155
+ * @brief Check if a clock source is ready.
156
+ *
157
+ * In general, it is not safe to rely on a clock source unless this
158
+ * function returns nonzero. Also note that this function may return
159
+ * nonzero for a short period of time after a clock has been turned
160
+ * off. Consult the reference material for your MCU for more details.
161
+ *
162
+ * @param clock Clock whose readiness to check for.
163
+ * @return Nonzero if the clock is ready, zero otherwise.
164
+ * @see rcc_turn_on_clk()
165
+ * @see rcc_turn_off_clk()
166
+ */
167
+int rcc_is_clk_ready(rcc_clk clock) {
168
+    return (int)(*rcc_clk_reg(clock) & rcc_clk_ready_mask(clock));
206 169
 }

+ 67 - 0
libmaple/rcc_private.h 파일 보기

@@ -0,0 +1,67 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2011 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/*
28
+ * RCC private header.
29
+ */
30
+
31
+#ifndef _LIBMAPLE_PRIVATE_RCC_H_
32
+#define _LIBMAPLE_PRIVATE_RCC_H_
33
+
34
+#include <libmaple/bitband.h>
35
+
36
+struct rcc_dev_info {
37
+    const rcc_clk_domain clk_domain;
38
+    const uint8 line_num;
39
+};
40
+
41
+extern const struct rcc_dev_info rcc_dev_table[];
42
+
43
+static inline void rcc_do_clk_enable(__io uint32** enable_regs,
44
+                                     rcc_clk_id id) {
45
+    __io uint32 *enable_reg = enable_regs[rcc_dev_clk(id)];
46
+    uint8 line_num = rcc_dev_table[id].line_num;
47
+    bb_peri_set_bit(enable_reg, line_num, 1);
48
+}
49
+
50
+static inline void rcc_do_reset_dev(__io uint32** reset_regs,
51
+                                    rcc_clk_id id) {
52
+    __io uint32 *reset_reg = reset_regs[rcc_dev_clk(id)];
53
+    uint8 line_num = rcc_dev_table[id].line_num;
54
+    bb_peri_set_bit(reset_reg, line_num, 1);
55
+    bb_peri_set_bit(reset_reg, line_num, 0);
56
+}
57
+
58
+static inline void rcc_do_set_prescaler(const uint32 *masks,
59
+                                        rcc_prescaler prescaler,
60
+                                        uint32 divider) {
61
+    uint32 cfgr = RCC_BASE->CFGR;
62
+    cfgr &= ~masks[prescaler];
63
+    cfgr |= divider;
64
+    RCC_BASE->CFGR = cfgr;
65
+}
66
+
67
+#endif

+ 23 - 31
libmaple/rules.mk 파일 보기

@@ -3,43 +3,35 @@ sp              := $(sp).x
3 3
 dirstack_$(sp)  := $(d)
4 4
 d               := $(dir)
5 5
 BUILDDIRS       += $(BUILD_PATH)/$(d)
6
-BUILDDIRS       += $(BUILD_PATH)/$(d)/usb
7
-BUILDDIRS       += $(BUILD_PATH)/$(d)/usb/usb_lib
8 6
 
9
-LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH) -I$(LIBMAPLE_PATH)/usb -I$(LIBMAPLE_PATH)/usb/usb_lib
7
+LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH)/include -I$(LIBMAPLE_MODULE_SERIES)/include
8
+LIBMAPLE_PRIVATE_INCLUDES := -I$(LIBMAPLE_PATH)
10 9
 
11 10
 # Local flags
12
-CFLAGS_$(d) = -I$(d) $(LIBMAPLE_INCLUDES) -Wall -Werror
11
+CFLAGS_$(d) = $(LIBMAPLE_PRIVATE_INCLUDES) $(LIBMAPLE_INCLUDES) -Wall -Werror
13 12
 
14 13
 # Local rules and targets
15
-cSRCS_$(d) := adc.c                    \
16
-              bkp.c                    \
17
-              dac.c                    \
18
-              dma.c                    \
19
-              exti.c                   \
20
-              flash.c                  \
21
-              fsmc.c                   \
22
-              gpio.c                   \
23
-              iwdg.c                   \
24
-              nvic.c                   \
25
-              pwr.c		       \
26
-              i2c.c                    \
27
-              rcc.c                    \
28
-              spi.c                    \
29
-              syscalls.c               \
30
-              systick.c                \
31
-              timer.c                  \
32
-              usart.c                  \
33
-              util.c                   \
34
-              usb/usb.c                \
35
-              usb/usb_reg_map.c        \
36
-              usb/usb_cdcacm.c         \
37
-              usb/usb_lib/usb_core.c   \
38
-              usb/usb_lib/usb_init.c   \
39
-              usb/usb_lib/usb_mem.c    \
40
-              usb/usb_lib/usb_regs.c
41
-
14
+cSRCS_$(d) := adc.c
15
+cSRCS_$(d) += dac.c
16
+cSRCS_$(d) += dma.c
17
+cSRCS_$(d) += exti.c
18
+cSRCS_$(d) += flash.c
19
+cSRCS_$(d) += gpio.c
20
+cSRCS_$(d) += iwdg.c
21
+cSRCS_$(d) += nvic.c
22
+cSRCS_$(d) += pwr.c
23
+cSRCS_$(d) += rcc.c
24
+cSRCS_$(d) += spi.c
25
+cSRCS_$(d) += systick.c
26
+cSRCS_$(d) += timer.c
27
+cSRCS_$(d) += usart.c
28
+cSRCS_$(d) += usart_private.c
29
+cSRCS_$(d) += util.c
42 30
 sSRCS_$(d) := exc.S
31
+# I2C support must be ported to F2:
32
+ifeq ($(MCU_SERIES),stm32f1)
33
+cSRCS_$(d) += i2c.c
34
+endif
43 35
 
44 36
 cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%)
45 37
 sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%)

+ 4 - 80
libmaple/spi.c 파일 보기

@@ -1,6 +1,7 @@
1 1
 /******************************************************************************
2 2
  * The MIT License
3 3
  *
4
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
4 5
  * Copyright (c) 2010 Perry Hung.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
@@ -25,48 +26,18 @@
25 26
  *****************************************************************************/
26 27
 
27 28
 /**
28
- * @file spi.c
29
+ * @file libmaple/spi.c
29 30
  * @author Marti Bolivar <mbolivar@leaflabs.com>
30 31
  * @brief Serial Peripheral Interface (SPI) support.
31 32
  *        Currently, there is no Integrated Interchip Sound (I2S) support.
32 33
  */
33 34
 
34
-#include "spi.h"
35
-#include "bitband.h"
35
+#include <libmaple/spi.h>
36
+#include <libmaple/bitband.h>
36 37
 
37 38
 static void spi_reconfigure(spi_dev *dev, uint32 cr1_config);
38 39
 
39 40
 /*
40
- * SPI devices
41
- */
42
-
43
-static spi_dev spi1 = {
44
-    .regs     = SPI1_BASE,
45
-    .clk_id   = RCC_SPI1,
46
-    .irq_num  = NVIC_SPI1,
47
-};
48
-/** SPI device 1 */
49
-spi_dev *SPI1 = &spi1;
50
-
51
-static spi_dev spi2 = {
52
-    .regs     = SPI2_BASE,
53
-    .clk_id   = RCC_SPI2,
54
-    .irq_num  = NVIC_SPI2,
55
-};
56
-/** SPI device 2 */
57
-spi_dev *SPI2 = &spi2;
58
-
59
-#ifdef STM32_HIGH_DENSITY
60
-static spi_dev spi3 = {
61
-    .regs     = SPI3_BASE,
62
-    .clk_id   = RCC_SPI3,
63
-    .irq_num  = NVIC_SPI3,
64
-};
65
-/** SPI device 3 */
66
-spi_dev *SPI3 = &spi3;
67
-#endif
68
-
69
-/*
70 41
  * SPI convenience routines
71 42
  */
72 43
 
@@ -80,37 +51,6 @@ void spi_init(spi_dev *dev) {
80 51
 }
81 52
 
82 53
 /**
83
- * @brief Configure GPIO bit modes for use as a SPI port's pins.
84
- * @param as_master If true, configure bits for use as a bus master.
85
- *                  Otherwise, configure bits for use as slave.
86
- * @param nss_dev NSS pin's GPIO device
87
- * @param comm_dev SCK, MISO, MOSI pins' GPIO device
88
- * @param nss_bit NSS pin's GPIO bit on nss_dev
89
- * @param sck_bit SCK pin's GPIO bit on comm_dev
90
- * @param miso_bit MISO pin's GPIO bit on comm_dev
91
- * @param mosi_bit MOSI pin's GPIO bit on comm_dev
92
- */
93
-void spi_gpio_cfg(uint8 as_master,
94
-                  gpio_dev *nss_dev,
95
-                  uint8 nss_bit,
96
-                  gpio_dev *comm_dev,
97
-                  uint8 sck_bit,
98
-                  uint8 miso_bit,
99
-                  uint8 mosi_bit) {
100
-    if (as_master) {
101
-        gpio_set_mode(nss_dev, nss_bit, GPIO_AF_OUTPUT_PP);
102
-        gpio_set_mode(comm_dev, sck_bit, GPIO_AF_OUTPUT_PP);
103
-        gpio_set_mode(comm_dev, miso_bit, GPIO_INPUT_FLOATING);
104
-        gpio_set_mode(comm_dev, mosi_bit, GPIO_AF_OUTPUT_PP);
105
-    } else {
106
-        gpio_set_mode(nss_dev, nss_bit, GPIO_INPUT_FLOATING);
107
-        gpio_set_mode(comm_dev, sck_bit, GPIO_INPUT_FLOATING);
108
-        gpio_set_mode(comm_dev, miso_bit, GPIO_AF_OUTPUT_PP);
109
-        gpio_set_mode(comm_dev, mosi_bit, GPIO_INPUT_FLOATING);
110
-    }
111
-}
112
-
113
-/**
114 54
  * @brief Configure and enable a SPI device as bus master.
115 55
  *
116 56
  * The device's peripheral will be disabled before being reconfigured.
@@ -165,18 +105,6 @@ uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) {
165 105
 }
166 106
 
167 107
 /**
168
- * @brief Call a function on each SPI port
169
- * @param fn Function to call.
170
- */
171
-void spi_foreach(void (*fn)(spi_dev*)) {
172
-    fn(SPI1);
173
-    fn(SPI2);
174
-#ifdef STM32_HIGH_DENSITY
175
-    fn(SPI3);
176
-#endif
177
-}
178
-
179
-/**
180 108
  * @brief Enable a SPI peripheral
181 109
  * @param dev Device to enable
182 110
  */
@@ -234,7 +162,3 @@ static void spi_reconfigure(spi_dev *dev, uint32 cr1_config) {
234 162
     dev->regs->CR1 = cr1_config;
235 163
     spi_peripheral_enable(dev);
236 164
 }
237
-
238
-/*
239
- * IRQ handlers (TODO)
240
- */

+ 37 - 0
libmaple/spi_private.h 파일 보기

@@ -0,0 +1,37 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+#ifndef _LIBMAPLE_SPI_PRIVATE_H_
28
+#define _LIBMAPLE_SPI_PRIVATE_H_
29
+
30
+#define SPI_DEV(num)                              \
31
+    {                                             \
32
+        .regs    = SPI##num##_BASE,               \
33
+        .clk_id  = RCC_SPI##num,                  \
34
+        .irq_num = NVIC_SPI##num,                 \
35
+    }
36
+
37
+#endif

+ 0 - 191
libmaple/stm32.h 파일 보기

@@ -1,191 +0,0 @@
1
-/******************************************************************************
2
- * The MIT License
3
- *
4
- * Copyright (c) 2010 LeafLabs, LLC.
5
- *
6
- * Permission is hereby granted, free of charge, to any person
7
- * obtaining a copy of this software and associated documentation
8
- * files (the "Software"), to deal in the Software without
9
- * restriction, including without limitation the rights to use, copy,
10
- * modify, merge, publish, distribute, sublicense, and/or sell copies
11
- * of the Software, and to permit persons to whom the Software is
12
- * furnished to do so, subject to the following conditions:
13
- *
14
- * The above copyright notice and this permission notice shall be
15
- * included in all copies or substantial portions of the Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- * SOFTWARE.
25
- *****************************************************************************/
26
-
27
-/**
28
- * @file stm32.h
29
- * @brief STM32 chip-specific definitions
30
- */
31
-
32
-#ifndef _STM32_H_
33
-#define _STM32_H_
34
-
35
-/*
36
- * User-specific configuration.
37
- *
38
- * The #defines here depend upon how libmaple is used.  Because of the
39
- * potential for a mismatch between them and the actual libmaple
40
- * usage, you should try to keep their number to an absolute minimum.
41
- */
42
-
43
-#ifdef __DOXYGEN_PREDEFINED_HACK
44
-
45
-    /** @brief APB1 clock speed, in Hz. */
46
-    #define STM32_PCLK1
47
-    /** @brief APB2 clock speed, in Hz. */
48
-    #define STM32_PCLK2
49
-
50
-    /** Deprecated.  Use STM32_PCLK1 instead. */
51
-    #define PCLK1
52
-    /** Deprecated. Use STM32_PCLK2 instead. */
53
-    #define PCLK2
54
-
55
-#endif
56
-
57
-#ifndef STM32_PCLK1
58
-#define STM32_PCLK1   36000000U
59
-#endif
60
-#ifndef PCLK1
61
-#define PCLK1 STM32_PCLK1
62
-#endif
63
-#if PCLK1 != STM32_PCLK1
64
-#error "(Deprecated) PCLK1 differs from STM32_PCLK1"
65
-#endif
66
-
67
-#ifndef STM32_PCLK2
68
-#define STM32_PCLK2   72000000U
69
-#endif
70
-#ifndef PCLK2
71
-#define PCLK2 STM32_PCLK2
72
-#endif
73
-#if PCLK2 != STM32_PCLK2
74
-#error "(Deprecated) PCLK2 differs from STM32_PCLK2"
75
-#endif
76
-
77
-/*
78
- * Density-specific configuration.
79
- */
80
-
81
-#ifdef __DOXYGEN_PREDEFINED_HACK
82
-
83
-    /**
84
-     * @brief Number of interrupts in the NVIC.
85
-     *
86
-     * This define is automatically generated whenever the proper
87
-     * density is defined (currently, this is restricted to defining
88
-     * one of STM32_MEDIUM_DENSITY and STM32_HIGH_DENSITY).
89
-     */
90
-    #define STM32_NR_INTERRUPTS
91
-
92
-    /** Deprecated.  Use STM32_NR_INTERRUPTS instead. */
93
-    #define NR_INTERRUPTS
94
-
95
-#endif
96
-
97
-#ifdef STM32_MEDIUM_DENSITY
98
-    #define STM32_NR_INTERRUPTS 43
99
-#elif defined(STM32_HIGH_DENSITY)
100
-    #define STM32_NR_INTERRUPTS 60
101
-#else
102
-#error "No STM32 board type defined!"
103
-#endif
104
-
105
-#define NR_INTERRUPTS STM32_NR_INTERRUPTS
106
-
107
-/*
108
- * MCU-specific configuration.
109
- */
110
-
111
-#ifdef __DOXYGEN_PREDEFINED_HACK
112
-
113
-    /**
114
-     * Number of GPIO ports.
115
-     */
116
-    #define STM32_NR_GPIO_PORTS
117
-
118
-    /**
119
-     * @brief Multiplier to convert microseconds into loop iterations
120
-     *        in delay_us().
121
-     *
122
-     * @see delay_us()
123
-     */
124
-    #define STM32_DELAY_US_MULT
125
-
126
-    /**
127
-     * @brief Pointer to end of built-in SRAM.
128
-     *
129
-     * Points to the address which is 1 byte past the last valid
130
-     * SRAM address.
131
-     */
132
-    #define STM32_SRAM_END
133
-
134
-    /** Deprecated.  Use STM32_NR_GPIO_PORTS instead. */
135
-    #define NR_GPIO_PORTS
136
-    /** Deprecated.  Use STM32_DELAY_US_MULT instead. */
137
-    #define DELAY_US_MULT
138
-
139
-#endif
140
-
141
-#if defined(MCU_STM32F103RB)
142
-    /* e.g., LeafLabs Maple */
143
-
144
-    #define STM32_NR_GPIO_PORTS          4
145
-    #define STM32_DELAY_US_MULT         12
146
-    #define STM32_SRAM_END              ((void*)0x20005000)
147
-
148
-    #define NR_GPIO_PORTS               STM32_NR_GPIO_PORTS
149
-    #define DELAY_US_MULT               STM32_DELAY_US_MULT
150
-
151
-#elif defined(MCU_STM32F103ZE)
152
-    /* e.g., LeafLabs Maple Native */
153
-
154
-    #define STM32_NR_GPIO_PORTS          7
155
-    #define STM32_DELAY_US_MULT         12
156
-    #define STM32_SRAM_END              ((void*)0x20010000)
157
-
158
-    #define NR_GPIO_PORTS               STM32_NR_GPIO_PORTS
159
-    #define DELAY_US_MULT               STM32_DELAY_US_MULT
160
-
161
-#elif defined(MCU_STM32F103CB)
162
-    /* e.g., LeafLabs Maple Mini */
163
-
164
-    /* This STM32_NR_GPIO_PORTS value is not, strictly speaking, true.
165
-     * But only pins 0 and 1 exist, and they're used for OSC on the
166
-     * Mini, so we'll live with this for now. */
167
-    #define STM32_NR_GPIO_PORTS          3
168
-    #define STM32_DELAY_US_MULT         12
169
-    #define STM32_SRAM_END              ((void*)0x20005000)
170
-
171
-    #define NR_GPIO_PORTS               STM32_NR_GPIO_PORTS
172
-    #define DELAY_US_MULT               STM32_DELAY_US_MULT
173
-
174
-#elif defined(MCU_STM32F103RE)
175
-    /* e.g., LeafLabs Maple RET6 edition */
176
-
177
-    #define STM32_NR_GPIO_PORTS          4
178
-    #define STM32_DELAY_US_MULT         12
179
-    #define STM32_SRAM_END              ((void*)0x20010000)
180
-
181
-    #define NR_GPIO_PORTS               STM32_NR_GPIO_PORTS
182
-    #define DELAY_US_MULT               STM32_DELAY_US_MULT
183
-
184
-#else
185
-
186
-#error "No MCU type specified. Add something like -DMCU_STM32F103RB "   \
187
-       "to your compiler arguments (probably in a Makefile)."
188
-
189
-#endif
190
-
191
-#endif  /* _STM32_H_ */

+ 45 - 0
libmaple/stm32_private.h 파일 보기

@@ -0,0 +1,45 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+*****************************************************************************/
26
+
27
+#ifndef _LIBMAPLE_STM32_PRIVATE_H_
28
+#define _LIBMAPLE_STM32_PRIVATE_H_
29
+
30
+typedef enum stm32_mem_block_purpose {
31
+    STM32_BLOCK_CODE,
32
+    STM32_BLOCK_SRAM,
33
+    STM32_BLOCK_PERIPH,
34
+    STM32_BLOCK_FSMC_1_2,
35
+    STM32_BLOCK_FSMC_3_4,
36
+    STM32_BLOCK_FSMC_REG,
37
+    STM32_BLOCK_UNUSED,
38
+    STM32_BLOCK_CORTEX_INTERNAL,
39
+} stm32_mem_block_purpose;
40
+
41
+static inline stm32_mem_block_purpose stm32_block_purpose(void *addr) {
42
+    return (stm32_mem_block_purpose)((unsigned)addr >> 29);
43
+}
44
+
45
+#endif

+ 112 - 0
libmaple/stm32f1/adc.c 파일 보기

@@ -0,0 +1,112 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ * Copyright (c) 2010 Perry Hung.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person
8
+ * obtaining a copy of this software and associated documentation
9
+ * files (the "Software"), to deal in the Software without
10
+ * restriction, including without limitation the rights to use, copy,
11
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ * of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *****************************************************************************/
27
+
28
+/**
29
+ * @file libmaple/stm32f1/adc.c
30
+ * @author Marti Bolivar <mbolivar@leaflabs.com>,
31
+ *         Perry Hung <perry@leaflabs.com>
32
+ * @brief STM32F1 ADC support.
33
+ */
34
+
35
+#include <libmaple/adc.h>
36
+#include <libmaple/gpio.h>
37
+
38
+/*
39
+ * Devices
40
+ */
41
+
42
+static adc_dev adc1 = {
43
+    .regs   = ADC1_BASE,
44
+    .clk_id = RCC_ADC1,
45
+};
46
+/** ADC1 device. */
47
+const adc_dev *ADC1 = &adc1;
48
+
49
+static adc_dev adc2 = {
50
+    .regs   = ADC2_BASE,
51
+    .clk_id = RCC_ADC2,
52
+};
53
+/** ADC2 device. */
54
+const adc_dev *ADC2 = &adc2;
55
+
56
+#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
57
+static adc_dev adc3 = {
58
+    .regs   = ADC3_BASE,
59
+    .clk_id = RCC_ADC3,
60
+};
61
+/** ADC3 device. */
62
+const adc_dev *ADC3 = &adc3;
63
+#endif
64
+
65
+/*
66
+ * STM32F1 routines
67
+ */
68
+
69
+/**
70
+ * @brief Calibrate an ADC peripheral
71
+ * @param dev adc device
72
+ */
73
+void adc_calibrate(const adc_dev *dev) {
74
+    __io uint32 *rstcal_bit = bb_perip(&(dev->regs->CR2), 3);
75
+    __io uint32 *cal_bit = bb_perip(&(dev->regs->CR2), 2);
76
+
77
+    *rstcal_bit = 1;
78
+    while (*rstcal_bit)
79
+        ;
80
+
81
+    *cal_bit = 1;
82
+    while (*cal_bit)
83
+        ;
84
+}
85
+
86
+/*
87
+ * Common routines
88
+ */
89
+
90
+void adc_set_prescaler(adc_prescaler pre) {
91
+    rcc_set_prescaler(RCC_PRESCALER_ADC, (uint32)pre);
92
+}
93
+
94
+void adc_foreach(void (*fn)(const adc_dev*)) {
95
+    fn(ADC1);
96
+    fn(ADC2);
97
+#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
98
+    fn(ADC3);
99
+#endif
100
+}
101
+
102
+void adc_config_gpio(const adc_dev *ignored, gpio_dev *gdev, uint8 bit) {
103
+    gpio_set_mode(gdev, bit, GPIO_INPUT_ANALOG);
104
+}
105
+
106
+void adc_enable_single_swstart(const adc_dev *dev) {
107
+    adc_init(dev);
108
+    adc_set_extsel(dev, ADC_SWSTART);
109
+    adc_set_exttrig(dev, 1);
110
+    adc_enable(dev);
111
+    adc_calibrate(dev);
112
+}

libmaple/bkp.c → libmaple/stm32f1/bkp.c 파일 보기

@@ -25,14 +25,14 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file bkp.c
29
- * @brief Backup register support.
28
+ * @file libmaple/stm32f1/bkp.c
29
+ * @brief STM32F1 Backup register support.
30 30
  */
31 31
 
32
-#include "bkp.h"
33
-#include "pwr.h"
34
-#include "rcc.h"
35
-#include "bitband.h"
32
+#include <libmaple/bkp.h>
33
+#include <libmaple/pwr.h>
34
+#include <libmaple/rcc.h>
35
+#include <libmaple/bitband.h>
36 36
 
37 37
 static inline __io uint32* data_register(uint8 reg);
38 38
 

+ 412 - 0
libmaple/stm32f1/dma.c 파일 보기

@@ -0,0 +1,412 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Michael Hope.
5
+ * Copyright (c) 2012 LeafLabs, LLC.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person
8
+ * obtaining a copy of this software and associated documentation
9
+ * files (the "Software"), to deal in the Software without
10
+ * restriction, including without limitation the rights to use, copy,
11
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ * of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *****************************************************************************/
27
+
28
+/**
29
+ * @file libmaple/stm32f1/dma.c
30
+ * @author Marti Bolivar <mbolivar@leaflabs.com>;
31
+ *         Original implementation by Michael Hope
32
+ * @brief STM32F1 DMA support.
33
+ */
34
+
35
+#include <libmaple/dma.h>
36
+#include <libmaple/bitband.h>
37
+
38
+/* Hack to ensure inlining in dma_irq_handler() */
39
+#define DMA_GET_HANDLER(dev, tube) (dev->handlers[tube - 1].handler)
40
+#include "dma_private.h"
41
+
42
+/*
43
+ * Devices
44
+ */
45
+
46
+static dma_dev dma1 = {
47
+    .regs     = DMA1_BASE,
48
+    .clk_id   = RCC_DMA1,
49
+    .handlers = {{ .handler = NULL, .irq_line = NVIC_DMA_CH1 },
50
+                 { .handler = NULL, .irq_line = NVIC_DMA_CH2 },
51
+                 { .handler = NULL, .irq_line = NVIC_DMA_CH3 },
52
+                 { .handler = NULL, .irq_line = NVIC_DMA_CH4 },
53
+                 { .handler = NULL, .irq_line = NVIC_DMA_CH5 },
54
+                 { .handler = NULL, .irq_line = NVIC_DMA_CH6 },
55
+                 { .handler = NULL, .irq_line = NVIC_DMA_CH7 }},
56
+};
57
+/** STM32F1 DMA1 device */
58
+dma_dev *DMA1 = &dma1;
59
+
60
+#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
61
+static dma_dev dma2 = {
62
+    .regs     = DMA2_BASE,
63
+    .clk_id   = RCC_DMA2,
64
+    .handlers = {{ .handler = NULL, .irq_line = NVIC_DMA2_CH1   },
65
+                 { .handler = NULL, .irq_line = NVIC_DMA2_CH2   },
66
+                 { .handler = NULL, .irq_line = NVIC_DMA2_CH3   },
67
+                 { .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 },
68
+                 { .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 }}, /* !@#$ */
69
+};
70
+/** STM32F1 DMA2 device */
71
+dma_dev *DMA2 = &dma2;
72
+#endif
73
+
74
+/*
75
+ * Auxiliary routines
76
+ */
77
+
78
+/* Can channel serve cfg->tube_req_src? */
79
+static int cfg_req_ok(dma_channel channel, dma_tube_config *cfg) {
80
+    return (cfg->tube_req_src & 0x7) == channel;
81
+}
82
+
83
+/* Can dev serve cfg->tube_req_src? */
84
+static int cfg_dev_ok(dma_dev *dev, dma_tube_config *cfg) {
85
+    return (rcc_clk_id)(cfg->tube_req_src >> 3) == dev->clk_id;
86
+}
87
+
88
+/* Is addr acceptable for use as DMA src/dst? */
89
+static int cfg_mem_ok(__io void *addr) {
90
+    enum dma_atype atype = _dma_addr_type(addr);
91
+    return atype == DMA_ATYPE_MEM || atype == DMA_ATYPE_PER;
92
+}
93
+
94
+/* Is the direction implied by src->dst supported? */
95
+static int cfg_dir_ok(dma_tube_config *cfg) {
96
+    /* We can't do peripheral->peripheral transfers. */
97
+    return ((_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM) ||
98
+            (_dma_addr_type(cfg->tube_dst) == DMA_ATYPE_MEM));
99
+}
100
+
101
+static int preconfig_check(dma_dev *dev, dma_channel channel,
102
+                           dma_tube_config *cfg) {
103
+    if (!cfg_req_ok(channel, cfg)) {
104
+        return -DMA_TUBE_CFG_EREQ;
105
+    }
106
+    if (cfg->tube_nr_xfers > 65535) {
107
+        return -DMA_TUBE_CFG_ENDATA;
108
+    }
109
+    if (!cfg_dev_ok(dev, cfg)) {
110
+        return -DMA_TUBE_CFG_EDEV;
111
+    }
112
+    if (!cfg_mem_ok(cfg->tube_src)) {
113
+        return -DMA_TUBE_CFG_ESRC;
114
+    }
115
+    if (!cfg_mem_ok(cfg->tube_dst)) {
116
+        return -DMA_TUBE_CFG_EDST;
117
+    }
118
+    if (!cfg_dir_ok(cfg)) {
119
+        return -DMA_TUBE_CFG_EDIR;
120
+    }
121
+    return DMA_TUBE_CFG_SUCCESS;
122
+}
123
+
124
+static inline void set_ccr(dma_tube_reg_map *chregs,
125
+                           dma_xfer_size msize, int minc,
126
+                           dma_xfer_size psize, int pinc,
127
+                           uint32 other_flags) {
128
+    chregs->CCR = ((msize << 10) | (psize << 8) |
129
+                   (minc ? DMA_CCR_MINC : 0) | (pinc ? DMA_CCR_PINC : 0) |
130
+                   other_flags);
131
+}
132
+
133
+static inline uint32 cfg_ccr_flags(unsigned tube_flags) {
134
+    /* DMA_CFG_SRC_INC and DMA_CFG_DST_INC are special */
135
+    return tube_flags & ~(DMA_CFG_SRC_INC | DMA_CFG_DST_INC);
136
+}
137
+
138
+/* Configure chregs according to cfg, where cfg->tube_dst is peripheral. */
139
+static int config_to_per(dma_tube_reg_map *chregs, dma_tube_config *cfg) {
140
+    /* Check that ->tube_src is memory (if it's anything else, we
141
+     * shouldn't have been called). */
142
+    ASSERT(_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM);
143
+
144
+    set_ccr(chregs,
145
+            cfg->tube_src_size, cfg->tube_flags & DMA_CFG_SRC_INC,
146
+            cfg->tube_dst_size, cfg->tube_flags & DMA_CFG_DST_INC,
147
+            (cfg_ccr_flags(cfg->tube_flags) | DMA_CCR_DIR_FROM_MEM));
148
+    chregs->CMAR = (uint32)cfg->tube_src;
149
+    chregs->CPAR = (uint32)cfg->tube_dst;
150
+    return DMA_TUBE_CFG_SUCCESS;
151
+}
152
+
153
+/* Configure chregs according to cfg, where cfg->tube_dst is memory. */
154
+static int config_to_mem(dma_tube_reg_map *chregs, dma_tube_config *cfg) {
155
+    uint32 mem2mem;
156
+
157
+    if ((_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM) &&
158
+        (cfg->tube_flags & DMA_CFG_CIRC)) {
159
+        /* Can't do mem-to-mem and circular mode */
160
+        return -DMA_TUBE_CFG_ECFG;
161
+    }
162
+
163
+    mem2mem = (_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM ?
164
+               DMA_CCR_MEM2MEM : 0);
165
+    set_ccr(chregs,
166
+            cfg->tube_dst_size, cfg->tube_flags & DMA_CFG_DST_INC,
167
+            cfg->tube_src_size, cfg->tube_flags & DMA_CFG_SRC_INC,
168
+            (cfg_ccr_flags(cfg->tube_flags) |
169
+             DMA_CCR_DIR_FROM_PER |
170
+             mem2mem));
171
+    chregs->CNDTR = cfg->tube_nr_xfers;
172
+    chregs->CMAR = (uint32)cfg->tube_dst;
173
+    chregs->CPAR = (uint32)cfg->tube_src;
174
+    return DMA_TUBE_CFG_SUCCESS;
175
+}
176
+
177
+/*
178
+ * Routines
179
+ */
180
+
181
+int dma_tube_cfg(dma_dev *dev, dma_channel channel, dma_tube_config *cfg) {
182
+    dma_tube_reg_map *chregs;
183
+    int ret = preconfig_check(dev, channel, cfg);
184
+
185
+    if (ret < 0) {
186
+        return ret;
187
+    }
188
+
189
+    dma_disable(dev, channel);        /* Must disable before reconfiguring */
190
+    dma_clear_isr_bits(dev, channel); /* For sanity and consistency
191
+                                       * with STM32F2. */
192
+
193
+    chregs = dma_tube_regs(dev, channel);
194
+    switch (_dma_addr_type(cfg->tube_dst)) {
195
+    case DMA_ATYPE_PER:
196
+        ret = config_to_per(chregs, cfg);
197
+        break;
198
+    case DMA_ATYPE_MEM:
199
+        ret = config_to_mem(chregs, cfg);
200
+        break;
201
+    default:
202
+        /* Can't happen */
203
+        ASSERT(0);
204
+        return -DMA_TUBE_CFG_ECFG;
205
+    }
206
+    if (ret < 0) {
207
+        return ret;
208
+    }
209
+    chregs->CNDTR = cfg->tube_nr_xfers;
210
+    return DMA_TUBE_CFG_SUCCESS;
211
+}
212
+
213
+void dma_set_priority(dma_dev *dev,
214
+                      dma_channel channel,
215
+                      dma_priority priority) {
216
+    dma_channel_reg_map *channel_regs;
217
+    uint32 ccr;
218
+
219
+    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
220
+
221
+    channel_regs = dma_channel_regs(dev, channel);
222
+    ccr = channel_regs->CCR;
223
+    ccr &= ~DMA_CCR_PL;
224
+    ccr |= (priority << 12);
225
+    channel_regs->CCR = ccr;
226
+}
227
+
228
+void dma_set_num_transfers(dma_dev *dev,
229
+                           dma_channel channel,
230
+                           uint16 num_transfers) {
231
+    dma_channel_reg_map *channel_regs;
232
+
233
+    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
234
+
235
+    channel_regs = dma_channel_regs(dev, channel);
236
+    channel_regs->CNDTR = num_transfers;
237
+}
238
+
239
+void dma_attach_interrupt(dma_dev *dev, dma_channel channel,
240
+                          void (*handler)(void)) {
241
+    DMA_GET_HANDLER(dev, channel) = handler;
242
+    nvic_irq_enable(dev->handlers[channel - 1].irq_line);
243
+}
244
+
245
+void dma_detach_interrupt(dma_dev *dev, dma_channel channel) {
246
+    /* Don't use nvic_irq_disable()! Think about DMA2 channels 4 and 5. */
247
+    dma_channel_regs(dev, channel)->CCR &= ~0xF;
248
+    DMA_GET_HANDLER(dev, channel) = NULL;
249
+}
250
+
251
+void dma_enable(dma_dev *dev, dma_channel channel) {
252
+    dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel);
253
+    bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 1);
254
+}
255
+
256
+void dma_disable(dma_dev *dev, dma_channel channel) {
257
+    dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel);
258
+    bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 0);
259
+}
260
+
261
+dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) {
262
+    /* Grab and clear the ISR bits. */
263
+    uint8 status_bits = dma_get_isr_bits(dev, channel);
264
+    dma_clear_isr_bits(dev, channel);
265
+
266
+    /* If the channel global interrupt flag is cleared, then
267
+     * something's very wrong. */
268
+    ASSERT(status_bits & 0x1);
269
+    /* If GIF is set, then some other flag should be set, barring
270
+     * something unexpected (e.g. the user making an unforeseen IFCR
271
+     * write). */
272
+    ASSERT(status_bits != 0x1);
273
+
274
+    /* ISR flags get set even if the corresponding interrupt enable
275
+     * bits in the channel's configuration register are cleared, so we
276
+     * can't use a switch here.
277
+     *
278
+     * Don't change the order of these if statements. */
279
+    if (status_bits & 0x8) {
280
+        return DMA_TRANSFER_ERROR;
281
+    } else if (status_bits & 0x2) {
282
+        return DMA_TRANSFER_COMPLETE;
283
+    } else if (status_bits & 0x4) {
284
+        return DMA_TRANSFER_HALF_COMPLETE;
285
+    }
286
+
287
+    /* If we get here, one of our assumptions has been violated, but
288
+     * the debug level is too low for the above ASSERTs() to have had
289
+     * any effect. In order to fail fast, mimic the DMA controller's
290
+     * behavior when an error occurs. */
291
+    dma_disable(dev, channel);
292
+    return DMA_TRANSFER_ERROR;
293
+}
294
+
295
+void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *addr) {
296
+    dma_channel_reg_map *chan_regs;
297
+
298
+    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
299
+
300
+    chan_regs = dma_channel_regs(dev, channel);
301
+    chan_regs->CMAR = (uint32)addr;
302
+}
303
+
304
+void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *addr) {
305
+    dma_channel_reg_map *chan_regs;
306
+
307
+    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
308
+
309
+    chan_regs = dma_channel_regs(dev, channel);
310
+    chan_regs->CPAR = (uint32)addr;
311
+}
312
+
313
+/**
314
+ * @brief Deprecated. Use dma_tube_cfg() instead.
315
+ *
316
+ * Set up a DMA transfer.
317
+ *
318
+ * The channel will be disabled before being reconfigured.  The
319
+ * transfer will have low priority by default.  You may choose another
320
+ * priority before the transfer begins using dma_set_priority(), as
321
+ * well as performing any other configuration you desire.  When the
322
+ * channel is configured to your liking, enable it using dma_enable().
323
+ *
324
+ * @param dev DMA device.
325
+ * @param channel DMA channel.
326
+ * @param peripheral_address Base address of peripheral data register
327
+ *                           involved in the transfer.
328
+ * @param peripheral_size Peripheral data transfer size.
329
+ * @param memory_address Base memory address involved in the transfer.
330
+ * @param memory_size Memory data transfer size.
331
+ * @param mode Logical OR of dma_mode_flags
332
+ *
333
+ * @see dma_tube_cfg()
334
+ *
335
+ * @sideeffect Disables the given DMA channel.
336
+ * @see dma_xfer_size
337
+ * @see dma_mode_flags
338
+ * @see dma_set_num_transfers()
339
+ * @see dma_set_priority()
340
+ * @see dma_attach_interrupt()
341
+ * @see dma_enable()
342
+ */
343
+__deprecated
344
+void dma_setup_transfer(dma_dev       *dev,
345
+                        dma_channel    channel,
346
+                        __io void     *peripheral_address,
347
+                        dma_xfer_size  peripheral_size,
348
+                        __io void     *memory_address,
349
+                        dma_xfer_size  memory_size,
350
+                        uint32         mode) {
351
+    dma_channel_reg_map *channel_regs = dma_channel_regs(dev, channel);
352
+
353
+    dma_disable(dev, channel);  /* can't write to CMAR/CPAR otherwise */
354
+    channel_regs->CCR = (memory_size << 10) | (peripheral_size << 8) | mode;
355
+    channel_regs->CMAR = (uint32)memory_address;
356
+    channel_regs->CPAR = (uint32)peripheral_address;
357
+}
358
+
359
+/*
360
+ * IRQ handlers
361
+ */
362
+
363
+void __irq_dma1_channel1(void) {
364
+    dma_irq_handler(DMA1, DMA_CH1);
365
+}
366
+
367
+void __irq_dma1_channel2(void) {
368
+    dma_irq_handler(DMA1, DMA_CH2);
369
+}
370
+
371
+void __irq_dma1_channel3(void) {
372
+    dma_irq_handler(DMA1, DMA_CH3);
373
+}
374
+
375
+void __irq_dma1_channel4(void) {
376
+    dma_irq_handler(DMA1, DMA_CH4);
377
+}
378
+
379
+void __irq_dma1_channel5(void) {
380
+    dma_irq_handler(DMA1, DMA_CH5);
381
+}
382
+
383
+void __irq_dma1_channel6(void) {
384
+    dma_irq_handler(DMA1, DMA_CH6);
385
+}
386
+
387
+void __irq_dma1_channel7(void) {
388
+    dma_irq_handler(DMA1, DMA_CH7);
389
+}
390
+
391
+#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
392
+void __irq_dma2_channel1(void) {
393
+    dma_irq_handler(DMA2, DMA_CH1);
394
+}
395
+
396
+void __irq_dma2_channel2(void) {
397
+    dma_irq_handler(DMA2, DMA_CH2);
398
+}
399
+
400
+void __irq_dma2_channel3(void) {
401
+    dma_irq_handler(DMA2, DMA_CH3);
402
+}
403
+
404
+void __irq_dma2_channel4_5(void) {
405
+    if ((DMA2_BASE->CCR4 & DMA_CCR_EN) && (DMA2_BASE->ISR & DMA_ISR_GIF4)) {
406
+        dma_irq_handler(DMA2, DMA_CH4);
407
+    }
408
+    if ((DMA2_BASE->CCR5 & DMA_CCR_EN) && (DMA2_BASE->ISR & DMA_ISR_GIF5)) {
409
+        dma_irq_handler(DMA2, DMA_CH5);
410
+    }
411
+}
412
+#endif

+ 32 - 0
libmaple/stm32f1/exti.c 파일 보기

@@ -0,0 +1,32 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+*****************************************************************************/
26
+
27
+#include <libmaple/gpio.h>
28
+#include "exti_private.h"
29
+
30
+void exti_select(exti_num num, exti_cfg port) {
31
+    exti_do_select(&AFIO_BASE->EXTICR1 + num / 4, num, port);
32
+}

libmaple/fsmc.c → libmaple/stm32f1/fsmc.c 파일 보기

@@ -1,6 +1,7 @@
1 1
 /******************************************************************************
2 2
  * The MIT License
3 3
  *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
4 5
  * Copyright (c) 2010 Bryan Newbold.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
@@ -25,18 +26,19 @@
25 26
  *****************************************************************************/
26 27
 
27 28
 /**
28
- * @file fsmc.c
29
- * @brief Flexible static memory controller support.
29
+ * @file libmaple/stm32f1/fsmc.c
30
+ * @author Marti Bolivar <mbolivar@leaflabs.com>,
31
+ *         Bryan Newbold <bnewbold@robocracy.org>
32
+ * @brief STM32F1 FSMC support.
30 33
  */
31 34
 
32
-#include "fsmc.h"
33
-#include "gpio.h"
35
+#include <libmaple/stm32.h>
34 36
 
35
-#ifdef STM32_HIGH_DENSITY
37
+#if STM32_HAVE_FSMC /* Don't try building the rest for MCUs without FSMC */
38
+
39
+#include <libmaple/fsmc.h>
40
+#include <libmaple/gpio.h>
36 41
 
37
-/**
38
- * Configure FSMC GPIOs for use with SRAM.
39
- */
40 42
 void fsmc_sram_init_gpios(void) {
41 43
     /* Data lines... */
42 44
     gpio_set_mode(GPIOD,  0, GPIO_AF_OUTPUT_PP);
@@ -90,4 +92,4 @@ void fsmc_sram_init_gpios(void) {
90 92
     gpio_set_mode(GPIOE,  1, GPIO_AF_OUTPUT_PP);   // NBL1
91 93
 }
92 94
 
93
-#endif  /* STM32_HIGH_DENSITY */
95
+#endif  /* STM32_HAVE_FSMC */

+ 166 - 0
libmaple/stm32f1/gpio.c 파일 보기

@@ -0,0 +1,166 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Perry Hung.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @file libmaple/stm32f1/gpio.c
29
+ * @brief STM32F1 GPIO support.
30
+ */
31
+
32
+#include <libmaple/gpio.h>
33
+#include <libmaple/rcc.h>
34
+
35
+/*
36
+ * GPIO devices
37
+ */
38
+
39
+gpio_dev gpioa = {
40
+    .regs      = GPIOA_BASE,
41
+    .clk_id    = RCC_GPIOA,
42
+    .exti_port = EXTI_PA,
43
+};
44
+/** GPIO port A device. */
45
+gpio_dev* const GPIOA = &gpioa;
46
+
47
+gpio_dev gpiob = {
48
+    .regs      = GPIOB_BASE,
49
+    .clk_id    = RCC_GPIOB,
50
+    .exti_port = EXTI_PB,
51
+};
52
+/** GPIO port B device. */
53
+gpio_dev* const GPIOB = &gpiob;
54
+
55
+gpio_dev gpioc = {
56
+    .regs      = GPIOC_BASE,
57
+    .clk_id    = RCC_GPIOC,
58
+    .exti_port = EXTI_PC,
59
+};
60
+/** GPIO port C device. */
61
+gpio_dev* const GPIOC = &gpioc;
62
+
63
+gpio_dev gpiod = {
64
+    .regs      = GPIOD_BASE,
65
+    .clk_id    = RCC_GPIOD,
66
+    .exti_port = EXTI_PD,
67
+};
68
+/** GPIO port D device. */
69
+gpio_dev* const GPIOD = &gpiod;
70
+
71
+#ifdef STM32_HIGH_DENSITY
72
+gpio_dev gpioe = {
73
+    .regs      = GPIOE_BASE,
74
+    .clk_id    = RCC_GPIOE,
75
+    .exti_port = EXTI_PE,
76
+};
77
+/** GPIO port E device. */
78
+gpio_dev* const GPIOE = &gpioe;
79
+
80
+gpio_dev gpiof = {
81
+    .regs      = GPIOF_BASE,
82
+    .clk_id    = RCC_GPIOF,
83
+    .exti_port = EXTI_PF,
84
+};
85
+/** GPIO port F device. */
86
+gpio_dev* const GPIOF = &gpiof;
87
+
88
+gpio_dev gpiog = {
89
+    .regs      = GPIOG_BASE,
90
+    .clk_id    = RCC_GPIOG,
91
+    .exti_port = EXTI_PG,
92
+};
93
+/** GPIO port G device. */
94
+gpio_dev* const GPIOG = &gpiog;
95
+#endif
96
+
97
+/*
98
+ * GPIO routines
99
+ */
100
+
101
+/**
102
+ * Initialize and reset all available GPIO devices.
103
+ */
104
+void gpio_init_all(void) {
105
+    gpio_init(GPIOA);
106
+    gpio_init(GPIOB);
107
+    gpio_init(GPIOC);
108
+    gpio_init(GPIOD);
109
+#ifdef STM32_HIGH_DENSITY
110
+    gpio_init(GPIOE);
111
+    gpio_init(GPIOF);
112
+    gpio_init(GPIOG);
113
+#endif
114
+}
115
+
116
+/**
117
+ * Set the mode of a GPIO pin.
118
+ *
119
+ * @param dev GPIO device.
120
+ * @param pin Pin on the device whose mode to set, 0--15.
121
+ * @param mode General purpose or alternate function mode to set the pin to.
122
+ * @see gpio_pin_mode
123
+ */
124
+void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) {
125
+    gpio_reg_map *regs = dev->regs;
126
+    __io uint32 *cr = &regs->CRL + (pin >> 3);
127
+    uint32 shift = (pin & 0x7) * 4;
128
+    uint32 tmp = *cr;
129
+
130
+    tmp &= ~(0xF << shift);
131
+    tmp |= (mode == GPIO_INPUT_PU ? GPIO_INPUT_PD : mode) << shift;
132
+    *cr = tmp;
133
+
134
+    if (mode == GPIO_INPUT_PD) {
135
+        regs->ODR &= ~(1U << pin);
136
+    } else if (mode == GPIO_INPUT_PU) {
137
+        regs->ODR |= (1U << pin);
138
+    }
139
+}
140
+
141
+/*
142
+ * AFIO
143
+ */
144
+
145
+/**
146
+ * @brief Initialize the AFIO clock, and reset the AFIO registers.
147
+ */
148
+void afio_init(void) {
149
+    rcc_clk_enable(RCC_AFIO);
150
+    rcc_reset_dev(RCC_AFIO);
151
+}
152
+
153
+#define AFIO_EXTI_SEL_MASK 0xF
154
+
155
+/**
156
+ * @brief Perform an alternate function remap.
157
+ * @param remapping Remapping to perform.
158
+ */
159
+void afio_remap(afio_remap_peripheral remapping) {
160
+    if (remapping & AFIO_REMAP_USE_MAPR2) {
161
+        remapping &= ~AFIO_REMAP_USE_MAPR2;
162
+        AFIO_BASE->MAPR2 |= remapping;
163
+    } else {
164
+        AFIO_BASE->MAPR |= remapping;
165
+    }
166
+}

+ 129 - 0
libmaple/stm32f1/i2c.c 파일 보기

@@ -0,0 +1,129 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @file libmaple/stm32f1/i2c.c
29
+ * @brief STM32F1 I2C support
30
+ */
31
+
32
+#include "i2c_private.h"
33
+#include <libmaple/i2c.h>
34
+
35
+/*
36
+ * Devices
37
+ */
38
+
39
+static i2c_dev i2c1 = I2C_DEV_OLD(1, &gpiob, 7, 6);
40
+static i2c_dev i2c2 = I2C_DEV_OLD(2, &gpiob, 11, 10);
41
+
42
+/** STM32F1 I2C device 1 */
43
+i2c_dev* const I2C1 = &i2c1;
44
+/** STM32F1 I2C device 2 */
45
+i2c_dev* const I2C2 = &i2c2;
46
+
47
+/*
48
+ * Routines
49
+ */
50
+
51
+static int i2c1_wants_remap(const i2c_dev *dev) {
52
+    /* Check if we've got I2C1 configured for SDA/SCL remap on PB9/PB8 */
53
+    return (dev->clk_id == RCC_I2C1) &&
54
+        (scl_port(dev)->clk_id == RCC_GPIOB) &&
55
+        (sda_port(dev)->clk_id == RCC_GPIOB) &&
56
+        (dev->sda_pin == 9) &&
57
+        (dev->scl_pin == 8);
58
+}
59
+
60
+void i2c_config_gpios(const i2c_dev *dev) {
61
+    if (i2c1_wants_remap(dev)) {
62
+        afio_remap(AFIO_REMAP_I2C1);
63
+    }
64
+    gpio_set_mode(sda_port(dev), dev->sda_pin, GPIO_AF_OUTPUT_OD);
65
+    gpio_set_mode(scl_port(dev), dev->scl_pin, GPIO_AF_OUTPUT_OD);
66
+}
67
+
68
+void i2c_master_release_bus(const i2c_dev *dev) {
69
+    gpio_write_bit(scl_port(dev), dev->scl_pin, 1);
70
+    gpio_write_bit(sda_port(dev), dev->sda_pin, 1);
71
+    gpio_set_mode(scl_port(dev), dev->scl_pin, GPIO_OUTPUT_OD);
72
+    gpio_set_mode(sda_port(dev), dev->sda_pin, GPIO_OUTPUT_OD);
73
+}
74
+
75
+/*
76
+ * IRQ handlers
77
+ */
78
+
79
+void __irq_i2c1_ev(void) {
80
+   _i2c_irq_handler(I2C1);
81
+}
82
+
83
+void __irq_i2c2_ev(void) {
84
+   _i2c_irq_handler(I2C2);
85
+}
86
+
87
+void __irq_i2c1_er(void) {
88
+    _i2c_irq_error_handler(I2C1);
89
+}
90
+
91
+void __irq_i2c2_er(void) {
92
+    _i2c_irq_error_handler(I2C2);
93
+}
94
+
95
+/*
96
+ * Internal APIs
97
+ */
98
+
99
+void _i2c_irq_priority_fixup(i2c_dev *dev) {
100
+    /*
101
+     * Important STM32 Errata:
102
+     *
103
+     * See STM32F10xx8 and STM32F10xxB Errata sheet (Doc ID 14574 Rev 8),
104
+     * Section 2.11.1, 2.11.2.
105
+     *
106
+     * 2.11.1:
107
+     * When the EV7, EV7_1, EV6_1, EV6_3, EV2, EV8, and EV3 events are not
108
+     * managed before the current byte is being transferred, problems may be
109
+     * encountered such as receiving an extra byte, reading the same data twice
110
+     * or missing data.
111
+     *
112
+     * 2.11.2:
113
+     * In Master Receiver mode, when closing the communication using
114
+     * method 2, the content of the last read data can be corrupted.
115
+     *
116
+     * If the user software is not able to read the data N-1 before the STOP
117
+     * condition is generated on the bus, the content of the shift register
118
+     * (data N) will be corrupted. (data N is shifted 1-bit to the left).
119
+     *
120
+     * ----------------------------------------------------------------------
121
+     *
122
+     * In order to ensure that events are not missed, the i2c interrupt must
123
+     * not be preempted. We set the i2c interrupt priority to be the highest
124
+     * interrupt in the system (priority level 0). All other interrupts have
125
+     * been initialized to priority level 16. See nvic_init().
126
+     */
127
+    nvic_irq_set_priority(dev->ev_nvic_line, 0);
128
+    nvic_irq_set_priority(dev->er_nvic_line, 0);
129
+}

+ 254 - 0
libmaple/stm32f1/include/series/adc.h 파일 보기

@@ -0,0 +1,254 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ * Copyright (c) 2010 Perry Hung.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person
8
+ * obtaining a copy of this software and associated documentation
9
+ * files (the "Software"), to deal in the Software without
10
+ * restriction, including without limitation the rights to use, copy,
11
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ * of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *****************************************************************************/
27
+
28
+/**
29
+ * @file libmaple/stm32f1/include/series/adc.h
30
+ * @author Marti Bolivar <mbolivar@leaflabs.com>,
31
+ *         Perry Hung <perry@leaflabs.com>
32
+ * @brief STM32F1 ADC header.
33
+ */
34
+
35
+#ifndef _LIBMAPLE_STM32F1_ADC_H_
36
+#define _LIBMAPLE_STM32F1_ADC_H_
37
+
38
+#include <libmaple/bitband.h>
39
+#include <libmaple/libmaple_types.h>
40
+#include <libmaple/rcc.h>       /* For the prescalers */
41
+
42
+/*
43
+ * Devices
44
+ */
45
+
46
+extern const struct adc_dev *ADC1;
47
+extern const struct adc_dev *ADC2;
48
+#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
49
+extern const struct adc_dev *ADC3;
50
+#endif
51
+
52
+/*
53
+ * Register map base pointers
54
+ */
55
+
56
+/** ADC1 register map base pointer. */
57
+#define ADC1_BASE                       ((struct adc_reg_map*)0x40012400)
58
+/** ADC2 register map base pointer. */
59
+#define ADC2_BASE                       ((struct adc_reg_map*)0x40012800)
60
+/** ADC3 register map base pointer. */
61
+#define ADC3_BASE                       ((struct adc_reg_map*)0x40013C00)
62
+
63
+/*
64
+ * Register bit definitions
65
+ */
66
+
67
+/* Control register 2 */
68
+
69
+#define ADC_CR2_ADON_BIT                0
70
+#define ADC_CR2_CONT_BIT                1
71
+#define ADC_CR2_CAL_BIT                 2
72
+#define ADC_CR2_RSTCAL_BIT              3
73
+#define ADC_CR2_DMA_BIT                 8
74
+#define ADC_CR2_ALIGN_BIT               11
75
+#define ADC_CR2_JEXTTRIG_BIT            15
76
+#define ADC_CR2_EXTTRIG_BIT             20
77
+#define ADC_CR2_JSWSTART_BIT            21
78
+#define ADC_CR2_SWSTART_BIT             22
79
+#define ADC_CR2_TSEREFE_BIT             23
80
+
81
+#define ADC_CR2_ADON                    (1U << ADC_CR2_ADON_BIT)
82
+#define ADC_CR2_CONT                    (1U << ADC_CR2_CONT_BIT)
83
+#define ADC_CR2_CAL                     (1U << ADC_CR2_CAL_BIT)
84
+#define ADC_CR2_RSTCAL                  (1U << ADC_CR2_RSTCAL_BIT)
85
+#define ADC_CR2_DMA                     (1U << ADC_CR2_DMA_BIT)
86
+#define ADC_CR2_ALIGN                   (1U << ADC_CR2_ALIGN_BIT)
87
+#define ADC_CR2_JEXTSEL                 0x7000
88
+#define ADC_CR2_JEXTTRIG                (1U << ADC_CR2_JEXTTRIG_BIT)
89
+#define ADC_CR2_EXTSEL                  0xE0000
90
+#define ADC_CR2_EXTTRIG                 (1U << ADC_CR2_EXTTRIG_BIT)
91
+#define ADC_CR2_JSWSTART                (1U << ADC_CR2_JSWSTART_BIT)
92
+#define ADC_CR2_SWSTART                 (1U << ADC_CR2_SWSTART_BIT)
93
+#define ADC_CR2_TSEREFE                 (1U << ADC_CR2_TSEREFE_BIT)
94
+
95
+/*
96
+ * Other types
97
+ */
98
+
99
+/**
100
+ * @brief STM32F1 external event selectors for regular group
101
+ *        conversion.
102
+ *
103
+ * Some external events are only available on ADCs 1 and 2, others
104
+ * only on ADC3, while others are available on all three ADCs.
105
+ * Additionally, some events are only available on high- and
106
+ * XL-density STM32F1 MCUs, as they use peripherals only available on
107
+ * those MCU densities.
108
+ *
109
+ * For ease of use, each event selector is given along with the ADCs
110
+ * it's available on, along with any other availability restrictions.
111
+ *
112
+ * @see adc_set_extsel()
113
+ */
114
+typedef enum adc_extsel_event {
115
+    /* TODO: Smarten this up a bit, as follows.
116
+     *
117
+     * The EXTSEL bits on F1 are a little brain-damaged in that the
118
+     * TIM8 TRGO event has different bits depending on whether you're
119
+     * using ADC1/2 or ADC3.  We route around this by declaring two
120
+     * enumerators, ADC_EXT_EV_ADC12_TIM8_TRGO and
121
+     * ADC_EXT_EV_ADC3_TIM8_TRGO.
122
+     *
123
+     * The right thing to do is to provide a single
124
+     * ADC_EXT_EV_TIM8_TRGO enumerator and override adc_set_extsel on
125
+     * STM32F1 to handle this situation correctly. We can do that
126
+     * later, though, and change the per-ADC enumerator values to
127
+     * ADC_EXT_EV_TIM8_TRGO to preserve compatibility. */
128
+
129
+    /* ADC1 and ADC2 only: */
130
+    ADC_EXT_EV_TIM1_CC1  = 0x00000, /**< ADC1, ADC2: Timer 1 CC1 event */
131
+    ADC_EXT_EV_TIM1_CC2  = 0x20000, /**< ADC1, ADC2: Timer 1 CC2 event */
132
+    ADC_EXT_EV_TIM2_CC2  = 0x60000, /**< ADC1, ADC2: Timer 2 CC2 event */
133
+    ADC_EXT_EV_TIM3_TRGO = 0x80000, /**< ADC1, ADC2: Timer 3 TRGO event */
134
+    ADC_EXT_EV_TIM4_CC4  = 0xA0000, /**< ADC1, ADC2: Timer 4 CC4 event */
135
+    ADC_EXT_EV_EXTI11    = 0xC0000, /**< ADC1, ADC2: EXTI11 event */
136
+
137
+    /* Common: */
138
+    ADC_EXT_EV_TIM1_CC3  = 0x40000, /**< ADC1, ADC2, ADC3: Timer 1 CC3 event */
139
+    ADC_EXT_EV_SWSTART   = 0xE0000, /**< ADC1, ADC2, ADC3: Software start */
140
+
141
+    /* HD only: */
142
+    ADC_EXT_EV_TIM3_CC1  = 0x00000, /**<
143
+                                     * ADC3: Timer 3 CC1 event
144
+                                     * Availability: high- and XL-density. */
145
+    ADC_EXT_EV_TIM2_CC3  = 0x20000, /**<
146
+                                     * ADC3: Timer 2 CC3 event
147
+                                     * Availability: high- and XL-density. */
148
+    ADC_EXT_EV_TIM8_CC1  = 0x60000, /**<
149
+                                     * ADC3: Timer 8 CC1 event
150
+                                     * Availability: high- and XL-density. */
151
+    ADC_EXT_EV_ADC3_TIM8_TRGO = 0x80000, /**<
152
+                                     * ADC3: Timer 8 TRGO event
153
+                                     * Availability: high- and XL-density. */
154
+    ADC_EXT_EV_TIM5_CC1  = 0xA0000, /**<
155
+                                     * ADC3: Timer 5 CC1 event
156
+                                     * Availability: high- and XL-density. */
157
+    ADC_EXT_EV_ADC12_TIM8_TRGO = 0xC0000, /**<
158
+                                     * ADC1, ADC2: Timer 8 TRGO event
159
+                                     * Availability: high- and XL-density. */
160
+    ADC_EXT_EV_TIM5_CC3  = 0xC0000, /**<
161
+                                     * ADC3: Timer 5 CC3 event
162
+                                     * Availability: high- and XL-density. */
163
+} adc_extsel_event;
164
+
165
+/* We'll keep these old adc_extsel_event enumerators around for a
166
+ * while, for backwards compatibility: */
167
+/** Deprecated. Use ADC_EXT_EV_TIM1_CC1 instead. */
168
+#define ADC_ADC12_TIM1_CC1  ADC_EXT_EV_TIM1_CC1
169
+/** Deprecated. Use ADC_EXT_EV_TIM1_CC2 instead. */
170
+#define ADC_ADC12_TIM1_CC2  ADC_EXT_EV_TIM1_CC2
171
+/** Deprecated. Use ADC_EXT_EV_TIM1_CC3 instead. */
172
+#define ADC_ADC12_TIM1_CC3  ADC_EXT_EV_TIM1_CC3
173
+/** Deprecated. Use ADC_EXT_EV_TIM2_CC2 instead. */
174
+#define ADC_ADC12_TIM2_CC2  ADC_EXT_EV_TIM2_CC2
175
+/** Deprecated. Use ADC_EXT_EV_TIM3_TRGO instead. */
176
+#define ADC_ADC12_TIM3_TRGO ADC_EXT_EV_TIM3_TRGO
177
+/** Deprecated. Use ADC_EXT_EV_TIM4_CC4 instead. */
178
+#define ADC_ADC12_TIM4_CC4  ADC_EXT_EV_TIM4_CC4
179
+/** Deprecated. Use ADC_EXT_EV_EXTI11 instead. */
180
+#define ADC_ADC12_EXTI11    ADC_EXT_EV_EXTI11
181
+/** Deprecated. Use ADC_EXT_EV_ADC12_TIM8_TRGO instead. */
182
+#define ADC_ADC12_TIM8_TRGO ADC_EXT_EV_ADC12_TIM8_TRGO
183
+/** Deprecated. Use ADC_EXT_EV_SWSTART instead. */
184
+#define ADC_ADC12_SWSTART   ADC_EXT_EV_SWSTART
185
+/** Deprecated. Use ADC_EXT_EV_TIM1_CC1 instead. */
186
+#define ADC_ADC3_TIM3_CC1   ADC_EXT_EV_TIM1_CC1
187
+/** Deprecated. Use ADC_EXT_EV_TIM1_CC2 instead. */
188
+#define ADC_ADC3_TIM2_CC3   ADC_EXT_EV_TIM1_CC2
189
+/** Deprecated. Use ADC_EXT_EV_TIM1_CC3 instead. */
190
+#define ADC_ADC3_TIM1_CC3   ADC_EXT_EV_TIM1_CC3
191
+/** Deprecated. Use ADC_EXT_EV_TIM2_CC2 instead. */
192
+#define ADC_ADC3_TIM8_CC1   ADC_EXT_EV_TIM2_CC2
193
+/** Deprecated. Use ADC_EXT_EV_TIM3_TRGO instead. */
194
+#define ADC_ADC3_TIM8_TRGO  ADC_EXT_EV_TIM3_TRGO
195
+/** Deprecated. Use ADC_EXT_EV_TIM4_CC4 instead. */
196
+#define ADC_ADC3_TIM5_CC1   ADC_EXT_EV_TIM4_CC4
197
+/** Deprecated. Use ADC_EXT_EV_EXTI11 instead. */
198
+#define ADC_ADC3_TIM5_CC3   ADC_EXT_EV_EXTI11
199
+/** Deprecated. Use ADC_EXT_EV_TIM8_TRGO instead. */
200
+#define ADC_ADC3_SWSTART    ADC_EXT_EV_TIM8_TRGO
201
+/** Deprecated. Use ADC_EXT_EV_SWSTART instead. */
202
+#define ADC_SWSTART         ADC_EXT_EV_SWSTART
203
+
204
+/**
205
+ * @brief STM32F1 sample times, in ADC clock cycles.
206
+ *
207
+ * These control the amount of time spent sampling the input voltage.
208
+ *
209
+ * IMPORTANT: maximum external impedance must be below 0.4kOhms for
210
+ * 1.5 cycle sampling time. At 55.5 cycles/sample, the external input
211
+ * impedance must be at most 50kOhms. See your device's datasheet for
212
+ * more information.
213
+ */
214
+typedef enum adc_smp_rate {
215
+    ADC_SMPR_1_5,               /**< 1.5 ADC cycles */
216
+    ADC_SMPR_7_5,               /**< 7.5 ADC cycles */
217
+    ADC_SMPR_13_5,              /**< 13.5 ADC cycles */
218
+    ADC_SMPR_28_5,              /**< 28.5 ADC cycles */
219
+    ADC_SMPR_41_5,              /**< 41.5 ADC cycles */
220
+    ADC_SMPR_55_5,              /**< 55.5 ADC cycles */
221
+    ADC_SMPR_71_5,              /**< 71.5 ADC cycles */
222
+    ADC_SMPR_239_5,             /**< 239.5 ADC cycles */
223
+} adc_smp_rate;
224
+
225
+/**
226
+ * @brief STM32F1 ADC prescalers, as divisors of PCLK2.
227
+ */
228
+typedef enum adc_prescaler {
229
+    ADC_PRE_PCLK2_DIV_2 = RCC_ADCPRE_PCLK_DIV_2, /** PCLK2 divided by 2 */
230
+    ADC_PRE_PCLK2_DIV_4 = RCC_ADCPRE_PCLK_DIV_4, /** PCLK2 divided by 4 */
231
+    ADC_PRE_PCLK2_DIV_6 = RCC_ADCPRE_PCLK_DIV_6, /** PCLK2 divided by 6 */
232
+    ADC_PRE_PCLK2_DIV_8 = RCC_ADCPRE_PCLK_DIV_8, /** PCLK2 divided by 8 */
233
+} adc_prescaler;
234
+
235
+/*
236
+ * Routines
237
+ */
238
+
239
+void adc_calibrate(const adc_dev *dev);
240
+
241
+/**
242
+ * @brief Set external trigger conversion mode event for regular channels
243
+ *
244
+ * Availability: STM32F1.
245
+ *
246
+ * @param dev    ADC device
247
+ * @param enable If 1, conversion on external events is enabled; if 0,
248
+ *               disabled.
249
+ */
250
+static inline void adc_set_exttrig(const adc_dev *dev, uint8 enable) {
251
+    *bb_perip(&dev->regs->CR2, ADC_CR2_EXTTRIG_BIT) = !!enable;
252
+}
253
+
254
+#endif

+ 71 - 0
libmaple/stm32f1/include/series/dac.h 파일 보기

@@ -0,0 +1,71 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @file libmaple/stm32f1/include/series/dac.h
29
+ * @brief STM32F1 DAC support
30
+ */
31
+
32
+#ifndef _LIBMAPLE_STM32F1_DAC_H_
33
+#define _LIBMAPLE_STM32F1_DAC_H_
34
+
35
+#ifdef __cplusplus
36
+extern "C"{
37
+#endif
38
+
39
+#include <libmaple/libmaple_types.h>
40
+
41
+/** STM32F1 DAC register map type. */
42
+typedef struct dac_reg_map {
43
+    __io uint32 CR;      /**< Control register */
44
+    __io uint32 SWTRIGR; /**< Software trigger register */
45
+    __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data
46
+                              holding register */
47
+    __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data
48
+                              holding register */
49
+    __io uint32 DHR8R1;  /**< Channel 1 8-bit left-aligned data
50
+                              holding register */
51
+    __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data
52
+                              holding register */
53
+    __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data
54
+                              holding register */
55
+    __io uint32 DHR8R2;  /**< Channel 2 8-bit left-aligned data
56
+                              holding register */
57
+    __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data
58
+                              holding register */
59
+    __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data
60
+                              holding register */
61
+    __io uint32 DHR8RD;  /**< Dual DAC 8-bit right-aligned data holding
62
+                              register */
63
+    __io uint32 DOR1;    /**< Channel 1 data output register */
64
+    __io uint32 DOR2;    /**< Channel 2 data output register */
65
+} dac_reg_map;
66
+
67
+#ifdef __cplusplus
68
+}
69
+#endif
70
+
71
+#endif

+ 565 - 0
libmaple/stm32f1/include/series/dma.h 파일 보기

@@ -0,0 +1,565 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Michael Hope.
5
+ * Copyright (c) 2012 LeafLabs, LLC
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person
8
+ * obtaining a copy of this software and associated documentation
9
+ * files (the "Software"), to deal in the Software without
10
+ * restriction, including without limitation the rights to use, copy,
11
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ * of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *****************************************************************************/
27
+
28
+/**
29
+ * @file libmaple/stm32f1/include/series/dma.h
30
+ * @author Marti Bolivar <mbolivar@leaflabs.com>;
31
+ *         Original implementation by Michael Hope
32
+ * @brief STM32F1 DMA series header.
33
+ */
34
+
35
+/*
36
+ * See /notes/dma-stm32f1.txt for more information.
37
+ */
38
+
39
+#ifndef _LIBMAPLE_STM32F1_DMA_H_
40
+#define _LIBMAPLE_STM32F1_DMA_H_
41
+
42
+#ifdef __cplusplus
43
+extern "C"{
44
+#endif
45
+
46
+#include <libmaple/libmaple_types.h>
47
+#include <libmaple/dma_common.h>
48
+
49
+/*
50
+ * Register maps and base pointers
51
+ */
52
+
53
+/**
54
+ * @brief STM32F1 DMA register map type.
55
+ *
56
+ * Note that DMA controller 2 (register map base pointer DMA2_BASE)
57
+ * only supports channels 1--5.
58
+ */
59
+typedef struct dma_reg_map {
60
+    __io uint32 ISR;            /**< Interrupt status register */
61
+    __io uint32 IFCR;           /**< Interrupt flag clear register */
62
+    __io uint32 CCR1;           /**< Channel 1 configuration register */
63
+    __io uint32 CNDTR1;         /**< Channel 1 number of data register */
64
+    __io uint32 CPAR1;          /**< Channel 1 peripheral address register */
65
+    __io uint32 CMAR1;          /**< Channel 1 memory address register */
66
+    const uint32 RESERVED1;     /**< Reserved. */
67
+    __io uint32 CCR2;           /**< Channel 2 configuration register */
68
+    __io uint32 CNDTR2;         /**< Channel 2 number of data register */
69
+    __io uint32 CPAR2;          /**< Channel 2 peripheral address register */
70
+    __io uint32 CMAR2;          /**< Channel 2 memory address register */
71
+    const uint32 RESERVED2;     /**< Reserved. */
72
+    __io uint32 CCR3;           /**< Channel 3 configuration register */
73
+    __io uint32 CNDTR3;         /**< Channel 3 number of data register */
74
+    __io uint32 CPAR3;          /**< Channel 3 peripheral address register */
75
+    __io uint32 CMAR3;          /**< Channel 3 memory address register */
76
+    const uint32 RESERVED3;     /**< Reserved. */
77
+    __io uint32 CCR4;           /**< Channel 4 configuration register */
78
+    __io uint32 CNDTR4;         /**< Channel 4 number of data register */
79
+    __io uint32 CPAR4;          /**< Channel 4 peripheral address register */
80
+    __io uint32 CMAR4;          /**< Channel 4 memory address register */
81
+    const uint32 RESERVED4;     /**< Reserved. */
82
+    __io uint32 CCR5;           /**< Channel 5 configuration register */
83
+    __io uint32 CNDTR5;         /**< Channel 5 number of data register */
84
+    __io uint32 CPAR5;          /**< Channel 5 peripheral address register */
85
+    __io uint32 CMAR5;          /**< Channel 5 memory address register */
86
+    const uint32 RESERVED5;     /**< Reserved. */
87
+    __io uint32 CCR6;           /**< Channel 6 configuration register */
88
+    __io uint32 CNDTR6;         /**< Channel 6 number of data register */
89
+    __io uint32 CPAR6;          /**< Channel 6 peripheral address register */
90
+    __io uint32 CMAR6;          /**< Channel 6 memory address register */
91
+    const uint32 RESERVED6;     /**< Reserved. */
92
+    __io uint32 CCR7;           /**< Channel 7 configuration register */
93
+    __io uint32 CNDTR7;         /**< Channel 7 number of data register */
94
+    __io uint32 CPAR7;          /**< Channel 7 peripheral address register */
95
+    __io uint32 CMAR7;          /**< Channel 7 memory address register */
96
+    const uint32 RESERVED7;     /**< Reserved. */
97
+} dma_reg_map;
98
+
99
+/** DMA controller 1 register map base pointer */
100
+#define DMA1_BASE                       ((struct dma_reg_map*)0x40020000)
101
+/** DMA controller 2 register map base pointer */
102
+#define DMA2_BASE                       ((struct dma_reg_map*)0x40020400)
103
+
104
+/**
105
+ * @brief STM32F1 DMA channel (i.e. tube) register map type.
106
+ * Provides access to an individual channel's registers.
107
+ * @see dma_tube_regs()
108
+ */
109
+typedef struct dma_tube_reg_map {
110
+    __io uint32 CCR;           /**< Channel configuration register */
111
+    __io uint32 CNDTR;         /**< Channel number of data register */
112
+    __io uint32 CPAR;          /**< Channel peripheral address register */
113
+    __io uint32 CMAR;          /**< Channel memory address register */
114
+} dma_tube_reg_map;
115
+
116
+/** DMA1 channel 1 register map base pointer */
117
+#define DMA1CH1_BASE                ((struct dma_tube_reg_map*)0x40020008)
118
+/** DMA1 channel 2 register map base pointer */
119
+#define DMA1CH2_BASE                ((struct dma_tube_reg_map*)0x4002001C)
120
+/** DMA1 channel 3 register map base pointer */
121
+#define DMA1CH3_BASE                ((struct dma_tube_reg_map*)0x40020030)
122
+/** DMA1 channel 4 register map base pointer */
123
+#define DMA1CH4_BASE                ((struct dma_tube_reg_map*)0x40020044)
124
+/** DMA1 channel 5 register map base pointer */
125
+#define DMA1CH5_BASE                ((struct dma_tube_reg_map*)0x40020058)
126
+/** DMA1 channel 6 register map base pointer */
127
+#define DMA1CH6_BASE                ((struct dma_tube_reg_map*)0x4002006C)
128
+/** DMA1 channel 7 register map base pointer */
129
+#define DMA1CH7_BASE                ((struct dma_tube_reg_map*)0x40020080)
130
+
131
+/** DMA2 channel 1 register map base pointer */
132
+#define DMA2CH1_BASE                ((struct dma_tube_reg_map*)0x40020408)
133
+/** DMA2 channel 2 register map base pointer */
134
+#define DMA2CH2_BASE                ((struct dma_tube_reg_map*)0x4002041C)
135
+/** DMA2 channel 3 register map base pointer */
136
+#define DMA2CH3_BASE                ((struct dma_tube_reg_map*)0x40020430)
137
+/** DMA2 channel 4 register map base pointer */
138
+#define DMA2CH4_BASE                ((struct dma_tube_reg_map*)0x40020444)
139
+/** DMA2 channel 5 register map base pointer */
140
+#define DMA2CH5_BASE                ((struct dma_tube_reg_map*)0x40020458)
141
+
142
+/*
143
+ * Register bit definitions
144
+ */
145
+
146
+/* Interrupt status register */
147
+
148
+#define DMA_ISR_TEIF7_BIT               27
149
+#define DMA_ISR_HTIF7_BIT               26
150
+#define DMA_ISR_TCIF7_BIT               25
151
+#define DMA_ISR_GIF7_BIT                24
152
+#define DMA_ISR_TEIF6_BIT               23
153
+#define DMA_ISR_HTIF6_BIT               22
154
+#define DMA_ISR_TCIF6_BIT               21
155
+#define DMA_ISR_GIF6_BIT                20
156
+#define DMA_ISR_TEIF5_BIT               19
157
+#define DMA_ISR_HTIF5_BIT               18
158
+#define DMA_ISR_TCIF5_BIT               17
159
+#define DMA_ISR_GIF5_BIT                16
160
+#define DMA_ISR_TEIF4_BIT               15
161
+#define DMA_ISR_HTIF4_BIT               14
162
+#define DMA_ISR_TCIF4_BIT               13
163
+#define DMA_ISR_GIF4_BIT                12
164
+#define DMA_ISR_TEIF3_BIT               11
165
+#define DMA_ISR_HTIF3_BIT               10
166
+#define DMA_ISR_TCIF3_BIT               9
167
+#define DMA_ISR_GIF3_BIT                8
168
+#define DMA_ISR_TEIF2_BIT               7
169
+#define DMA_ISR_HTIF2_BIT               6
170
+#define DMA_ISR_TCIF2_BIT               5
171
+#define DMA_ISR_GIF2_BIT                4
172
+#define DMA_ISR_TEIF1_BIT               3
173
+#define DMA_ISR_HTIF1_BIT               2
174
+#define DMA_ISR_TCIF1_BIT               1
175
+#define DMA_ISR_GIF1_BIT                0
176
+
177
+#define DMA_ISR_TEIF7                   (1U << DMA_ISR_TEIF7_BIT)
178
+#define DMA_ISR_HTIF7                   (1U << DMA_ISR_HTIF7_BIT)
179
+#define DMA_ISR_TCIF7                   (1U << DMA_ISR_TCIF7_BIT)
180
+#define DMA_ISR_GIF7                    (1U << DMA_ISR_GIF7_BIT)
181
+#define DMA_ISR_TEIF6                   (1U << DMA_ISR_TEIF6_BIT)
182
+#define DMA_ISR_HTIF6                   (1U << DMA_ISR_HTIF6_BIT)
183
+#define DMA_ISR_TCIF6                   (1U << DMA_ISR_TCIF6_BIT)
184
+#define DMA_ISR_GIF6                    (1U << DMA_ISR_GIF6_BIT)
185
+#define DMA_ISR_TEIF5                   (1U << DMA_ISR_TEIF5_BIT)
186
+#define DMA_ISR_HTIF5                   (1U << DMA_ISR_HTIF5_BIT)
187
+#define DMA_ISR_TCIF5                   (1U << DMA_ISR_TCIF5_BIT)
188
+#define DMA_ISR_GIF5                    (1U << DMA_ISR_GIF5_BIT)
189
+#define DMA_ISR_TEIF4                   (1U << DMA_ISR_TEIF4_BIT)
190
+#define DMA_ISR_HTIF4                   (1U << DMA_ISR_HTIF4_BIT)
191
+#define DMA_ISR_TCIF4                   (1U << DMA_ISR_TCIF4_BIT)
192
+#define DMA_ISR_GIF4                    (1U << DMA_ISR_GIF4_BIT)
193
+#define DMA_ISR_TEIF3                   (1U << DMA_ISR_TEIF3_BIT)
194
+#define DMA_ISR_HTIF3                   (1U << DMA_ISR_HTIF3_BIT)
195
+#define DMA_ISR_TCIF3                   (1U << DMA_ISR_TCIF3_BIT)
196
+#define DMA_ISR_GIF3                    (1U << DMA_ISR_GIF3_BIT)
197
+#define DMA_ISR_TEIF2                   (1U << DMA_ISR_TEIF2_BIT)
198
+#define DMA_ISR_HTIF2                   (1U << DMA_ISR_HTIF2_BIT)
199
+#define DMA_ISR_TCIF2                   (1U << DMA_ISR_TCIF2_BIT)
200
+#define DMA_ISR_GIF2                    (1U << DMA_ISR_GIF2_BIT)
201
+#define DMA_ISR_TEIF1                   (1U << DMA_ISR_TEIF1_BIT)
202
+#define DMA_ISR_HTIF1                   (1U << DMA_ISR_HTIF1_BIT)
203
+#define DMA_ISR_TCIF1                   (1U << DMA_ISR_TCIF1_BIT)
204
+#define DMA_ISR_GIF1                    (1U << DMA_ISR_GIF1_BIT)
205
+
206
+/* Interrupt flag clear register */
207
+
208
+#define DMA_IFCR_CTEIF7_BIT             27
209
+#define DMA_IFCR_CHTIF7_BIT             26
210
+#define DMA_IFCR_CTCIF7_BIT             25
211
+#define DMA_IFCR_CGIF7_BIT              24
212
+#define DMA_IFCR_CTEIF6_BIT             23
213
+#define DMA_IFCR_CHTIF6_BIT             22
214
+#define DMA_IFCR_CTCIF6_BIT             21
215
+#define DMA_IFCR_CGIF6_BIT              20
216
+#define DMA_IFCR_CTEIF5_BIT             19
217
+#define DMA_IFCR_CHTIF5_BIT             18
218
+#define DMA_IFCR_CTCIF5_BIT             17
219
+#define DMA_IFCR_CGIF5_BIT              16
220
+#define DMA_IFCR_CTEIF4_BIT             15
221
+#define DMA_IFCR_CHTIF4_BIT             14
222
+#define DMA_IFCR_CTCIF4_BIT             13
223
+#define DMA_IFCR_CGIF4_BIT              12
224
+#define DMA_IFCR_CTEIF3_BIT             11
225
+#define DMA_IFCR_CHTIF3_BIT             10
226
+#define DMA_IFCR_CTCIF3_BIT             9
227
+#define DMA_IFCR_CGIF3_BIT              8
228
+#define DMA_IFCR_CTEIF2_BIT             7
229
+#define DMA_IFCR_CHTIF2_BIT             6
230
+#define DMA_IFCR_CTCIF2_BIT             5
231
+#define DMA_IFCR_CGIF2_BIT              4
232
+#define DMA_IFCR_CTEIF1_BIT             3
233
+#define DMA_IFCR_CHTIF1_BIT             2
234
+#define DMA_IFCR_CTCIF1_BIT             1
235
+#define DMA_IFCR_CGIF1_BIT              0
236
+
237
+#define DMA_IFCR_CTEIF7                 (1U << DMA_IFCR_CTEIF7_BIT)
238
+#define DMA_IFCR_CHTIF7                 (1U << DMA_IFCR_CHTIF7_BIT)
239
+#define DMA_IFCR_CTCIF7                 (1U << DMA_IFCR_CTCIF7_BIT)
240
+#define DMA_IFCR_CGIF7                  (1U << DMA_IFCR_CGIF7_BIT)
241
+#define DMA_IFCR_CTEIF6                 (1U << DMA_IFCR_CTEIF6_BIT)
242
+#define DMA_IFCR_CHTIF6                 (1U << DMA_IFCR_CHTIF6_BIT)
243
+#define DMA_IFCR_CTCIF6                 (1U << DMA_IFCR_CTCIF6_BIT)
244
+#define DMA_IFCR_CGIF6                  (1U << DMA_IFCR_CGIF6_BIT)
245
+#define DMA_IFCR_CTEIF5                 (1U << DMA_IFCR_CTEIF5_BIT)
246
+#define DMA_IFCR_CHTIF5                 (1U << DMA_IFCR_CHTIF5_BIT)
247
+#define DMA_IFCR_CTCIF5                 (1U << DMA_IFCR_CTCIF5_BIT)
248
+#define DMA_IFCR_CGIF5                  (1U << DMA_IFCR_CGIF5_BIT)
249
+#define DMA_IFCR_CTEIF4                 (1U << DMA_IFCR_CTEIF4_BIT)
250
+#define DMA_IFCR_CHTIF4                 (1U << DMA_IFCR_CHTIF4_BIT)
251
+#define DMA_IFCR_CTCIF4                 (1U << DMA_IFCR_CTCIF4_BIT)
252
+#define DMA_IFCR_CGIF4                  (1U << DMA_IFCR_CGIF4_BIT)
253
+#define DMA_IFCR_CTEIF3                 (1U << DMA_IFCR_CTEIF3_BIT)
254
+#define DMA_IFCR_CHTIF3                 (1U << DMA_IFCR_CHTIF3_BIT)
255
+#define DMA_IFCR_CTCIF3                 (1U << DMA_IFCR_CTCIF3_BIT)
256
+#define DMA_IFCR_CGIF3                  (1U << DMA_IFCR_CGIF3_BIT)
257
+#define DMA_IFCR_CTEIF2                 (1U << DMA_IFCR_CTEIF2_BIT)
258
+#define DMA_IFCR_CHTIF2                 (1U << DMA_IFCR_CHTIF2_BIT)
259
+#define DMA_IFCR_CTCIF2                 (1U << DMA_IFCR_CTCIF2_BIT)
260
+#define DMA_IFCR_CGIF2                  (1U << DMA_IFCR_CGIF2_BIT)
261
+#define DMA_IFCR_CTEIF1                 (1U << DMA_IFCR_CTEIF1_BIT)
262
+#define DMA_IFCR_CHTIF1                 (1U << DMA_IFCR_CHTIF1_BIT)
263
+#define DMA_IFCR_CTCIF1                 (1U << DMA_IFCR_CTCIF1_BIT)
264
+#define DMA_IFCR_CGIF1                  (1U << DMA_IFCR_CGIF1_BIT)
265
+
266
+/* Channel configuration register */
267
+
268
+#define DMA_CCR_MEM2MEM_BIT             14
269
+#define DMA_CCR_MINC_BIT                7
270
+#define DMA_CCR_PINC_BIT                6
271
+#define DMA_CCR_CIRC_BIT                5
272
+#define DMA_CCR_DIR_BIT                 4
273
+#define DMA_CCR_TEIE_BIT                3
274
+#define DMA_CCR_HTIE_BIT                2
275
+#define DMA_CCR_TCIE_BIT                1
276
+#define DMA_CCR_EN_BIT                  0
277
+
278
+#define DMA_CCR_MEM2MEM                 (1U << DMA_CCR_MEM2MEM_BIT)
279
+#define DMA_CCR_PL                      (0x3 << 12)
280
+#define DMA_CCR_PL_LOW                  (0x0 << 12)
281
+#define DMA_CCR_PL_MEDIUM               (0x1 << 12)
282
+#define DMA_CCR_PL_HIGH                 (0x2 << 12)
283
+#define DMA_CCR_PL_VERY_HIGH            (0x3 << 12)
284
+#define DMA_CCR_MSIZE                   (0x3 << 10)
285
+#define DMA_CCR_MSIZE_8BITS             (0x0 << 10)
286
+#define DMA_CCR_MSIZE_16BITS            (0x1 << 10)
287
+#define DMA_CCR_MSIZE_32BITS            (0x2 << 10)
288
+#define DMA_CCR_PSIZE                   (0x3 << 8)
289
+#define DMA_CCR_PSIZE_8BITS             (0x0 << 8)
290
+#define DMA_CCR_PSIZE_16BITS            (0x1 << 8)
291
+#define DMA_CCR_PSIZE_32BITS            (0x2 << 8)
292
+#define DMA_CCR_MINC                    (1U << DMA_CCR_MINC_BIT)
293
+#define DMA_CCR_PINC                    (1U << DMA_CCR_PINC_BIT)
294
+#define DMA_CCR_CIRC                    (1U << DMA_CCR_CIRC_BIT)
295
+#define DMA_CCR_DIR                     (1U << DMA_CCR_DIR_BIT)
296
+#define DMA_CCR_DIR_FROM_PER            (0U << DMA_CCR_DIR_BIT)
297
+#define DMA_CCR_DIR_FROM_MEM            (1U << DMA_CCR_DIR_BIT)
298
+#define DMA_CCR_TEIE                    (1U << DMA_CCR_TEIE_BIT)
299
+#define DMA_CCR_HTIE                    (1U << DMA_CCR_HTIE_BIT)
300
+#define DMA_CCR_TCIE                    (1U << DMA_CCR_TCIE_BIT)
301
+#define DMA_CCR_EN                      (1U << DMA_CCR_EN_BIT)
302
+
303
+/*
304
+ * Devices
305
+ */
306
+
307
+extern dma_dev *DMA1;
308
+#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
309
+extern dma_dev *DMA2;
310
+#endif
311
+
312
+/*
313
+ * Other types needed by, or useful for, <libmaple/dma.h>.
314
+ */
315
+
316
+/**
317
+ * @brief STM32F1 dma_tube.
318
+ * On STM32F1, DMA tubes are just channels.
319
+ */
320
+#define dma_tube dma_channel
321
+
322
+/**
323
+ * @brief On STM32F1, dma_channel_reg_map is an alias for dma_tube_reg_map.
324
+ * This is for backwards compatibility. */
325
+#define dma_channel_reg_map dma_tube_reg_map
326
+
327
+/**
328
+ * @brief STM32F1 configuration flags for dma_tube_config
329
+ * @see struct dma_tube_config
330
+ */
331
+typedef enum dma_cfg_flags {
332
+    /**
333
+     * Source address increment mode
334
+     *
335
+     * If this flag is set, the source address is incremented (by the
336
+     * source size) after each DMA transfer.
337
+     */
338
+    DMA_CFG_SRC_INC = 1U << 31,
339
+
340
+    /**
341
+     * Destination address increment mode
342
+     *
343
+     * If this flag is set, the destination address is incremented (by
344
+     * the destination size) after each DMA transfer.
345
+     */
346
+    DMA_CFG_DST_INC = 1U << 30,
347
+
348
+    /**
349
+     * Circular mode
350
+     *
351
+     * This mode is not available for memory-to-memory transfers.
352
+     */
353
+    DMA_CFG_CIRC = DMA_CCR_CIRC,
354
+
355
+    /** Transfer complete interrupt enable */
356
+    DMA_CFG_CMPLT_IE      = DMA_CCR_TCIE,
357
+    /** Transfer half-complete interrupt enable  */
358
+    DMA_CFG_HALF_CMPLT_IE = DMA_CCR_HTIE,
359
+    /** Transfer error interrupt enable */
360
+    DMA_CFG_ERR_IE        = DMA_CCR_TEIE,
361
+} dma_cfg_flags;
362
+
363
+/**
364
+ * @brief STM32F1 DMA request sources.
365
+ *
366
+ * IMPORTANT:
367
+ *
368
+ * 1. On STM32F1, each dma_request_src can only be used by a
369
+ * particular tube on a particular DMA controller. For example,
370
+ * DMA_REQ_SRC_ADC1 belongs to DMA1, tube 1. DMA2 cannot serve
371
+ * requests from ADC1, nor can DMA1 tube 2, etc. If you try to use a
372
+ * request source with the wrong DMA controller or tube on STM32F1,
373
+ * dma_tube_cfg() will fail.
374
+ *
375
+ * 2. In general, a DMA tube can only serve a single request source at
376
+ * a time, and on STM32F1, Terrible Super-Bad Things will happen if
377
+ * two request sources are active for a single tube.
378
+ *
379
+ * To make all this easier to sort out, these dma_request_src
380
+ * enumerators are grouped by DMA controller and tube.
381
+ *
382
+ * @see struct dma_tube_config
383
+ * @see dma_tube_cfg()
384
+ */
385
+typedef enum dma_request_src {
386
+    /* Each request source encodes the DMA controller and channel it
387
+     * belongs to, for error checking in dma_tube_cfg(). */
388
+
389
+    /* DMA1 request sources */
390
+
391
+    /**@{*/
392
+    /** (DMA1, tube 1) */
393
+    DMA_REQ_SRC_ADC1      = (RCC_DMA1 << 3) | 1,
394
+    DMA_REQ_SRC_TIM2_CH3  = (RCC_DMA1 << 3) | 1,
395
+    DMA_REQ_SRC_TIM4_CH1  = (RCC_DMA1 << 3) | 1,
396
+    /**@}*/
397
+
398
+    /**@{*/
399
+    /** (DMA1, tube 2)*/
400
+    DMA_REQ_SRC_SPI1_RX   = (RCC_DMA1 << 3) | 2,
401
+    DMA_REQ_SRC_USART3_TX = (RCC_DMA1 << 3) | 2,
402
+    DMA_REQ_SRC_TIM1_CH1  = (RCC_DMA1 << 3) | 2,
403
+    DMA_REQ_SRC_TIM2_UP   = (RCC_DMA1 << 3) | 2,
404
+    DMA_REQ_SRC_TIM3_CH3  = (RCC_DMA1 << 3) | 2,
405
+    /**@}*/
406
+
407
+    /**@{*/
408
+    /** (DMA1, tube 3)*/
409
+    DMA_REQ_SRC_SPI1_TX   = (RCC_DMA1 << 3) | 3,
410
+    DMA_REQ_SRC_USART3_RX = (RCC_DMA1 << 3) | 3,
411
+    DMA_REQ_SRC_TIM1_CH2  = (RCC_DMA1 << 3) | 3,
412
+    DMA_REQ_SRC_TIM3_CH4  = (RCC_DMA1 << 3) | 3,
413
+    DMA_REQ_SRC_TIM3_UP   = (RCC_DMA1 << 3) | 3,
414
+    /**@}*/
415
+
416
+    /**@{*/
417
+    /** (DMA1, tube 4)*/
418
+    DMA_REQ_SRC_SPI2_RX   = (RCC_DMA1 << 3) | 4,
419
+    DMA_REQ_SRC_I2S2_RX   = (RCC_DMA1 << 3) | 4,
420
+    DMA_REQ_SRC_USART1_TX = (RCC_DMA1 << 3) | 4,
421
+    DMA_REQ_SRC_I2C2_TX   = (RCC_DMA1 << 3) | 4,
422
+    DMA_REQ_SRC_TIM1_CH4  = (RCC_DMA1 << 3) | 4,
423
+    DMA_REQ_SRC_TIM1_TRIG = (RCC_DMA1 << 3) | 4,
424
+    DMA_REQ_SRC_TIM1_COM  = (RCC_DMA1 << 3) | 4,
425
+    DMA_REQ_SRC_TIM4_CH2  = (RCC_DMA1 << 3) | 4,
426
+    /**@}*/
427
+
428
+    /**@{*/
429
+    /** (DMA1, tube 5)*/
430
+    DMA_REQ_SRC_SPI2_TX   = (RCC_DMA1 << 3) | 5,
431
+    DMA_REQ_SRC_I2S2_TX   = (RCC_DMA1 << 3) | 5,
432
+    DMA_REQ_SRC_USART1_RX = (RCC_DMA1 << 3) | 5,
433
+    DMA_REQ_SRC_I2C2_RX   = (RCC_DMA1 << 3) | 5,
434
+    DMA_REQ_SRC_TIM1_UP   = (RCC_DMA1 << 3) | 5,
435
+    DMA_REQ_SRC_TIM2_CH1  = (RCC_DMA1 << 3) | 5,
436
+    DMA_REQ_SRC_TIM4_CH3  = (RCC_DMA1 << 3) | 5,
437
+    /**@}*/
438
+
439
+    /**@{*/
440
+    /** (DMA1, tube 6)*/
441
+    DMA_REQ_SRC_USART2_RX = (RCC_DMA1 << 3) | 6,
442
+    DMA_REQ_SRC_I2C1_TX   = (RCC_DMA1 << 3) | 6,
443
+    DMA_REQ_SRC_TIM1_CH3  = (RCC_DMA1 << 3) | 6,
444
+    DMA_REQ_SRC_TIM3_CH1  = (RCC_DMA1 << 3) | 6,
445
+    DMA_REQ_SRC_TIM3_TRIG = (RCC_DMA1 << 3) | 6,
446
+    /**@}*/
447
+
448
+    /**@{*/
449
+    /* Tube 7 */
450
+    DMA_REQ_SRC_USART2_TX = (RCC_DMA1 << 3) | 7,
451
+    DMA_REQ_SRC_I2C1_RX   = (RCC_DMA1 << 3) | 7,
452
+    DMA_REQ_SRC_TIM2_CH2  = (RCC_DMA1 << 3) | 7,
453
+    DMA_REQ_SRC_TIM2_CH4  = (RCC_DMA1 << 3) | 7,
454
+    DMA_REQ_SRC_TIM4_UP   = (RCC_DMA1 << 3) | 7,
455
+    /**@}*/
456
+
457
+    /* DMA2 request sources */
458
+
459
+    /**@{*/
460
+    /** (DMA2, tube 1)*/
461
+    DMA_REQ_SRC_SPI3_RX   = (RCC_DMA2 << 3) | 1,
462
+    DMA_REQ_SRC_I2S3_RX   = (RCC_DMA2 << 3) | 1,
463
+    DMA_REQ_SRC_TIM5_CH4  = (RCC_DMA2 << 3) | 1,
464
+    DMA_REQ_SRC_TIM5_TRIG = (RCC_DMA2 << 3) | 1,
465
+    /**@}*/
466
+
467
+    /**@{*/
468
+    /** (DMA2, tube 2)*/
469
+    DMA_REQ_SRC_SPI3_TX   = (RCC_DMA2 << 3) | 2,
470
+    DMA_REQ_SRC_I2S3_TX   = (RCC_DMA2 << 3) | 2,
471
+    DMA_REQ_SRC_TIM5_CH3  = (RCC_DMA2 << 3) | 2,
472
+    DMA_REQ_SRC_TIM5_UP   = (RCC_DMA2 << 3) | 2,
473
+    /**@}*/
474
+
475
+    /**@{*/
476
+    /** (DMA2, tube 3)*/
477
+    DMA_REQ_SRC_UART4_RX  = (RCC_DMA2 << 3) | 3,
478
+    DMA_REQ_SRC_TIM6_UP   = (RCC_DMA2 << 3) | 3,
479
+    DMA_REQ_SRC_DAC_CH1   = (RCC_DMA2 << 3) | 3,
480
+    /**@}*/
481
+
482
+    /**@{*/
483
+    /** (DMA2, tube 4)*/
484
+    DMA_REQ_SRC_SDIO      = (RCC_DMA2 << 3) | 4,
485
+    DMA_REQ_SRC_TIM5_CH2  = (RCC_DMA2 << 3) | 4,
486
+    /**@}*/
487
+
488
+    /**@{*/
489
+    /** (DMA2, tube 5)*/
490
+    DMA_REQ_SRC_ADC3      = (RCC_DMA2 << 3) | 5,
491
+    DMA_REQ_SRC_UART4_TX  = (RCC_DMA2 << 3) | 5,
492
+    DMA_REQ_SRC_TIM5_CH1  = (RCC_DMA2 << 3) | 5,
493
+    /**@}*/
494
+} dma_request_src;
495
+
496
+/*
497
+ * Convenience routines.
498
+ */
499
+
500
+/**
501
+ * @brief On STM32F1, dma_is_channel_enabled() is an alias for
502
+ *        dma_is_enabled().
503
+ * This is for backwards compatibility.
504
+ */
505
+#define dma_is_channel_enabled dma_is_enabled
506
+
507
+#define DMA_CHANNEL_NREGS 5     /* accounts for reserved word */
508
+static inline dma_tube_reg_map* dma_tube_regs(dma_dev *dev, dma_tube tube) {
509
+    __io uint32 *ccr1 = &dev->regs->CCR1;
510
+    return (dma_channel_reg_map*)(ccr1 + DMA_CHANNEL_NREGS * (tube - 1));
511
+}
512
+
513
+/**
514
+ * @brief On STM32F1, dma_channel_regs() is an alias for dma_tube_regs().
515
+ * This is for backwards compatibility. */
516
+#define dma_channel_regs(dev, ch) dma_tube_regs(dev, ch)
517
+
518
+static inline uint8 dma_is_enabled(dma_dev *dev, dma_tube tube) {
519
+    return (uint8)(dma_tube_regs(dev, tube)->CCR & DMA_CCR_EN);
520
+}
521
+
522
+static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_tube tube) {
523
+    uint8 shift = (tube - 1) * 4;
524
+    return (dev->regs->ISR >> shift) & 0xF;
525
+}
526
+
527
+static inline void dma_clear_isr_bits(dma_dev *dev, dma_tube tube) {
528
+    dev->regs->IFCR = (1U << (4 * (tube - 1)));
529
+}
530
+
531
+/**
532
+ * @brief Deprecated
533
+ * STM32F1 mode flags for dma_setup_xfer(). Use dma_tube_cfg() instead.
534
+ * @see dma_tube_cfg()
535
+ */
536
+typedef enum dma_mode_flags {
537
+    DMA_MEM_2_MEM  = 1 << 14, /**< Memory to memory mode */
538
+    DMA_MINC_MODE  = 1 << 7,  /**< Auto-increment memory address */
539
+    DMA_PINC_MODE  = 1 << 6,  /**< Auto-increment peripheral address */
540
+    DMA_CIRC_MODE  = 1 << 5,  /**< Circular mode */
541
+    DMA_FROM_MEM   = 1 << 4,  /**< Read from memory to peripheral */
542
+    DMA_TRNS_ERR   = 1 << 3,  /**< Interrupt on transfer error */
543
+    DMA_HALF_TRNS  = 1 << 2,  /**< Interrupt on half-transfer */
544
+    DMA_TRNS_CMPLT = 1 << 1   /**< Interrupt on transfer completion */
545
+} dma_mode_flags;
546
+
547
+/* Keep this around for backwards compatibility, but it's deprecated.
548
+ * New code should use dma_tube_cfg() instead.
549
+ *
550
+ * (It's not possible to fully configure a DMA stream on F2 with just
551
+ * this information, so this interface is too tied to the F1.) */
552
+__deprecated
553
+void dma_setup_transfer(dma_dev       *dev,
554
+                        dma_channel    channel,
555
+                        __io void     *peripheral_address,
556
+                        dma_xfer_size  peripheral_size,
557
+                        __io void     *memory_address,
558
+                        dma_xfer_size  memory_size,
559
+                        uint32         mode);
560
+
561
+#ifdef __cplusplus
562
+} // extern "C"
563
+#endif
564
+
565
+#endif

+ 46 - 0
libmaple/stm32f1/include/series/exti.h 파일 보기

@@ -0,0 +1,46 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 LeafLabs, LLC.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @file libmaple/stm32f1/include/series/exti.h
29
+ * @brief STM32F1 external interrupts
30
+ */
31
+
32
+#ifndef _LIBMAPLE_STM32F1_EXTI_H_
33
+#define _LIBMAPLE_STM32F1_EXTI_H_
34
+
35
+#ifdef __cpluspus
36
+extern "C" {
37
+#endif
38
+
39
+struct exti_reg_map;
40
+#define EXTI_BASE ((struct exti_reg_map*)0x40010400)
41
+
42
+#ifdef __cpluspus
43
+}
44
+#endif
45
+
46
+#endif

libmaple/flash.h → libmaple/stm32f1/include/series/flash.h 파일 보기

@@ -25,21 +25,28 @@
25 25
  *****************************************************************************/
26 26
 
27 27
 /**
28
- * @file flash.h
29
- * @brief STM32 Medium and high density Flash register map and setup
30
- * routines
28
+ * @file libmaple/stm32f1/include/series/flash.h
29
+ * @brief STM32F1 Flash header.
30
+ *
31
+ * Provides register map, base pointer, and register bit definitions
32
+ * for the Flash controller on the STM32F1 line, along with
33
+ * series-specific configuration values.
31 34
  */
32 35
 
33
-#include "libmaple_types.h"
34
-
35
-#ifndef _FLASH_H_
36
-#define _FLASH_H_
36
+#ifndef _LIBMAPLE_STM32F1_FLASH_H_
37
+#define _LIBMAPLE_STM32F1_FLASH_H_
37 38
 
38 39
 #ifdef __cplusplus
39 40
 extern "C"{
40 41
 #endif
41 42
 
42
-/** Flash register map type */
43
+#include <libmaple/libmaple_types.h>
44
+
45
+/*
46
+ * Register map
47
+ */
48
+
49
+/** @brief STM32F1 Flash register map type */
43 50
 typedef struct flash_reg_map {
44 51
     __io uint32 ACR;            /**< Access control register */
45 52
     __io uint32 KEYR;           /**< Key register */
@@ -51,7 +58,6 @@ typedef struct flash_reg_map {
51 58
     __io uint32 WRPR;           /**< Write protection register */
52 59
 } flash_reg_map;
53 60
 
54
-/** Flash register map base pointer */
55 61
 #define FLASH_BASE                      ((struct flash_reg_map*)0x40022000)
56 62
 
57 63
 /*
@@ -64,9 +70,9 @@ typedef struct flash_reg_map {
64 70
 #define FLASH_ACR_PRFTBE_BIT            4
65 71
 #define FLASH_ACR_HLFCYA_BIT            3
66 72
 
67
-#define FLASH_ACR_PRFTBS                BIT(FLASH_ACR_PRFTBS_BIT)
68
-#define FLASH_ACR_PRFTBE                BIT(FLASH_ACR_PRFTBE_BIT)
69
-#define FLASH_ACR_HLFCYA                BIT(FLASH_ACR_HLFCYA_BIT)
73
+#define FLASH_ACR_PRFTBS                (1U << FLASH_ACR_PRFTBS_BIT)
74
+#define FLASH_ACR_PRFTBE                (1U << FLASH_ACR_PRFTBE_BIT)
75
+#define FLASH_ACR_HLFCYA                (1U << FLASH_ACR_HLFCYA_BIT)
70 76
 #define FLASH_ACR_LATENCY               0x7
71 77
 
72 78
 /* Status register */
@@ -76,10 +82,10 @@ typedef struct flash_reg_map {
76 82
 #define FLASH_SR_PGERR_BIT              2
77 83
 #define FLASH_SR_BSY_BIT                0
78 84
 
79
-#define FLASH_SR_EOP                    BIT(FLASH_SR_EOP_BIT)
80
-#define FLASH_SR_WRPRTERR               BIT(FLASH_SR_WRPRTERR_BIT)
81
-#define FLASH_SR_PGERR                  BIT(FLASH_SR_PGERR_BIT)
82
-#define FLASH_SR_BSY                    BIT(FLASH_SR_BSY_BIT)
85
+#define FLASH_SR_EOP                    (1U << FLASH_SR_EOP_BIT)
86
+#define FLASH_SR_WRPRTERR               (1U << FLASH_SR_WRPRTERR_BIT)
87
+#define FLASH_SR_PGERR                  (1U << FLASH_SR_PGERR_BIT)
88
+#define FLASH_SR_BSY                    (1U << FLASH_SR_BSY_BIT)
83 89
 
84 90
 /* Control register */
85 91
 
@@ -94,16 +100,16 @@ typedef struct flash_reg_map {
94 100
 #define FLASH_CR_PER_BIT                1
95 101
 #define FLASH_CR_PG_BIT                 0
96 102
 
97
-#define FLASH_CR_EOPIE                  BIT(FLASH_CR_EOPIE_BIT)
98
-#define FLASH_CR_ERRIE                  BIT(FLASH_CR_ERRIE_BIT)
99
-#define FLASH_CR_OPTWRE                 BIT(FLASH_CR_OPTWRE_BIT)
100
-#define FLASH_CR_LOCK                   BIT(FLASH_CR_LOCK_BIT)
101
-#define FLASH_CR_STRT                   BIT(FLASH_CR_STRT_BIT)
102
-#define FLASH_CR_OPTER                  BIT(FLASH_CR_OPTER_BIT)
103
-#define FLASH_CR_OPTPG                  BIT(FLASH_CR_OPTPG_BIT)
104
-#define FLASH_CR_MER                    BIT(FLASH_CR_MER_BIT)
105
-#define FLASH_CR_PER                    BIT(FLASH_CR_PER_BIT)
106
-#define FLASH_CR_PG                     BIT(FLASH_CR_PG_BIT)
103
+#define FLASH_CR_EOPIE                  (1U << FLASH_CR_EOPIE_BIT)
104
+#define FLASH_CR_ERRIE                  (1U << FLASH_CR_ERRIE_BIT)
105
+#define FLASH_CR_OPTWRE                 (1U << FLASH_CR_OPTWRE_BIT)
106
+#define FLASH_CR_LOCK                   (1U << FLASH_CR_LOCK_BIT)
107
+#define FLASH_CR_STRT                   (1U << FLASH_CR_STRT_BIT)
108
+#define FLASH_CR_OPTER                  (1U << FLASH_CR_OPTER_BIT)
109
+#define FLASH_CR_OPTPG                  (1U << FLASH_CR_OPTPG_BIT)
110
+#define FLASH_CR_MER                    (1U << FLASH_CR_MER_BIT)
111
+#define FLASH_CR_PER                    (1U << FLASH_CR_PER_BIT)
112
+#define FLASH_CR_PG                     (1U << FLASH_CR_PG_BIT)
107 113
 
108 114
 /* Option byte register */
109 115
 
@@ -116,27 +122,28 @@ typedef struct flash_reg_map {
116 122
 #define FLASH_OBR_DATA1                 (0xFF << 18)
117 123
 #define FLASH_OBR_DATA0                 (0xFF << 10)
118 124
 #define FLASH_OBR_USER                  0x3FF
119
-#define FLASH_OBR_nRST_STDBY            BIT(FLASH_OBR_nRST_STDBY_BIT)
120
-#define FLASH_OBR_nRST_STOP             BIT(FLASH_OBR_nRST_STOP_BIT)
121
-#define FLASH_OBR_WDG_SW                BIT(FLASH_OBR_WDG_SW_BIT)
122
-#define FLASH_OBR_RDPRT                 BIT(FLASH_OBR_RDPRT_BIT)
123
-#define FLASH_OBR_OPTERR                BIT(FLASH_OBR_OPTERR_BIT)
125
+#define FLASH_OBR_nRST_STDBY            (1U << FLASH_OBR_nRST_STDBY_BIT)
126
+#define FLASH_OBR_nRST_STOP             (1U << FLASH_OBR_nRST_STOP_BIT)
127
+#define FLASH_OBR_WDG_SW                (1U << FLASH_OBR_WDG_SW_BIT)
128
+#define FLASH_OBR_RDPRT                 (1U << FLASH_OBR_RDPRT_BIT)
129
+#define FLASH_OBR_OPTERR                (1U << FLASH_OBR_OPTERR_BIT)
124 130
 
125 131
 /*
126
- * Setup routines
132
+ * Series-specific configuration values.
127 133
  */
128 134
 
129
-#define FLASH_WAIT_STATE_0              0x0
130
-#define FLASH_WAIT_STATE_1              0x1
131
-#define FLASH_WAIT_STATE_2              0x2
135
+#define FLASH_SAFE_WAIT_STATES          FLASH_WAIT_STATE_2
132 136
 
133
-void flash_enable_prefetch(void);
134
-void flash_set_latency(uint32 wait_states);
137
+/* Flash memory features available via ACR */
138
+enum {
139
+    FLASH_PREFETCH   = 0x10,
140
+    FLASH_HALF_CYCLE = 0x8,
141
+    FLASH_ICACHE     = 0x0,     /* Not available on STM32F1 */
142
+    FLASH_DCACHE     = 0x0,     /* Not available on STM32F1 */
143
+};
135 144
 
136 145
 #ifdef __cplusplus
137 146
 }
138 147
 #endif
139 148
 
140 149
 #endif
141
-
142
-

libmaple/gpio.h → libmaple/stm32f1/include/series/gpio.h 파일 보기

@@ -2,6 +2,7 @@
2 2
  * The MIT License
3 3
  *
4 4
  * Copyright (c) 2010 Perry Hung.
5
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
5 6
  *
6 7
  * Permission is hereby granted, free of charge, to any person
7 8
  * obtaining a copy of this software and associated documentation
@@ -25,22 +26,22 @@
25 26
 *****************************************************************************/
26 27
 
27 28
 /**
28
- *  @file gpio.h
29
- *
30
- *  @brief General purpose I/O (GPIO) and Alternate Function I/O
31
- *         (AFIO) prototypes, defines, and inlined access functions.
29
+ * @file libmaple/stm32f1/include/series/gpio.h
30
+ * @brief STM32F1 GPIO and AFIO support.
31
+ * General purpose I/O (GPIO) and Alternate Function I/O (AFIO).
32 32
  */
33 33
 
34
-#ifndef _GPIO_H_
35
-#define _GPIO_H_
36
-
37
-#include "libmaple.h"
38
-#include "rcc.h"
34
+#ifndef _LIBMAPLE_STM32F1_GPIO_H_
35
+#define _LIBMAPLE_STM32F1_GPIO_H_
39 36
 
40 37
 #ifdef __cplusplus
41 38
 extern "C"{
42 39
 #endif
43 40
 
41
+#include <libmaple/stm32.h>
42
+#include <libmaple/libmaple_types.h>
43
+#include <libmaple/exti.h>
44
+
44 45
 /*
45 46
  * GPIO register maps and devices
46 47
  */
@@ -56,46 +57,22 @@ typedef struct gpio_reg_map {
56 57
     __io uint32 LCKR;     /**< Port configuration lock register */
57 58
 } gpio_reg_map;
58 59
 
59
-/**
60
- * @brief External interrupt line port selector.
61
- *
62
- * Used to determine which GPIO port to map an external interrupt line
63
- * onto. */
64
-/* (See AFIO sections, below) */
65
-typedef enum afio_exti_port {
66
-    AFIO_EXTI_PA,               /**< Use port A (PAx) pin. */
67
-    AFIO_EXTI_PB,               /**< Use port B (PBx) pin. */
68
-    AFIO_EXTI_PC,               /**< Use port C (PCx) pin. */
69
-    AFIO_EXTI_PD,               /**< Use port D (PDx) pin. */
70
-#ifdef STM32_HIGH_DENSITY
71
-    AFIO_EXTI_PE,               /**< Use port E (PEx) pin. */
72
-    AFIO_EXTI_PF,               /**< Use port F (PFx) pin. */
73
-    AFIO_EXTI_PG,               /**< Use port G (PGx) pin. */
74
-#endif
75
-} afio_exti_port;
76
-
77
-/** GPIO device type */
78
-typedef struct gpio_dev {
79
-    gpio_reg_map *regs;       /**< Register map */
80
-    rcc_clk_id clk_id;        /**< RCC clock information */
81
-    afio_exti_port exti_port; /**< AFIO external interrupt port value */
82
-} gpio_dev;
83
-
84
-extern gpio_dev gpioa;
85
-extern gpio_dev* const GPIOA;
86
-extern gpio_dev gpiob;
87
-extern gpio_dev* const GPIOB;
88
-extern gpio_dev gpioc;
89
-extern gpio_dev* const GPIOC;
90
-extern gpio_dev gpiod;
91
-extern gpio_dev* const GPIOD;
60
+struct gpio_dev;
61
+extern struct gpio_dev gpioa;
62
+extern struct gpio_dev* const GPIOA;
63
+extern struct gpio_dev gpiob;
64
+extern struct gpio_dev* const GPIOB;
65
+extern struct gpio_dev gpioc;
66
+extern struct gpio_dev* const GPIOC;
67
+extern struct gpio_dev gpiod;
68
+extern struct gpio_dev* const GPIOD;
92 69
 #ifdef STM32_HIGH_DENSITY
93
-extern gpio_dev gpioe;
94
-extern gpio_dev* const GPIOE;
95
-extern gpio_dev gpiof;
96
-extern gpio_dev* const GPIOF;
97
-extern gpio_dev gpiog;
98
-extern gpio_dev* const GPIOG;
70
+extern struct gpio_dev gpioe;
71
+extern struct gpio_dev* const GPIOE;
72
+extern struct gpio_dev gpiof;
73
+extern struct gpio_dev* const GPIOF;
74
+extern struct gpio_dev gpiog;
75
+extern struct gpio_dev* const GPIOG;
99 76
 #endif
100 77
 
101 78
 /** GPIO port A register map base pointer */
@@ -106,14 +83,12 @@ extern gpio_dev* const GPIOG;
106 83
 #define GPIOC_BASE                      ((struct gpio_reg_map*)0x40011000)
107 84
 /** GPIO port D register map base pointer */
108 85
 #define GPIOD_BASE                      ((struct gpio_reg_map*)0x40011400)
109
-#ifdef STM32_HIGH_DENSITY
110 86
 /** GPIO port E register map base pointer */
111 87
 #define GPIOE_BASE                      ((struct gpio_reg_map*)0x40011800)
112 88
 /** GPIO port F register map base pointer */
113 89
 #define GPIOF_BASE                      ((struct gpio_reg_map*)0x40011C00)
114 90
 /** GPIO port G register map base pointer */
115 91
 #define GPIOG_BASE                      ((struct gpio_reg_map*)0x40012000)
116
-#endif
117 92
 
118 93
 /*
119 94
  * GPIO register bit definitions
@@ -136,86 +111,33 @@ extern gpio_dev* const GPIOG;
136 111
 #define GPIO_CR_MODE_OUTPUT_50MHZ       0x3
137 112
 
138 113
 /**
139
- * @brief GPIO Pin modes.
114
+ * @brief GPIO pin modes.
140 115
  *
141 116
  * These only allow for 50MHZ max output speeds; if you want slower,
142 117
  * use direct register access.
143 118
  */
144 119
 typedef enum gpio_pin_mode {
145
-    GPIO_OUTPUT_PP = (GPIO_CR_CNF_OUTPUT_PP |
146
-                      GPIO_CR_MODE_OUTPUT_50MHZ), /**< Output push-pull. */
147
-    GPIO_OUTPUT_OD = (GPIO_CR_CNF_OUTPUT_OD |
148
-                      GPIO_CR_MODE_OUTPUT_50MHZ), /**< Output open-drain. */
149
-    GPIO_AF_OUTPUT_PP = (GPIO_CR_CNF_AF_OUTPUT_PP |
150
-                         GPIO_CR_MODE_OUTPUT_50MHZ), /**< Alternate function
151
-                                                        output push-pull. */
152
-    GPIO_AF_OUTPUT_OD = (GPIO_CR_CNF_AF_OUTPUT_OD |
153
-                         GPIO_CR_MODE_OUTPUT_50MHZ), /**< Alternate function
154
-                                                        output open drain. */
155
-    GPIO_INPUT_ANALOG = (GPIO_CR_CNF_INPUT_ANALOG |
156
-                         GPIO_CR_MODE_INPUT), /**< Analog input. */
157
-    GPIO_INPUT_FLOATING = (GPIO_CR_CNF_INPUT_FLOATING |
158
-                           GPIO_CR_MODE_INPUT), /**< Input floating. */
159
-    GPIO_INPUT_PD = (GPIO_CR_CNF_INPUT_PU_PD |
160
-                     GPIO_CR_MODE_INPUT), /**< Input pull-down. */
161
-    GPIO_INPUT_PU /**< Input pull-up. */
162
-    /* GPIO_INPUT_PU treated as a special case, for ODR twiddling */
120
+    /** Output push-pull. */
121
+    GPIO_OUTPUT_PP      = GPIO_CR_CNF_OUTPUT_PP | GPIO_CR_MODE_OUTPUT_50MHZ,
122
+    /** Output open-drain. */
123
+    GPIO_OUTPUT_OD      = GPIO_CR_CNF_OUTPUT_OD | GPIO_CR_MODE_OUTPUT_50MHZ,
124
+    /** Alternate function output push-pull. */
125
+    GPIO_AF_OUTPUT_PP   = GPIO_CR_CNF_AF_OUTPUT_PP | GPIO_CR_MODE_OUTPUT_50MHZ,
126
+    /** Alternate function output open drain. */
127
+    GPIO_AF_OUTPUT_OD   = GPIO_CR_CNF_AF_OUTPUT_OD | GPIO_CR_MODE_OUTPUT_50MHZ,
128
+    /** Analog input. */
129
+    GPIO_INPUT_ANALOG   = GPIO_CR_CNF_INPUT_ANALOG | GPIO_CR_MODE_INPUT,
130
+    /** Input floating. */
131
+    GPIO_INPUT_FLOATING = GPIO_CR_CNF_INPUT_FLOATING | GPIO_CR_MODE_INPUT,
132
+    /** Input pull-down. */
133
+    GPIO_INPUT_PD       = GPIO_CR_CNF_INPUT_PU_PD | GPIO_CR_MODE_INPUT,
134
+    /** Input pull-up. */
135
+    GPIO_INPUT_PU, /* (treated a special case, for ODR twiddling) */
163 136
 } gpio_pin_mode;
164 137
 
165
-/*
166
- * GPIO Convenience routines
167
- */
168
-
169
-void gpio_init(gpio_dev *dev);
170
-void gpio_init_all(void);
171
-void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode);
172
-
173
-/**
174
- * @brief Get a GPIO port's corresponding afio_exti_port.
175
- * @param dev GPIO device whose afio_exti_port to return.
176
- */
177
-static inline afio_exti_port gpio_exti_port(gpio_dev *dev) {
178
-    return dev->exti_port;
179
-}
180
-
181
-/**
182
- * Set or reset a GPIO pin.
183
- *
184
- * Pin must have previously been configured to output mode.
185
- *
186
- * @param dev GPIO device whose pin to set.
187
- * @param pin Pin on to set or reset
188
- * @param val If true, set the pin.  If false, reset the pin.
189
- */
190
-static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) {
191
-    if (val) {
192
-        dev->regs->BSRR = BIT(pin);
193
-    } else {
194
-        dev->regs->BRR = BIT(pin);
195
-    }
196
-}
197
-
198
-/**
199
- * Determine whether or not a GPIO pin is set.
200
- *
201
- * Pin must have previously been configured to input mode.
202
- *
203
- * @param dev GPIO device whose pin to test.
204
- * @param pin Pin on dev to test.
205
- * @return True if the pin is set, false otherwise.
206
- */
207
-static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) {
208
-    return dev->regs->IDR & BIT(pin);
209
-}
210
-
211
-/**
212
- * Toggle a pin configured as output push-pull.
213
- * @param dev GPIO device.
214
- * @param pin Pin on dev to toggle.
215
- */
216
-static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) {
217
-    dev->regs->ODR = dev->regs->ODR ^ BIT(pin);
218
-}
138
+/* Hacks for F2: */
139
+#define GPIO_MODE_ANALOG GPIO_INPUT_ANALOG
140
+#define GPIO_MODE_OUTPUT GPIO_OUTPUT_PP
219 141
 
220 142
 /*
221 143
  * AFIO register map
@@ -223,19 +145,14 @@ static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) {
223 145
 
224 146
 /** AFIO register map */
225 147
 typedef struct afio_reg_map {
226
-    __io uint32 EVCR;        /**< Event control register.  */
227
-    __io uint32 MAPR;        /**< AF remap and debug I/O configuration
228
-                                register. */
229
-    __io uint32 EXTICR1;     /**< External interrupt configuration
230
-                                register 1. */
231
-    __io uint32 EXTICR2;     /**< External interrupt configuration
232
-                                register 2. */
233
-    __io uint32 EXTICR3;     /**< External interrupt configuration
234
-                                register 3. */
235
-    __io uint32 EXTICR4;     /**< External interrupt configuration
236
-                                register 4. */
237
-    __io uint32 MAPR2;       /**< AF remap and debug I/O configuration
238
-                                register 2. */
148
+    __io uint32 EVCR;    /**< Event control register.  */
149
+    __io uint32 MAPR;    /**< AF remap and debug I/O configuration register. */
150
+    __io uint32 EXTICR1; /**< External interrupt configuration register 1. */
151
+    __io uint32 EXTICR2; /**< External interrupt configuration register 2. */
152
+    __io uint32 EXTICR3; /**< External interrupt configuration register 3. */
153
+    __io uint32 EXTICR4; /**< External interrupt configuration register 4. */
154
+    __io uint32 MAPR2;   /**<
155
+                          * AF remap and debug I/O configuration register 2. */
239 156
 } afio_reg_map;
240 157
 
241 158
 /** AFIO register map base pointer. */
@@ -277,17 +194,17 @@ typedef struct afio_reg_map {
277 194
 #define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST    (0x1 << 24)
278 195
 #define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW           (0x2 << 24)
279 196
 #define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW        (0x4 << 24)
280
-#define AFIO_MAPR_ADC2_ETRGREG_REMAP           BIT(20)
281
-#define AFIO_MAPR_ADC2_ETRGINJ_REMAP           BIT(19)
282
-#define AFIO_MAPR_ADC1_ETRGREG_REMAP           BIT(18)
283
-#define AFIO_MAPR_ADC1_ETRGINJ_REMAP           BIT(17)
284
-#define AFIO_MAPR_TIM5CH4_IREMAP               BIT(16)
285
-#define AFIO_MAPR_PD01_REMAP                   BIT(15)
197
+#define AFIO_MAPR_ADC2_ETRGREG_REMAP           (1U << 20)
198
+#define AFIO_MAPR_ADC2_ETRGINJ_REMAP           (1U << 19)
199
+#define AFIO_MAPR_ADC1_ETRGREG_REMAP           (1U << 18)
200
+#define AFIO_MAPR_ADC1_ETRGINJ_REMAP           (1U << 17)
201
+#define AFIO_MAPR_TIM5CH4_IREMAP               (1U << 16)
202
+#define AFIO_MAPR_PD01_REMAP                   (1U << 15)
286 203
 #define AFIO_MAPR_CAN_REMAP                    (0x3 << 13)
287 204
 #define AFIO_MAPR_CAN_REMAP_NONE               (0x0 << 13)
288 205
 #define AFIO_MAPR_CAN_REMAP_PB8_PB9            (0x2 << 13)
289 206
 #define AFIO_MAPR_CAN_REMAP_PD0_PD1            (0x3 << 13)
290
-#define AFIO_MAPR_TIM4_REMAP                   BIT(12)
207
+#define AFIO_MAPR_TIM4_REMAP                   (1U << 12)
291 208
 #define AFIO_MAPR_TIM3_REMAP                   (0x3 << 10)
292 209
 #define AFIO_MAPR_TIM3_REMAP_NONE              (0x0 << 10)
293 210
 #define AFIO_MAPR_TIM3_REMAP_PARTIAL           (0x2 << 10)
@@ -305,10 +222,10 @@ typedef struct afio_reg_map {
305 222
 #define AFIO_MAPR_USART3_REMAP_NONE            (0x0 << 4)
306 223
 #define AFIO_MAPR_USART3_REMAP_PARTIAL         (0x1 << 4)
307 224
 #define AFIO_MAPR_USART3_REMAP_FULL            (0x3 << 4)
308
-#define AFIO_MAPR_USART2_REMAP                 BIT(3)
309
-#define AFIO_MAPR_USART1_REMAP                 BIT(2)
310
-#define AFIO_MAPR_I2C1_REMAP                   BIT(1)
311
-#define AFIO_MAPR_SPI1_REMAP                   BIT(0)
225
+#define AFIO_MAPR_USART2_REMAP                 (1U << 3)
226
+#define AFIO_MAPR_USART1_REMAP                 (1U << 2)
227
+#define AFIO_MAPR_I2C1_REMAP                   (1U << 1)
228
+#define AFIO_MAPR_SPI1_REMAP                   (1U << 0)
312 229
 
313 230
 /* External interrupt configuration register 1 */
314 231
 
@@ -382,12 +299,12 @@ typedef struct afio_reg_map {
382 299
 
383 300
 /* AF remap and debug I/O configuration register 2 */
384 301
 
385
-#define AFIO_MAPR2_FSMC_NADV            BIT(10)
386
-#define AFIO_MAPR2_TIM14_REMAP          BIT(9)
387
-#define AFIO_MAPR2_TIM13_REMAP          BIT(8)
388
-#define AFIO_MAPR2_TIM11_REMAP          BIT(7)
389
-#define AFIO_MAPR2_TIM10_REMAP          BIT(6)
390
-#define AFIO_MAPR2_TIM9_REMAP           BIT(5)
302
+#define AFIO_MAPR2_FSMC_NADV            (1U << 10)
303
+#define AFIO_MAPR2_TIM14_REMAP          (1U << 9)
304
+#define AFIO_MAPR2_TIM13_REMAP          (1U << 8)
305
+#define AFIO_MAPR2_TIM11_REMAP          (1U << 7)
306
+#define AFIO_MAPR2_TIM10_REMAP          (1U << 6)
307
+#define AFIO_MAPR2_TIM9_REMAP           (1U << 5)
391 308
 
392 309
 /*
393 310
  * AFIO convenience routines
@@ -395,95 +312,67 @@ typedef struct afio_reg_map {
395 312
 
396 313
 void afio_init(void);
397 314
 
398
-/**
399
- * External interrupt line numbers.
400
- */
401
-typedef enum afio_exti_num {
402
-    AFIO_EXTI_0,                /**< External interrupt line 0. */
403
-    AFIO_EXTI_1,                /**< External interrupt line 1. */
404
-    AFIO_EXTI_2,                /**< External interrupt line 2. */
405
-    AFIO_EXTI_3,                /**< External interrupt line 3. */
406
-    AFIO_EXTI_4,                /**< External interrupt line 4. */
407
-    AFIO_EXTI_5,                /**< External interrupt line 5. */
408
-    AFIO_EXTI_6,                /**< External interrupt line 6. */
409
-    AFIO_EXTI_7,                /**< External interrupt line 7. */
410
-    AFIO_EXTI_8,                /**< External interrupt line 8. */
411
-    AFIO_EXTI_9,                /**< External interrupt line 9. */
412
-    AFIO_EXTI_10,               /**< External interrupt line 10. */
413
-    AFIO_EXTI_11,               /**< External interrupt line 11. */
414
-    AFIO_EXTI_12,               /**< External interrupt line 12. */
415
-    AFIO_EXTI_13,               /**< External interrupt line 13. */
416
-    AFIO_EXTI_14,               /**< External interrupt line 14. */
417
-    AFIO_EXTI_15,               /**< External interrupt line 15. */
418
-} afio_exti_num;
419
-
420
-void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port);
421
-
422 315
 /* HACK: Use upper bit to denote MAPR2, Bit 31 is reserved and
423 316
  * not used in either MAPR or MAPR2 */
424
-#define AFIO_REMAP_USE_MAPR2            (1 << 31)
317
+#define AFIO_REMAP_USE_MAPR2            (1U << 31)
425 318
 
426 319
 /**
427 320
  * @brief Available peripheral remaps.
428 321
  * @see afio_remap()
429 322
  */
430 323
 typedef enum afio_remap_peripheral {
431
-    AFIO_REMAP_ADC2_ETRGREG  = AFIO_MAPR_ADC2_ETRGREG_REMAP, /**<
432
-        ADC 2 external trigger regular conversion remapping */
433
-    AFIO_REMAP_ADC2_ETRGINJ  = AFIO_MAPR_ADC2_ETRGINJ_REMAP, /**<
434
-        ADC 2 external trigger injected conversion remapping */
435
-    AFIO_REMAP_ADC1_ETRGREG  = AFIO_MAPR_ADC1_ETRGREG_REMAP, /**<
436
-        ADC 1 external trigger regular conversion remapping */
437
-    AFIO_REMAP_ADC1_ETRGINJ  = AFIO_MAPR_ADC1_ETRGINJ_REMAP, /**<
438
-        ADC 1 external trigger injected conversion remapping */
439
-    AFIO_REMAP_TIM5CH4_I     = AFIO_MAPR_TIM5CH4_IREMAP, /**<
440
-        Timer 5 channel 4 internal remapping */
441
-    AFIO_REMAP_PD01          = AFIO_MAPR_PD01_REMAP, /**<
442
-        Port D0/Port D1 mapping on OSC_IN/OSC_OUT */
443
-    AFIO_REMAP_CAN_1         = AFIO_MAPR_CAN_REMAP_PB8_PB9, /**<
444
-        CAN alternate function remapping 1 (RX on PB8, TX on PB9) */
445
-    AFIO_REMAP_CAN_2         = AFIO_MAPR_CAN_REMAP_PD0_PD1, /**<
446
-        CAN alternate function remapping 2 (RX on PD0, TX on PD1) */
447
-    AFIO_REMAP_TIM4          = AFIO_MAPR_TIM4_REMAP, /**<
448
-        Timer 4 remapping */
449
-    AFIO_REMAP_TIM3_PARTIAL  = AFIO_MAPR_TIM3_REMAP_PARTIAL, /**<
450
-        Timer 3 partial remapping */
451
-    AFIO_REMAP_TIM3_FULL      = AFIO_MAPR_TIM3_REMAP_FULL, /**<
452
-        Timer 3 full remapping */
453
-    AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3, /**<
454
-        Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3, CH3
455
-        on PA2, CH4 on PA3) */
456
-    AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11, /**<
457
-        Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1, CH3
458
-        on PB10, CH4 on PB11) */
459
-    AFIO_REMAP_TIM2_FULL      = AFIO_MAPR_TIM2_REMAP_FULL, /**<
460
-        Timer 2 full remapping */
461
-    AFIO_REMAP_USART2        = AFIO_MAPR_USART2_REMAP, /**<
462
-        USART 2 remapping */
463
-    AFIO_REMAP_USART1        = AFIO_MAPR_USART1_REMAP, /**<
464
-        USART 1 remapping */
465
-    AFIO_REMAP_I2C1          = AFIO_MAPR_I2C1_REMAP, /**<
466
-        I2C 1 remapping */
467
-    AFIO_REMAP_SPI1          = AFIO_MAPR_SPI1_REMAP, /**<
468
-        SPI 1 remapping */
469
-    AFIO_REMAP_FSMC_NADV     = (AFIO_MAPR2_FSMC_NADV |
470
-                                AFIO_REMAP_USE_MAPR2), /**<
471
-        NADV signal not connected */
472
-    AFIO_REMAP_TIM14         = (AFIO_MAPR2_TIM14_REMAP |
473
-                                AFIO_REMAP_USE_MAPR2), /**<
474
-        Timer 14 remapping */
475
-    AFIO_REMAP_TIM13         = (AFIO_MAPR2_TIM13_REMAP |
476
-                                AFIO_REMAP_USE_MAPR2), /**<
477
-        Timer 13 remapping */
478
-    AFIO_REMAP_TIM11         = (AFIO_MAPR2_TIM11_REMAP |
479
-                                AFIO_REMAP_USE_MAPR2), /**<
480
-        Timer 11 remapping */
481
-    AFIO_REMAP_TIM10         = (AFIO_MAPR2_TIM10_REMAP |
482
-                                AFIO_REMAP_USE_MAPR2), /**<
483
-        Timer 10 remapping */
484
-    AFIO_REMAP_TIM9          = (AFIO_MAPR2_TIM9_REMAP |
485
-                                AFIO_REMAP_USE_MAPR2) /**<
486
-        Timer 9 */
324
+     /** ADC 2 external trigger regular conversion remapping */
325
+    AFIO_REMAP_ADC2_ETRGREG   = AFIO_MAPR_ADC2_ETRGREG_REMAP,
326
+     /** ADC 2 external trigger injected conversion remapping */
327
+    AFIO_REMAP_ADC2_ETRGINJ   = AFIO_MAPR_ADC2_ETRGINJ_REMAP,
328
+    /** ADC 1 external trigger regular conversion remapping */
329
+    AFIO_REMAP_ADC1_ETRGREG   = AFIO_MAPR_ADC1_ETRGREG_REMAP,
330
+    /** ADC 1 external trigger injected conversion remapping */
331
+    AFIO_REMAP_ADC1_ETRGINJ   = AFIO_MAPR_ADC1_ETRGINJ_REMAP,
332
+    /** Timer 5 channel 4 internal remapping */
333
+    AFIO_REMAP_TIM5CH4_I      = AFIO_MAPR_TIM5CH4_IREMAP,
334
+    /** Port D0/Port D1 mapping on OSC_IN/OSC_OUT */
335
+    AFIO_REMAP_PD01           = AFIO_MAPR_PD01_REMAP,
336
+    /** CAN alternate function remapping 1 (RX on PB8, TX on PB9) */
337
+    AFIO_REMAP_CAN_1          = AFIO_MAPR_CAN_REMAP_PB8_PB9,
338
+    /** CAN alternate function remapping 2 (RX on PD0, TX on PD1) */
339
+    AFIO_REMAP_CAN_2          = AFIO_MAPR_CAN_REMAP_PD0_PD1,
340
+    /** Timer 4 remapping */
341
+    AFIO_REMAP_TIM4           = AFIO_MAPR_TIM4_REMAP,
342
+    /** Timer 3 partial remapping */
343
+    AFIO_REMAP_TIM3_PARTIAL   = AFIO_MAPR_TIM3_REMAP_PARTIAL,
344
+    /** Timer 3 full remapping */
345
+    AFIO_REMAP_TIM3_FULL      = AFIO_MAPR_TIM3_REMAP_FULL,
346
+    /**
347
+     * Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3,
348
+     * CH3 on                                      PA2, CH4 on PA3) */
349
+    AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3,
350
+    /**
351
+     * Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1,
352
+     * CH3 on                                      PB10, CH4 on PB11) */
353
+    AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11,
354
+    /** Timer 2 full remapping */
355
+    AFIO_REMAP_TIM2_FULL      = AFIO_MAPR_TIM2_REMAP_FULL,
356
+    /** USART 2 remapping */
357
+    AFIO_REMAP_USART2         = AFIO_MAPR_USART2_REMAP,
358
+    /** USART 1 remapping */
359
+    AFIO_REMAP_USART1         = AFIO_MAPR_USART1_REMAP,
360
+    /** I2C 1 remapping */
361
+    AFIO_REMAP_I2C1           = AFIO_MAPR_I2C1_REMAP,
362
+    /** SPI 1 remapping */
363
+    AFIO_REMAP_SPI1           = AFIO_MAPR_SPI1_REMAP,
364
+    /** NADV signal not connected */
365
+    AFIO_REMAP_FSMC_NADV      = AFIO_MAPR2_FSMC_NADV | AFIO_REMAP_USE_MAPR2,
366
+    /** Timer 14 remapping */
367
+    AFIO_REMAP_TIM14          = AFIO_MAPR2_TIM14_REMAP | AFIO_REMAP_USE_MAPR2,
368
+    /** Timer 13 remapping */
369
+    AFIO_REMAP_TIM13          = AFIO_MAPR2_TIM13_REMAP | AFIO_REMAP_USE_MAPR2,
370
+    /** Timer 11 remapping */
371
+    AFIO_REMAP_TIM11          = AFIO_MAPR2_TIM11_REMAP | AFIO_REMAP_USE_MAPR2,
372
+    /** Timer 10 remapping */
373
+    AFIO_REMAP_TIM10          = AFIO_MAPR2_TIM10_REMAP | AFIO_REMAP_USE_MAPR2,
374
+    /** Timer 9 remapping */
375
+    AFIO_REMAP_TIM9           = AFIO_MAPR2_TIM9_REMAP | AFIO_REMAP_USE_MAPR2,
487 376
 } afio_remap_peripheral;
488 377
 
489 378
 void afio_remap(afio_remap_peripheral p);
@@ -497,16 +386,14 @@ void afio_remap(afio_remap_peripheral p);
497 386
  * @see afio_cfg_debug_ports()
498 387
  */
499 388
 typedef enum afio_debug_cfg {
500
-    AFIO_DEBUG_FULL_SWJ = AFIO_MAPR_SWJ_CFG_FULL_SWJ, /**<
501
-                                   Full Serial Wire and JTAG debug */
502
-    AFIO_DEBUG_FULL_SWJ_NO_NJRST = AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST, /**<
503
-                                   Full Serial Wire and JTAG, but no NJTRST. */
504
-    AFIO_DEBUG_SW_ONLY = AFIO_MAPR_SWJ_CFG_NO_JTAG_SW, /**<
505
-                                   Serial Wire debug only (JTAG-DP disabled,
506
-                                   SW-DP enabled) */
507
-    AFIO_DEBUG_NONE = AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW /**<
508
-                                   No debug; all JTAG and SW pins are free
509
-                                   for use as GPIOs. */
389
+    /** Full Serial Wire and JTAG debug */
390
+    AFIO_DEBUG_FULL_SWJ          = AFIO_MAPR_SWJ_CFG_FULL_SWJ,
391
+    /** Full Serial Wire and JTAG, but no NJTRST. */
392
+    AFIO_DEBUG_FULL_SWJ_NO_NJRST = AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST,
393
+    /** Serial Wire debug only (JTAG-DP disabled, SW-DP enabled) */
394
+    AFIO_DEBUG_SW_ONLY           = AFIO_MAPR_SWJ_CFG_NO_JTAG_SW,
395
+    /** No debug; all JTAG and SW pins are free for use as GPIOs. */
396
+    AFIO_DEBUG_NONE              = AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW,
510 397
 } afio_debug_cfg;
511 398
 
512 399
 /**
@@ -519,9 +406,88 @@ static inline void afio_cfg_debug_ports(afio_debug_cfg config) {
519 406
     *mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config;
520 407
 }
521 408
 
409
+/*
410
+ * Deprecated bits
411
+ */
412
+
413
+/**
414
+ * @brief Deprecated. Use exti_cfg instead.
415
+ *
416
+ * In previous versions of libmaple, exti_attach_interrupt() took an
417
+ * afio_exti_port argument; afio_exti_port was also a member of struct
418
+ * gpio_dev. This isn't portable, so we now use exti_cfg
419
+ * instead. This typedef (and the macros AFIO_EXTI_PA, ...,
420
+ * AFIO_EXTI_PG) exist to preserve backwards compatibility.
421
+ */
422
+typedef exti_cfg afio_exti_port;
423
+
424
+/** Deprecated. Use EXTI_PA instead. */
425
+#define AFIO_EXTI_PA EXTI_PA
426
+/** Deprecated. Use EXTI_PB instead. */
427
+#define AFIO_EXTI_PB EXTI_PB
428
+/** Deprecated. Use EXTI_PC instead. */
429
+#define AFIO_EXTI_PC EXTI_PC
430
+/** Deprecated. Use EXTI_PD instead. */
431
+#define AFIO_EXTI_PD EXTI_PD
432
+/** Deprecated. Use EXTI_PE instead. */
433
+#define AFIO_EXTI_PE EXTI_PE
434
+/** Deprecated. Use EXTI_PF instead. */
435
+#define AFIO_EXTI_PF EXTI_PF
436
+/** Deprecated. Use EXTI_PG instead. */
437
+#define AFIO_EXTI_PG EXTI_PG
438
+
439
+/**
440
+ * @brief Deprecated. Use exti_num instead.
441
+ *
442
+ * In previous versions of libmaple, exti_attach_interrupt() took an
443
+ * afio_exti_num argument. This isn't portable, so we use exti_num
444
+ * instead. This typedef (and the macros AFIO_EXTI_0, ...,
445
+ * AFIO_EXTI_15) exist to preserve backwards compatibility.
446
+ */
447
+typedef exti_num afio_exti_num;
448
+
449
+/** Deprecated. Use EXTI0 instead. */
450
+#define AFIO_EXTI_0 EXTI0
451
+/** Deprecated. Use EXTI1 instead. */
452
+#define AFIO_EXTI_1 EXTI1
453
+/** Deprecated. Use EXTI2 instead. */
454
+#define AFIO_EXTI_2 EXTI2
455
+/** Deprecated. Use EXTI3 instead. */
456
+#define AFIO_EXTI_3 EXTI3
457
+/** Deprecated. Use EXTI4 instead. */
458
+#define AFIO_EXTI_4 EXTI4
459
+/** Deprecated. Use EXTI5 instead. */
460
+#define AFIO_EXTI_5 EXTI5
461
+/** Deprecated. Use EXTI6 instead. */
462
+#define AFIO_EXTI_6 EXTI6
463
+/** Deprecated. Use EXTI7 instead. */
464
+#define AFIO_EXTI_7 EXTI7
465
+/** Deprecated. Use EXTI8 instead. */
466
+#define AFIO_EXTI_8 EXTI8
467
+/** Deprecated. Use EXTI9 instead. */
468
+#define AFIO_EXTI_9 EXTI9
469
+/** Deprecated. Use EXTI10 instead. */
470
+#define AFIO_EXTI_10 EXTI10
471
+/** Deprecated. Use EXTI11 instead. */
472
+#define AFIO_EXTI_11 EXTI11
473
+/** Deprecated. Use EXTI12 instead. */
474
+#define AFIO_EXTI_12 EXTI12
475
+/** Deprecated. Use EXTI13 instead. */
476
+#define AFIO_EXTI_13 EXTI13
477
+/** Deprecated. Use EXTI14 instead. */
478
+#define AFIO_EXTI_14 EXTI14
479
+/** Deprecated. Use EXTI15 instead. */
480
+#define AFIO_EXTI_15 EXTI15
481
+
482
+/**
483
+ * @brief Deprecated. Use exti_select(exti, port) instead.
484
+ */
485
+static __always_inline void afio_exti_select(exti_num exti, exti_cfg port) {
486
+    exti_select(exti, port);
487
+}
488
+
522 489
 #ifdef __cplusplus
523 490
 }
524 491
 #endif
525 492
 
526 493
 #endif
527
-

+ 85 - 0
libmaple/stm32f1/include/series/i2c.h 파일 보기

@@ -0,0 +1,85 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Perry Hung (from <libmaple/i2c.h>).
5
+ * Copyright (c) 2012 LeafLabs, LLC.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person
8
+ * obtaining a copy of this software and associated documentation
9
+ * files (the "Software"), to deal in the Software without
10
+ * restriction, including without limitation the rights to use, copy,
11
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ * of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *****************************************************************************/
27
+
28
+/**
29
+ * @file libmaple/include/stm32f1/include/series/i2c.h
30
+ * @brief STM32F1 I2C
31
+ */
32
+
33
+#ifndef _LIBMAPLE_STM32F1_I2C_H_
34
+#define _LIBMAPLE_STM32F1_I2C_H_
35
+
36
+#include <libmaple/i2c_common.h>
37
+#include <libmaple/gpio.h>
38
+#include <libmaple/stm32.h>
39
+
40
+/*
41
+ * Register maps
42
+ */
43
+
44
+struct i2c_reg_map;
45
+
46
+/** STM32F1 I2C1 register map base pointer */
47
+#define I2C1_BASE               ((struct i2c_reg_map*)0x40005400)
48
+/** STM32F1 I2C2 register map base pointer */
49
+#define I2C2_BASE               ((struct i2c_reg_map*)0x40005800)
50
+
51
+/*
52
+ * Devices
53
+ */
54
+
55
+extern i2c_dev* const I2C1;
56
+extern i2c_dev* const I2C2;
57
+
58
+/*
59
+ * For internal use
60
+ */
61
+
62
+static inline uint32 _i2c_bus_clk(i2c_dev *dev) {
63
+    /* Both I2C peripherals are on APB1 */
64
+    return STM32_PCLK1 / (1000 * 1000);
65
+}
66
+
67
+#define _I2C_HAVE_IRQ_FIXUP 1
68
+void _i2c_irq_priority_fixup(i2c_dev *dev);
69
+
70
+/*
71
+ * Deprecated functionality
72
+ */
73
+
74
+/* Flag to use alternate pin mapping in i2c_master_enable(). */
75
+#define _I2C_HAVE_DEPRECATED_I2C_REMAP 1
76
+#define I2C_REMAP 0x4
77
+static inline void _i2c_handle_remap(i2c_dev *dev, uint32 flags) {
78
+    if ((dev == I2C1) && (flags & I2C_REMAP)) {
79
+        afio_remap(AFIO_REMAP_I2C1);
80
+        I2C1->sda_pin = 9;
81
+        I2C1->scl_pin = 8;
82
+    }
83
+}
84
+
85
+#endif  /* _LIBMAPLE_STM32F1_I2C_H_ */

libmaple/nvic.h → libmaple/stm32f1/include/series/nvic.h 파일 보기


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.