aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/include
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2012-06-21 15:45:38 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2012-06-22 14:06:10 -0400
commit70f22b667a7d91c68d663c1bf9ef1c0bdcbdd377 (patch)
tree4cb7a320aa0dac59d38b00d6357f2df8073a7e23 /libmaple/include
parent3ba9c0ecd6fd881d21292a369f8b7e45be5d2cb4 (diff)
downloadlibrambutan-70f22b667a7d91c68d663c1bf9ef1c0bdcbdd377.tar.gz
librambutan-70f22b667a7d91c68d663c1bf9ef1c0bdcbdd377.zip
I2C: Move F1-only errata workarounds out of libmaple/i2c.c.
The IRQ priority hack is unnecessary on targets with properly functioning I2C IRQ handlers, so we shouldn't use it unless we have to. Add a mechanism so a series header can provide such a hack if necessary. Have the F1 series header use this mechanism. Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
Diffstat (limited to 'libmaple/include')
-rw-r--r--libmaple/include/libmaple/i2c.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/libmaple/include/libmaple/i2c.h b/libmaple/include/libmaple/i2c.h
index 8ce6674..c66ebcb 100644
--- a/libmaple/include/libmaple/i2c.h
+++ b/libmaple/include/libmaple/i2c.h
@@ -50,6 +50,17 @@ extern "C" {
* - uint32 _i2c_bus_clk(i2c_dev*): Clock frequency of dev's bus, in
* MHz. (This is for internal use only).
*
+ * - (optional) _I2C_HAVE_IRQ_FIXUP: Leave undefined, or define to 1.
+ * This is for internal use only. It's a hack to work around a
+ * silicon bug related to I2C IRQ pre-emption on some targets. If 1,
+ * the series header must also declare and implement a routine with
+ * this signature (it may also be provided as a macro):
+ *
+ * void _i2c_irq_priority_fixup(i2c_dev*)
+ *
+ * This will be called by i2c_enable_irq() before actually enabling
+ * I2C interrupts.
+ *
* - Reg. map base pointers, device pointer declarations.
*/
@@ -243,6 +254,12 @@ static inline void i2c_stop_condition(i2c_dev *dev) {
/* IRQ enable/disable */
+#ifndef _I2C_HAVE_IRQ_FIXUP
+/* The series header provides this if _I2C_HAVE_IRQ_FIXUP is defined,
+ * but we need it either way. */
+#define _i2c_irq_priority_fixup(dev) ((void)0)
+#endif
+
#define I2C_IRQ_ERROR I2C_CR2_ITERREN
#define I2C_IRQ_EVENT I2C_CR2_ITEVTEN
#define I2C_IRQ_BUFFER I2C_CR2_ITBUFEN
@@ -255,6 +272,7 @@ static inline void i2c_stop_condition(i2c_dev *dev) {
* I2C_IRQ_BUFFER (buffer interrupt).
*/
static inline void i2c_enable_irq(i2c_dev *dev, uint32 irqs) {
+ _i2c_irq_priority_fixup(dev);
dev->regs->CR2 |= irqs;
}