@@ -120,3 +120,81 @@ func (spi SPI) configurePins(config SPIConfig) {
120
120
config .SDO .ConfigureAltFunc (PinConfig {Mode : PinModeSPISDO }, spi .AltFuncSelector )
121
121
config .SDI .ConfigureAltFunc (PinConfig {Mode : PinModeSPISDI }, spi .AltFuncSelector )
122
122
}
123
+
124
+ // -- I2C ----------------------------------------------------------------------
125
+
126
+ type I2C struct {
127
+ Bus * stm32.I2C_Type
128
+ AltFuncSelector uint8
129
+ }
130
+
131
+ func (i2c I2C ) configurePins (config I2CConfig ) {
132
+ config .SCL .ConfigureAltFunc (PinConfig {Mode : PinModeI2CSCL }, i2c .AltFuncSelector )
133
+ config .SDA .ConfigureAltFunc (PinConfig {Mode : PinModeI2CSDA }, i2c .AltFuncSelector )
134
+ }
135
+
136
+ func (i2c I2C ) getFreqRange (config I2CConfig ) uint32 {
137
+ // all I2C interfaces are on APB1 (42 MHz)
138
+ clock := CPUFrequency () / 4
139
+ // convert to MHz
140
+ clock /= 1000000
141
+ // must be between 2 MHz (or 4 MHz for fast mode (Fm)) and 50 MHz, inclusive
142
+ var min , max uint32 = 2 , 50
143
+ if config .Frequency > 100000 {
144
+ min = 4 // fast mode (Fm)
145
+ }
146
+ if clock < min {
147
+ clock = min
148
+ } else if clock > max {
149
+ clock = max
150
+ }
151
+ return clock << stm32 .I2C_CR2_FREQ_Pos
152
+ }
153
+
154
+ func (i2c I2C ) getRiseTime (config I2CConfig ) uint32 {
155
+ // These bits must be programmed with the maximum SCL rise time given in the
156
+ // I2C bus specification, incremented by 1.
157
+ // For instance: in Sm mode, the maximum allowed SCL rise time is 1000 ns.
158
+ // If, in the I2C_CR2 register, the value of FREQ[5:0] bits is equal to 0x08
159
+ // and PCLK1 = 125 ns, therefore the TRISE[5:0] bits must be programmed with
160
+ // 09h (1000 ns / 125 ns = 8 + 1)
161
+ freqRange := i2c .getFreqRange (config )
162
+ if config .Frequency > 100000 {
163
+ // fast mode (Fm) adjustment
164
+ freqRange *= 300
165
+ freqRange /= 1000
166
+ }
167
+ return (freqRange + 1 ) << stm32 .I2C_TRISE_TRISE_Pos
168
+ }
169
+
170
+ func (i2c I2C ) getSpeed (config I2CConfig ) uint32 {
171
+ ccr := func (pclk uint32 , freq uint32 , coeff uint32 ) uint32 {
172
+ return (((pclk - 1 ) / (freq * coeff )) + 1 ) & stm32 .I2C_CCR_CCR_Msk
173
+ }
174
+ sm := func (pclk uint32 , freq uint32 ) uint32 { // standard mode (Sm)
175
+ if s := ccr (pclk , freq , 2 ); s < 4 {
176
+ return 4
177
+ } else {
178
+ return s
179
+ }
180
+ }
181
+ fm := func (pclk uint32 , freq uint32 , duty uint8 ) uint32 { // fast mode (Fm)
182
+ if duty == DutyCycle2 {
183
+ return ccr (pclk , freq , 3 )
184
+ } else {
185
+ return ccr (pclk , freq , 25 ) | stm32 .I2C_CCR_DUTY
186
+ }
187
+ }
188
+ // all I2C interfaces are on APB1 (42 MHz)
189
+ clock := CPUFrequency () / 4
190
+ if config .Frequency <= 100000 {
191
+ return sm (clock , config .Frequency )
192
+ } else {
193
+ s := fm (clock , config .Frequency , config .DutyCycle )
194
+ if (s & stm32 .I2C_CCR_CCR_Msk ) == 0 {
195
+ return 1
196
+ } else {
197
+ return s | stm32 .I2C_CCR_F_S
198
+ }
199
+ }
200
+ }
0 commit comments