github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_stm32_i2c_reva.go (about) 1 //go:build stm32f4 || stm32f1 2 3 package machine 4 5 // I2C implementation for 'older' STM32 MCUs, including the F1 and F4 series 6 // of MCUs. 7 8 import ( 9 "device/stm32" 10 "unsafe" 11 ) 12 13 const ( 14 flagOVR = 0x00010800 15 flagAF = 0x00010400 16 flagARLO = 0x00010200 17 flagBERR = 0x00010100 18 flagTXE = 0x00010080 19 flagRXNE = 0x00010040 20 flagSTOPF = 0x00010010 21 flagADD10 = 0x00010008 22 flagBTF = 0x00010004 23 flagADDR = 0x00010002 24 flagSB = 0x00010001 25 flagDUALF = 0x00100080 26 flagGENCALL = 0x00100010 27 flagTRA = 0x00100004 28 flagBUSY = 0x00100002 29 flagMSL = 0x00100001 30 ) 31 32 func (i2c *I2C) hasFlag(flag uint32) bool { 33 const mask = 0x0000FFFF 34 if uint8(flag>>16) == 1 { 35 return i2c.Bus.SR1.HasBits(flag & mask) 36 } else { 37 return i2c.Bus.SR2.HasBits(flag & mask) 38 } 39 } 40 41 func (i2c *I2C) clearFlag(flag uint32) { 42 const mask = 0x0000FFFF 43 i2c.Bus.SR1.Set(^(flag & mask)) 44 } 45 46 // clearFlagADDR reads both status registers to clear any pending ADDR flags. 47 func (i2c *I2C) clearFlagADDR() { 48 i2c.Bus.SR1.Get() 49 i2c.Bus.SR2.Get() 50 } 51 52 func (i2c *I2C) waitForFlag(flag uint32, set bool) bool { 53 const tryMax = 10000 54 hasFlag := false 55 for i := 0; !hasFlag && i < tryMax; i++ { 56 hasFlag = i2c.hasFlag(flag) == set 57 } 58 return hasFlag 59 } 60 61 func (i2c *I2C) waitForFlagOrError(flag uint32, set bool) bool { 62 const tryMax = 10000 63 hasFlag := false 64 for i := 0; !hasFlag && i < tryMax; i++ { 65 if hasFlag = i2c.hasFlag(flag) == set; !hasFlag { 66 // check for ACK failure 67 if i2c.hasFlag(flagAF) { 68 // generate stop condition 69 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP) 70 // clear pending flags 71 i2c.clearFlag(flagAF) 72 return false 73 } else if i2c.hasFlag(flagSTOPF) { 74 // clear stop flag 75 i2c.clearFlag(flagSTOPF) 76 return false 77 } 78 } 79 } 80 return hasFlag 81 } 82 83 type transferOption uint32 84 85 const ( 86 frameFirst = 0x00000001 87 frameFirstAndNext = 0x00000002 88 frameNext = 0x00000004 89 frameFirstAndLast = 0x00000008 90 frameLastNoStop = 0x00000010 91 frameLast = 0x00000020 92 frameNoOption = 0xFFFF0000 93 ) 94 95 // I2C fast mode (Fm) duty cycle 96 const ( 97 DutyCycle2 = 0 98 DutyCycle16x9 = 1 99 ) 100 101 // I2CConfig is used to store config info for I2C. 102 type I2CConfig struct { 103 Frequency uint32 104 SCL Pin 105 SDA Pin 106 DutyCycle uint8 107 } 108 109 // Configure is intended to setup the STM32 I2C interface. 110 func (i2c *I2C) Configure(config I2CConfig) error { 111 112 // The following is the required sequence in controller mode. 113 // 1. Program the peripheral input clock in I2C_CR2 Register in order to 114 // generate correct timings 115 // 2. Configure the clock control registers 116 // 3. Configure the rise time register 117 // 4. Program the I2C_CR1 register to enable the peripheral 118 // 5. Set the START bit in the I2C_CR1 register to generate a Start condition 119 120 // disable I2C interface before any configuration changes 121 i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_PE) 122 123 // reset I2C bus 124 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_SWRST) 125 i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_SWRST) 126 127 // enable clock for I2C 128 enableAltFuncClock(unsafe.Pointer(i2c.Bus)) 129 130 // init pins 131 if config.SCL == 0 && config.SDA == 0 { 132 config.SCL = I2C0_SCL_PIN 133 config.SDA = I2C0_SDA_PIN 134 } 135 i2c.configurePins(config) 136 137 // default to 100 kHz (Sm, standard mode) if no frequency is set 138 if config.Frequency == 0 { 139 config.Frequency = 100 * KHz 140 } 141 142 // configure I2C input clock 143 i2c.Bus.CR2.SetBits(i2c.getFreqRange(config)) 144 145 // configure rise time 146 i2c.Bus.TRISE.Set(i2c.getRiseTime(config)) 147 148 // configure clock control 149 i2c.Bus.CCR.Set(i2c.getSpeed(config)) 150 151 // disable GeneralCall and NoStretch modes 152 i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_ENGC | stm32.I2C_CR1_NOSTRETCH) 153 154 // enable I2C interface 155 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_PE) 156 157 return nil 158 } 159 160 // SetBaudRate sets the communication speed for I2C. 161 func (i2c *I2C) SetBaudRate(br uint32) error { 162 // TODO: implement 163 return errI2CNotImplemented 164 } 165 166 func (i2c *I2C) Tx(addr uint16, w, r []byte) error { 167 168 if err := i2c.controllerTransmit(addr, w); nil != err { 169 return err 170 } 171 172 if len(r) > 0 { 173 if err := i2c.controllerReceive(addr, r); nil != err { 174 return err 175 } 176 } 177 178 return nil 179 } 180 181 func (i2c *I2C) controllerTransmit(addr uint16, w []byte) error { 182 183 if !i2c.waitForFlag(flagBUSY, false) { 184 return errI2CBusReadyTimeout 185 } 186 187 // disable POS 188 i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_POS) 189 190 pos := 0 191 rem := len(w) 192 193 // send peripheral address 194 if err := i2c.controllerRequestWrite(addr, frameNoOption); nil != err { 195 return err 196 } 197 198 // clear ADDR flag 199 i2c.clearFlagADDR() 200 201 for rem > 0 { 202 // wait for TXE flag set 203 if !i2c.waitForFlagOrError(flagTXE, true) { 204 return errI2CAckExpected 205 } 206 207 // write data to DR 208 i2c.Bus.DR.Set(uint32(w[pos])) 209 // update counters 210 pos++ 211 rem-- 212 213 if i2c.hasFlag(flagBTF) && rem != 0 { 214 // write data to DR 215 i2c.Bus.DR.Set(uint32(w[pos])) 216 // update counters 217 pos++ 218 rem-- 219 } 220 221 // wait for transfer finished flag BTF set 222 if !i2c.waitForFlagOrError(flagBTF, true) { 223 return errI2CWriteTimeout 224 } 225 } 226 227 // generate stop condition 228 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP) 229 230 return nil 231 } 232 233 func (i2c *I2C) controllerRequestWrite(addr uint16, option transferOption) error { 234 235 if frameFirstAndLast == option || frameFirst == option || frameNoOption == option { 236 // generate start condition 237 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_START) 238 } else if false /* (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) */ { 239 // generate restart condition 240 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_START) 241 } 242 243 // ensure start bit is set 244 if !i2c.waitForFlag(flagSB, true) { 245 return errI2CSignalStartTimeout 246 } 247 248 // send peripheral address 249 i2c.Bus.DR.Set(uint32(addr) << 1) 250 251 // wait for address ACK from peripheral 252 if !i2c.waitForFlagOrError(flagADDR, true) { 253 return errI2CSignalStartTimeout 254 } 255 256 return nil 257 } 258 259 func (i2c *I2C) controllerReceive(addr uint16, r []byte) error { 260 261 if !i2c.waitForFlag(flagBUSY, false) { 262 return errI2CBusReadyTimeout 263 } 264 265 // disable POS 266 i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_POS) 267 268 pos := 0 269 rem := len(r) 270 271 // send peripheral address 272 if err := i2c.controllerRequestRead(addr, frameNoOption); nil != err { 273 return err 274 } 275 276 switch rem { 277 case 0: 278 // clear ADDR flag 279 i2c.clearFlagADDR() 280 // generate stop condition 281 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP) 282 283 case 1: 284 // disable ACK 285 i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_ACK) 286 // clear ADDR flag 287 i2c.clearFlagADDR() 288 // generate stop condition 289 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP) 290 291 case 2: 292 // disable ACK 293 i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_ACK) 294 // enable POS 295 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_POS) 296 // clear ADDR flag 297 i2c.clearFlagADDR() 298 299 default: 300 // enable ACK 301 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_ACK) 302 // clear ADDR flag 303 i2c.clearFlagADDR() 304 } 305 306 for rem > 0 { 307 switch rem { 308 case 1: 309 // wait until RXNE flag is set 310 if !i2c.waitForFlagOrError(flagRXNE, true) { 311 return errI2CReadTimeout 312 } 313 314 // read data from DR 315 r[pos] = byte(i2c.Bus.DR.Get()) 316 317 // update counters 318 pos++ 319 rem-- 320 321 case 2: 322 // wait until transfer finished flag BTF is set 323 if !i2c.waitForFlag(flagBTF, true) { 324 return errI2CReadTimeout 325 } 326 327 // generate stop condition 328 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP) 329 330 // read data from DR 331 r[pos] = byte(i2c.Bus.DR.Get()) 332 333 // update counters 334 pos++ 335 rem-- 336 337 // read data from DR 338 r[pos] = byte(i2c.Bus.DR.Get()) 339 340 // update counters 341 pos++ 342 rem-- 343 344 case 3: 345 // wait until transfer finished flag BTF is set 346 if !i2c.waitForFlag(flagBTF, true) { 347 return errI2CReadTimeout 348 } 349 350 // disable ACK 351 i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_ACK) 352 353 // read data from DR 354 r[pos] = byte(i2c.Bus.DR.Get()) 355 356 // update counters 357 pos++ 358 rem-- 359 360 // wait until transfer finished flag BTF is set 361 if !i2c.waitForFlag(flagBTF, true) { 362 return errI2CReadTimeout 363 } 364 365 // generate stop condition 366 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP) 367 368 // read data from DR 369 r[pos] = byte(i2c.Bus.DR.Get()) 370 371 // update counters 372 pos++ 373 rem-- 374 375 // read data from DR 376 r[pos] = byte(i2c.Bus.DR.Get()) 377 378 // update counters 379 pos++ 380 rem-- 381 382 default: 383 // wait until RXNE flag is set 384 if !i2c.waitForFlagOrError(flagRXNE, true) { 385 return errI2CReadTimeout 386 } 387 388 // read data from DR 389 r[pos] = byte(i2c.Bus.DR.Get()) 390 391 // update counters 392 pos++ 393 rem-- 394 395 if i2c.hasFlag(flagBTF) { 396 // read data from DR 397 r[pos] = byte(i2c.Bus.DR.Get()) 398 399 // update counters 400 pos++ 401 rem-- 402 } 403 } 404 } 405 406 return nil 407 } 408 409 func (i2c *I2C) controllerRequestRead(addr uint16, option transferOption) error { 410 411 // enable ACK 412 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_ACK) 413 414 if frameFirstAndLast == option || frameFirst == option || frameNoOption == option { 415 // generate start condition 416 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_START) 417 } else if false /* (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) */ { 418 // generate restart condition 419 i2c.Bus.CR1.SetBits(stm32.I2C_CR1_START) 420 } 421 422 // ensure start bit is set 423 if !i2c.waitForFlag(flagSB, true) { 424 return errI2CSignalStartTimeout 425 } 426 427 // send peripheral address 428 i2c.Bus.DR.Set(uint32(addr)<<1 | 1) 429 430 // wait for address ACK from peripheral 431 if !i2c.waitForFlagOrError(flagADDR, true) { 432 return errI2CSignalStartTimeout 433 } 434 435 return nil 436 }