Flipped polarity of output enables to match Guava pins logic
[sifive-blocks.git] / src / main / scala / devices / i2c / I2C.scala
1 /////////////////////////////////////////////////////////////////////
2 //// ////
3 //// WISHBONE revB.2 compliant I2C Master controller Top-level ////
4 //// ////
5 //// ////
6 //// Author: Richard Herveille ////
7 //// richard@asics.ws ////
8 //// www.asics.ws ////
9 //// ////
10 //// Downloaded from: http://www.opencores.org/projects/i2c/ ////
11 //// ////
12 /////////////////////////////////////////////////////////////////////
13 //// ////
14 //// Copyright (C) 2001 Richard Herveille ////
15 //// richard@asics.ws ////
16 //// ////
17 //// This source file may be used and distributed without ////
18 //// restriction provided that this copyright statement is not ////
19 //// removed from the file and that any derivative work contains ////
20 //// the original copyright notice and the associated disclaimer.////
21 //// ////
22 //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
23 //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
24 //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
25 //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
26 //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
27 //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
28 //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
29 //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
30 //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
31 //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
32 //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
33 //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
34 //// POSSIBILITY OF SUCH DAMAGE. ////
35 //// ////
36 /////////////////////////////////////////////////////////////////////
37
38 // This code was re-written in Chisel by SiFive, Inc.
39 // See LICENSE for license details.
40 // WISHBONE interface replaced by Tilelink2
41
42 package sifive.blocks.devices.i2c
43
44 import Chisel._
45 import config._
46 import util._
47 import regmapper._
48 import uncore.tilelink2._
49 import rocketchip.PeripheryBusConfig
50 import util.AsyncResetRegVec
51 import sifive.blocks.devices.gpio.{GPIOPinCtrl}
52
53 case class I2CConfig(address: BigInt)
54
55 trait HasI2CParameters {
56 implicit val p: Parameters
57 val params: I2CConfig
58 val c = params
59 }
60
61 class I2CPin extends Bundle {
62 val in = Bool(INPUT)
63 val out = Bool(OUTPUT)
64 val oe = Bool(OUTPUT)
65 }
66
67 class I2CPort extends Bundle {
68 val scl = new I2CPin
69 val sda = new I2CPin
70 }
71
72 trait I2CBundle extends Bundle with HasI2CParameters {
73 val port = new I2CPort
74 }
75
76 trait I2CModule extends Module with HasI2CParameters with HasRegMap {
77 val io: I2CBundle
78
79 val I2C_CMD_NOP = UInt(0x00)
80 val I2C_CMD_START = UInt(0x01)
81 val I2C_CMD_STOP = UInt(0x02)
82 val I2C_CMD_WRITE = UInt(0x04)
83 val I2C_CMD_READ = UInt(0x08)
84
85 class PrescalerBundle extends Bundle{
86 val hi = UInt(8.W)
87 val lo = UInt(8.W)
88 }
89
90 class ControlBundle extends Bundle{
91 val coreEn = Bool()
92 val intEn = Bool()
93 val reserved = UInt(6.W)
94 }
95
96 class CommandBundle extends Bundle{
97 val start = Bool()
98 val stop = Bool()
99 val read = Bool()
100 val write = Bool()
101 val ack = Bool()
102 val reserved = UInt(2.W)
103 val irqAck = Bool()
104 }
105
106 class StatusBundle extends Bundle{
107 val receivedAck = Bool() // received aknowledge from slave
108 val busy = Bool()
109 val arbLost = Bool()
110 val reserved = UInt(3.W)
111 val transferInProgress = Bool()
112 val irqFlag = Bool()
113 }
114
115 // control state visible to SW/driver
116 val prescaler = Reg(init = (new PrescalerBundle).fromBits(0xFFFF.U))
117 val control = Reg(init = (new ControlBundle).fromBits(0.U))
118 val transmitData = Reg(init = UInt(0, 8.W))
119 val receivedData = Reg(init = UInt(0, 8.W))
120 val cmd = Reg(init = (new CommandBundle).fromBits(0.U))
121 val status = Reg(init = (new StatusBundle).fromBits(0.U))
122
123
124 //////// Bit level ////////
125
126 io.port.scl.out := false.B // i2c clock line output
127 io.port.sda.out := false.B // i2c data line output
128
129 // filter SCL and SDA signals; (attempt to) remove glitches
130 val filterCnt = Reg(init = UInt(0, 14.W))
131 when ( !control.coreEn ) {
132 filterCnt := 0.U
133 } .elsewhen (!(filterCnt.orR)) {
134 filterCnt := Cat(prescaler.hi, prescaler.lo) >> 2 //16x I2C bus frequency
135 } .otherwise {
136 filterCnt := filterCnt - 1.U
137 }
138
139 val fSCL = Reg(init = UInt(0x7, 3.W))
140 val fSDA = Reg(init = UInt(0x7, 3.W))
141 when (!(filterCnt.orR)) {
142 fSCL := Cat(fSCL, io.port.scl.in)
143 fSDA := Cat(fSDA, io.port.sda.in)
144 }
145
146 val sSCL = Reg(init = true.B, next = (new Majority(fSCL.toBools.toSet)).out)
147 val sSDA = Reg(init = true.B, next = (new Majority(fSDA.toBools.toSet)).out)
148
149 val dSCL = Reg(init = true.B, next = sSCL)
150 val dSDA = Reg(init = true.B, next = sSDA)
151
152 val dSCLOen = Reg(next = io.port.scl.oe) // delayed scl_oen
153
154 // detect start condition => detect falling edge on SDA while SCL is high
155 // detect stop condition => detect rising edge on SDA while SCL is high
156 val startCond = Reg(init = false.B, next = !sSDA && dSDA && sSCL)
157 val stopCond = Reg(init = false.B, next = sSDA && !dSDA && sSCL)
158
159 // master drives SCL high, but another master pulls it low
160 // master start counting down its low cycle now (clock synchronization)
161 val sclSync = dSCL && !sSCL && io.port.scl.oe
162
163 // slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
164 // slave_wait remains asserted until the slave releases SCL
165 val slaveWait = Reg(init = false.B)
166 slaveWait := (io.port.scl.oe && !dSCLOen && !sSCL) || (slaveWait && !sSCL)
167
168 val clkEn = Reg(init = true.B) // clock generation signals
169 val cnt = Reg(init = UInt(0, 16.W)) // clock divider counter (synthesis)
170
171 // generate clk enable signal
172 when (!(cnt.orR) || !control.coreEn || sclSync ) {
173 cnt := Cat(prescaler.hi, prescaler.lo)
174 clkEn := true.B
175 }
176 .elsewhen (slaveWait) {
177 clkEn := false.B
178 }
179 .otherwise {
180 cnt := cnt - 1.U
181 clkEn := false.B
182 }
183
184 val sclOen = Reg(init = true.B)
185 io.port.scl.oe := !sclOen
186
187 val sdaOen = Reg(init = true.B)
188 io.port.sda.oe := !sdaOen
189
190 val sdaChk = Reg(init = false.B) // check SDA output (Multi-master arbitration)
191
192 val transmitBit = Reg(init = false.B)
193 val receivedBit = Reg(Bool())
194 when (sSCL && !dSCL) {
195 receivedBit := sSDA
196 }
197
198 val bitCmd = Reg(init = UInt(0, 4.W)) // command (from byte controller)
199 val bitCmdStop = Reg(init = false.B)
200 when (clkEn) {
201 bitCmdStop := bitCmd === I2C_CMD_STOP
202 }
203 val bitCmdAck = Reg(init = false.B)
204
205 val (s_bit_idle ::
206 s_bit_start_a :: s_bit_start_b :: s_bit_start_c :: s_bit_start_d :: s_bit_start_e ::
207 s_bit_stop_a :: s_bit_stop_b :: s_bit_stop_c :: s_bit_stop_d ::
208 s_bit_rd_a :: s_bit_rd_b :: s_bit_rd_c :: s_bit_rd_d ::
209 s_bit_wr_a :: s_bit_wr_b :: s_bit_wr_c :: s_bit_wr_d :: Nil) = Enum(UInt(), 18)
210 val bitState = Reg(init = s_bit_idle)
211
212 val arbLost = Reg(init = false.B, next = (sdaChk && !sSDA && sdaOen) | ((bitState === s_bit_idle) && stopCond && !bitCmdStop))
213
214 // bit FSM
215 when (arbLost) {
216 bitState := s_bit_idle
217 bitCmdAck := false.B
218 sclOen := true.B
219 sdaOen := true.B
220 sdaChk := false.B
221 }
222 .otherwise {
223 bitCmdAck := false.B
224
225 when (clkEn) {
226 switch (bitState) {
227 is (s_bit_idle) {
228 switch (bitCmd) {
229 is (I2C_CMD_START) { bitState := s_bit_start_a }
230 is (I2C_CMD_STOP) { bitState := s_bit_stop_a }
231 is (I2C_CMD_WRITE) { bitState := s_bit_wr_a }
232 is (I2C_CMD_READ) { bitState := s_bit_rd_a }
233 }
234 sdaChk := false.B
235 }
236
237 is (s_bit_start_a) {
238 bitState := s_bit_start_b
239 sclOen := sclOen
240 sdaOen := true.B
241 sdaChk := false.B
242 }
243 is (s_bit_start_b) {
244 bitState := s_bit_start_c
245 sclOen := true.B
246 sdaOen := true.B
247 sdaChk := false.B
248 }
249 is (s_bit_start_c) {
250 bitState := s_bit_start_d
251 sclOen := true.B
252 sdaOen := false.B
253 sdaChk := false.B
254 }
255 is (s_bit_start_d) {
256 bitState := s_bit_start_e
257 sclOen := true.B
258 sdaOen := false.B
259 sdaChk := false.B
260 }
261 is (s_bit_start_e) {
262 bitState := s_bit_idle
263 bitCmdAck := true.B
264 sclOen := false.B
265 sdaOen := false.B
266 sdaChk := false.B
267 }
268
269 is (s_bit_stop_a) {
270 bitState := s_bit_stop_b
271 sclOen := false.B
272 sdaOen := false.B
273 sdaChk := false.B
274 }
275 is (s_bit_stop_b) {
276 bitState := s_bit_stop_c
277 sclOen := true.B
278 sdaOen := false.B
279 sdaChk := false.B
280 }
281 is (s_bit_stop_c) {
282 bitState := s_bit_stop_d
283 sclOen := true.B
284 sdaOen := false.B
285 sdaChk := false.B
286 }
287 is (s_bit_stop_d) {
288 bitState := s_bit_idle
289 bitCmdAck := true.B
290 sclOen := true.B
291 sdaOen := true.B
292 sdaChk := false.B
293 }
294
295 is (s_bit_rd_a) {
296 bitState := s_bit_rd_b
297 sclOen := false.B
298 sdaOen := true.B
299 sdaChk := false.B
300 }
301 is (s_bit_rd_b) {
302 bitState := s_bit_rd_c
303 sclOen := true.B
304 sdaOen := true.B
305 sdaChk := false.B
306 }
307 is (s_bit_rd_c) {
308 bitState := s_bit_rd_d
309 sclOen := true.B
310 sdaOen := true.B
311 sdaChk := false.B
312 }
313 is (s_bit_rd_d) {
314 bitState := s_bit_idle
315 bitCmdAck := true.B
316 sclOen := false.B
317 sdaOen := true.B
318 sdaChk := false.B
319 }
320
321 is (s_bit_wr_a) {
322 bitState := s_bit_wr_b
323 sclOen := false.B
324 sdaOen := transmitBit
325 sdaChk := false.B
326 }
327 is (s_bit_wr_b) {
328 bitState := s_bit_wr_c
329 sclOen := true.B
330 sdaOen := transmitBit
331 sdaChk := false.B
332 }
333 is (s_bit_wr_c) {
334 bitState := s_bit_wr_d
335 sclOen := true.B
336 sdaOen := transmitBit
337 sdaChk := true.B
338 }
339 is (s_bit_wr_d) {
340 bitState := s_bit_idle
341 bitCmdAck := true.B
342 sclOen := false.B
343 sdaOen := transmitBit
344 sdaChk := false.B
345 }
346 }
347 }
348 }
349
350
351 //////// Byte level ///////
352 val load = Reg(init = false.B) // load shift register
353 val shift = Reg(init = false.B) // shift shift register
354 val cmdAck = Reg(init = false.B) // also done
355 val receivedAck = Reg(init = false.B) // from I2C slave
356 val go = (cmd.read | cmd.write | cmd.stop) & !cmdAck
357
358 val bitCnt = Reg(init = UInt(0, 3.W))
359 when (load) {
360 bitCnt := 0x7.U
361 }
362 .elsewhen (shift) {
363 bitCnt := bitCnt - 1.U
364 }
365 val bitCntDone = !(bitCnt.orR)
366
367 // receivedData is used as shift register directly
368 when (load) {
369 receivedData := transmitData
370 }
371 .elsewhen (shift) {
372 receivedData := Cat(receivedData, receivedBit)
373 }
374
375 val (s_byte_idle :: s_byte_start :: s_byte_read :: s_byte_write :: s_byte_ack :: s_byte_stop :: Nil) = Enum(UInt(), 6)
376 val byteState = Reg(init = s_byte_idle)
377
378 when (arbLost) {
379 bitCmd := I2C_CMD_NOP
380 transmitBit := false.B
381 shift := false.B
382 load := false.B
383 cmdAck := false.B
384 byteState := s_byte_idle
385 receivedAck := false.B
386 }
387 .otherwise {
388 transmitBit := receivedData(7)
389 shift := false.B
390 load := false.B
391 cmdAck := false.B
392
393 switch (byteState) {
394 is (s_byte_idle) {
395 when (go) {
396 when (cmd.start) {
397 byteState := s_byte_start
398 bitCmd := I2C_CMD_START
399 }
400 .elsewhen (cmd.read) {
401 byteState := s_byte_read
402 bitCmd := I2C_CMD_READ
403 }
404 .elsewhen (cmd.write) {
405 byteState := s_byte_write
406 bitCmd := I2C_CMD_WRITE
407 }
408 .otherwise { // stop
409 byteState := s_byte_stop
410 bitCmd := I2C_CMD_STOP
411 }
412
413 load := true.B
414 }
415 }
416 is (s_byte_start) {
417 when (bitCmdAck) {
418 when (cmd.read) {
419 byteState := s_byte_read
420 bitCmd := I2C_CMD_READ
421 }
422 .otherwise {
423 byteState := s_byte_write
424 bitCmd := I2C_CMD_WRITE
425 }
426
427 load := true.B
428 }
429 }
430 is (s_byte_write) {
431 when (bitCmdAck) {
432 when (bitCntDone) {
433 byteState := s_byte_ack
434 bitCmd := I2C_CMD_READ
435 }
436 .otherwise {
437 byteState := s_byte_write
438 bitCmd := I2C_CMD_WRITE
439 shift := true.B
440 }
441 }
442 }
443 is (s_byte_read) {
444 when (bitCmdAck) {
445 when (bitCntDone) {
446 byteState := s_byte_ack
447 bitCmd := I2C_CMD_WRITE
448 }
449 .otherwise {
450 byteState := s_byte_read
451 bitCmd := I2C_CMD_READ
452 }
453
454 shift := true.B
455 transmitBit := cmd.ack
456 }
457 }
458 is (s_byte_ack) {
459 when (bitCmdAck) {
460 when (cmd.stop) {
461 byteState := s_byte_stop
462 bitCmd := I2C_CMD_STOP
463 }
464 .otherwise {
465 byteState := s_byte_idle
466 bitCmd := I2C_CMD_NOP
467
468 // generate command acknowledge signal
469 cmdAck := true.B
470 }
471
472 // assign ack_out output to bit_controller_rxd (contains last received bit)
473 receivedAck := receivedBit
474
475 transmitBit := true.B
476 }
477 .otherwise {
478 transmitBit := cmd.ack
479 }
480 }
481 is (s_byte_stop) {
482 when (bitCmdAck) {
483 byteState := s_byte_idle
484 bitCmd := I2C_CMD_NOP
485
486 // assign ack_out output to bit_controller_rxd (contains last received bit)
487 cmdAck := true.B
488 }
489 }
490 }
491 }
492
493
494 //////// Top level ////////
495
496 // hack: b/c the same register offset is used to write cmd and read status
497 val nextCmd = Wire(UInt(8.W))
498 nextCmd := cmd.asUInt
499 cmd := (new CommandBundle).fromBits(nextCmd)
500
501 when (cmdAck || arbLost) {
502 cmd.start := false.B // clear command bits when done
503 cmd.stop := false.B // or when aribitration lost
504 cmd.read := false.B
505 cmd.write := false.B
506 }
507 cmd.irqAck := false.B // clear IRQ_ACK bit (essentially 1 cycle pulse b/c it is overwritten by regmap below)
508
509 status.receivedAck := receivedAck
510 when (stopCond) {
511 status.busy := false.B
512 }
513 .elsewhen (startCond) {
514 status.busy := true.B
515 }
516
517 when (arbLost) {
518 status.arbLost := true.B
519 }
520 .elsewhen (cmd.start) {
521 status.arbLost := false.B
522 }
523 status.transferInProgress := cmd.read || cmd.write
524 status.irqFlag := (cmdAck || arbLost || status.irqFlag) && !cmd.irqAck
525
526
527 regmap(
528 I2CCtrlRegs.prescaler_lo -> Seq(RegField(8, prescaler.lo)),
529 I2CCtrlRegs.prescaler_hi -> Seq(RegField(8, prescaler.hi)),
530 I2CCtrlRegs.control -> control.elements.map{ case(name, e) => RegField(e.getWidth, e.asInstanceOf[UInt]) }.toSeq,
531 I2CCtrlRegs.data -> Seq(RegField(8, r = RegReadFn(receivedData), w = RegWriteFn(transmitData))),
532 I2CCtrlRegs.cmd_status -> Seq(RegField(8, r = RegReadFn(status.asUInt), w = RegWriteFn(nextCmd)))
533 )
534
535 // tie off unused bits
536 control.reserved := 0.U
537 cmd.reserved := 0.U
538 status.reserved := 0.U
539
540 interrupts(0) := status.irqFlag & control.intEn
541 }
542
543 // Copied from UART.scala
544 class Majority(in: Set[Bool]) {
545 private val n = (in.size >> 1) + 1
546 private val clauses = in.subsets(n).map(_.reduce(_ && _))
547 val out = clauses.reduce(_ || _)
548 }
549
550
551 // Magic TL2 Incantation to create a TL2 Slave
552 class TLI2C(c: I2CConfig)(implicit p: Parameters)
553 extends TLRegisterRouter(c.address, interrupts = 1, beatBytes = p(PeripheryBusConfig).beatBytes)(
554 new TLRegBundle(c, _) with I2CBundle)(
555 new TLRegModule(c, _, _) with I2CModule)