From 01d7159952c62d1373bc452aab44d01f83dd5e3a Mon Sep 17 00:00:00 2001
From: Eric Brombaugh <ebrombaugh1@cox.net>
Date: Sat, 8 Apr 2023 19:50:52 -0700
Subject: [PATCH] Added high clock rate support

---
 examples/i2c_oled/README.md |  4 ++--
 examples/i2c_oled/i2c.h     | 16 ++++++++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/examples/i2c_oled/README.md b/examples/i2c_oled/README.md
index 1d5593e..062a6d5 100644
--- a/examples/i2c_oled/README.md
+++ b/examples/i2c_oled/README.md
@@ -11,8 +11,8 @@ https://user-images.githubusercontent.com/1132011/230734071-dee305de-5aad-4ca0-a
 
 ## Build options
 There are a few build-time options in the i2c.h source:
-* I2C_CLKRATE - currently maxxed out at 100kHz but can be reduced if needed. Higher
-rate support will be added in the future.
+* I2C_CLKRATE - defines the I2C bus clock rate. Both 100kHz and 400kHz are supported.
+* I2C_DUTY - for I2C_CLKRATE > 100kHz this specifies the duty cycle, either 33% or 36%.
 * TIMEOUT_MAX - the amount of tries in busy-wait loops before giving up. This value
 depends on the I2C_CLKRATE and should not affect normal operation.
 * I2C_IRQ - chooses IRQ-based operation instead of busy-wait polling. Useful to
diff --git a/examples/i2c_oled/i2c.h b/examples/i2c_oled/i2c.h
index 0bc096e..4f30fc7 100644
--- a/examples/i2c_oled/i2c.h
+++ b/examples/i2c_oled/i2c.h
@@ -7,7 +7,10 @@
 #define _I2C_H
 
 // I2C clock rate
-#define I2C_CLKRATE 100000
+#define I2C_CLKRATE 400000
+
+// uncomment this for high-speed 36% duty cycle, otherwise 33%
+#define I2C_DUTY
 
 // I2C Timeout count
 #define TIMEOUT_MAX 100000
@@ -46,7 +49,16 @@ void i2c_setup(void)
 	// standard mode good to 100kHz
 	tempreg = (APB_CLOCK/(2*I2C_CLKRATE))&I2C_CKCFGR_CCR;
 #else
-	// fast mode not yet handled here
+	// fast mode over 100kHz
+#ifndef I2C_DUTY
+	// 33% duty cycle
+	tempreg = (APB_CLOCK/(3*I2C_CLKRATE))&I2C_CKCFGR_CCR;
+#else
+	// 36% duty cycle
+	tempreg = (APB_CLOCK/(25*I2C_CLKRATE))&I2C_CKCFGR_CCR;
+	tempreg |= I2C_CKCFGR_DUTY;
+#endif
+	tempreg |= I2C_CKCFGR_FS;
 #endif
 	I2C1->CKCFGR = tempreg;
 
-- 
GitLab