summaryrefslogtreecommitdiffstats
path: root/libopencm3/include/libopencm3/stm32/tools.h
diff options
context:
space:
mode:
Diffstat (limited to 'libopencm3/include/libopencm3/stm32/tools.h')
-rw-r--r--libopencm3/include/libopencm3/stm32/tools.h65
1 files changed, 65 insertions, 0 deletions
diff --git a/libopencm3/include/libopencm3/stm32/tools.h b/libopencm3/include/libopencm3/stm32/tools.h
new file mode 100644
index 0000000..e172433
--- /dev/null
+++ b/libopencm3/include/libopencm3/stm32/tools.h
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Piotr Esden-Tempski <piotr@esden.net>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBOPENCM3_TOOLS_H
+#define LIBOPENCM3_TOOLS_H
+
+/*
+ * Register accessors / manipulators
+ */
+
+/* Get register content. */
+#define GET_REG(REG) ((uint16_t) *REG)
+
+/* Set register content. */
+#define SET_REG(REG, VAL) (*REG = (uint16_t)VAL)
+
+/* Clear register bit. */
+#define CLR_REG_BIT(REG, BIT) SET_REG(REG, (~BIT))
+
+/* Clear register bit masking out some bits that must not be touched. */
+#define CLR_REG_BIT_MSK(REG, MSK, BIT) \
+ SET_REG(REG, (GET_REG(REG) & MSK & (~BIT)))
+
+/* Get masked out bit value. */
+#define GET_REG_BIT(REG, BIT) (GET_REG(REG) & BIT)
+
+/*
+ * Set/reset a bit in a masked window by using toggle mechanism.
+ *
+ * This means that we look at the bits in the bit window designated by
+ * the mask. If the bit in the masked window is not matching the
+ * bit mask BIT then we write 1 and if the bit in the masked window is
+ * matching the bit mask BIT we write 0.
+ *
+ * TODO: We may need a faster implementation of that one?
+ */
+#define TOG_SET_REG_BIT_MSK(REG, MSK, BIT) \
+do { \
+ register uint16_t toggle_mask = GET_REG(REG) & (MSK); \
+ register uint16_t bit_selector; \
+ for (bit_selector = 1; bit_selector; bit_selector <<= 1) { \
+ if ((bit_selector & (BIT)) != 0) { \
+ toggle_mask ^= bit_selector; \
+ } \
+ } \
+ SET_REG(REG, toggle_mask); \
+} while (0)
+
+#endif