Initial (compilable) version of I2C (no actual logic yet)
[sifive-blocks.git] / src / main / scala / devices / i2c / I2C.scala
1 // See LICENSE for license details.
2 package sifive.blocks.devices.i2c
3
4 import Chisel._
5 import config._
6 import regmapper._
7 import uncore.tilelink2._
8 import rocketchip.PeripheryBusConfig
9 import util.AsyncResetRegVec
10 import sifive.blocks.devices.gpio.{GPIOPinCtrl}
11
12 case class I2CConfig(address: BigInt)
13
14 trait HasI2CParameters {
15 implicit val p: Parameters
16 val params: I2CConfig
17 val c = params
18 }
19
20 class I2CPin extends Bundle {
21 val in = Bool(INPUT)
22 val out = Bool(OUTPUT)
23 val oe = Bool(OUTPUT)
24 }
25
26 class I2CPort extends Bundle {
27 val scl = new I2CPin
28 val sda = new I2CPin
29 }
30
31 trait I2CBundle extends Bundle with HasI2CParameters {
32 val port = new I2CPort
33 }
34
35 trait I2CModule extends Module with HasI2CParameters with HasRegMap {
36 val io: I2CBundle
37
38 val prescaler_lo = Reg(UInt(8.W)) // low byte clock prescaler register
39 val prescaler_hi = Reg(UInt(8.W)) // high byte clock prescaler register
40 val control = Reg(UInt(8.W)) // control register
41 val data = Reg(UInt(8.W)) // write: transmit byte, read: receive byte
42 val cmd_status = Reg(UInt(8.W)) // write: command, read: status
43
44 // Note that these are out of order.
45 regmap(
46 I2CCtrlRegs.prescaler_lo -> Seq(RegField(8, prescaler_lo)),
47 I2CCtrlRegs.prescaler_hi -> Seq(RegField(8, prescaler_hi)),
48 I2CCtrlRegs.control -> Seq(RegField(8, control)),
49 I2CCtrlRegs.data -> Seq(RegField(8, data)),
50 I2CCtrlRegs.cmd_status -> Seq(RegField(8, cmd_status))
51 )
52 }
53
54 // Magic TL2 Incantation to create a TL2 Slave
55 class TLI2C(c: I2CConfig)(implicit p: Parameters)
56 extends TLRegisterRouter(c.address, interrupts = 1, beatBytes = p(PeripheryBusConfig).beatBytes)(
57 new TLRegBundle(c, _) with I2CBundle)(
58 new TLRegModule(c, _, _) with I2CModule)