|
2 | 2 | from k0emu.bus import Bus |
3 | 3 | from k0emu.devices import (MemoryDevice, RegisterFileDevice, |
4 | 4 | ProcessorStatusDevice, InterruptControllerDevice, |
| 5 | + I2CControllerDevice, |
5 | 6 | WatchdogDevice, WatchTimerDevice) |
| 7 | +from k0emu.i2c import StubI2CTarget |
6 | 8 |
|
7 | 9 |
|
8 | 10 | class MemoryDeviceTests(unittest.TestCase): |
@@ -1007,3 +1009,196 @@ def test_write_out_of_bounds_raises(self): |
1007 | 1009 | wt.write(1, 0x00) |
1008 | 1010 |
|
1009 | 1011 |
|
| 1012 | +class _FakeProcessor(object): |
| 1013 | + def __init__(self): |
| 1014 | + self.reset_count = 0 |
| 1015 | + |
| 1016 | + def reset(self): |
| 1017 | + self.reset_count += 1 |
| 1018 | + |
| 1019 | + |
| 1020 | +def _make_i2c_on_bus(): |
| 1021 | + proc = _FakeProcessor() |
| 1022 | + bus = Bus(proc) |
| 1023 | + intc = InterruptControllerDevice("intc") |
| 1024 | + bus.add_device(intc, (0xFFE0, 0xFFEB)) |
| 1025 | + bus.set_interrupt_controller(intc) |
| 1026 | + i2c = I2CControllerDevice("iic0") |
| 1027 | + bus.add_device(i2c, (0xFF1F, 0xFF1F), (0xFFA8, 0xFFAA)) |
| 1028 | + intc.connect(i2c, i2c.INT_TRANSFER, intc.INTIIC0) |
| 1029 | + return i2c, intc, bus |
| 1030 | + |
| 1031 | + |
| 1032 | +class I2CControllerTests(unittest.TestCase): |
| 1033 | + |
| 1034 | + def _iicif0_set(self, intc): |
| 1035 | + return bool(intc.read(InterruptControllerDevice.IF0H) & 0x40) |
| 1036 | + |
| 1037 | + def _clear_iicif0(self, intc): |
| 1038 | + intc.write(InterruptControllerDevice.IF0H, |
| 1039 | + intc.read(InterruptControllerDevice.IF0H) & ~0x40) |
| 1040 | + |
| 1041 | + # basics |
| 1042 | + |
| 1043 | + def test_name(self): |
| 1044 | + i2c = I2CControllerDevice("iic0") |
| 1045 | + self.assertEqual(i2c.name, "iic0") |
| 1046 | + |
| 1047 | + def test_size(self): |
| 1048 | + i2c = I2CControllerDevice("iic0") |
| 1049 | + self.assertEqual(i2c.size, 4) |
| 1050 | + |
| 1051 | + def test_registers_initially_zero(self): |
| 1052 | + i2c = I2CControllerDevice("iic0") |
| 1053 | + for reg in range(4): |
| 1054 | + self.assertEqual(i2c.read(reg), 0x00) |
| 1055 | + |
| 1056 | + def test_iic0_write_read(self): |
| 1057 | + i2c = I2CControllerDevice("iic0") |
| 1058 | + i2c.write(I2CControllerDevice.IIC0, 0x42) |
| 1059 | + self.assertEqual(i2c.read(I2CControllerDevice.IIC0), 0x42) |
| 1060 | + |
| 1061 | + def test_iiccl0_write_read(self): |
| 1062 | + i2c = I2CControllerDevice("iic0") |
| 1063 | + i2c.write(I2CControllerDevice.IICCL0, 0x0C) |
| 1064 | + self.assertEqual(i2c.read(I2CControllerDevice.IICCL0), 0x0C) |
| 1065 | + |
| 1066 | + def test_disable_clears_status(self): |
| 1067 | + i2c = I2CControllerDevice("iic0") |
| 1068 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0) |
| 1069 | + i2c.write(I2CControllerDevice.IICS0, 0xFF) |
| 1070 | + i2c.write(I2CControllerDevice.IICC0, 0x00) # disable |
| 1071 | + self.assertEqual(i2c.read(I2CControllerDevice.IICS0), 0x00) |
| 1072 | + |
| 1073 | + # writing |
| 1074 | + |
| 1075 | + def test_start_sets_iicif0(self): |
| 1076 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1077 | + stub = StubI2CTarget() |
| 1078 | + i2c.add_target(0x50, stub) |
| 1079 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1080 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1081 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1082 | + self.assertTrue(self._iicif0_set(intc)) |
| 1083 | + |
| 1084 | + def test_start_sets_msts0_and_trc0(self): |
| 1085 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1086 | + stub = StubI2CTarget() |
| 1087 | + i2c.add_target(0x50, stub) |
| 1088 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1089 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1090 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1091 | + iics0 = i2c.read(I2CControllerDevice.IICS0) |
| 1092 | + self.assertTrue(iics0 & I2CControllerDevice.MSTS0) |
| 1093 | + self.assertTrue(iics0 & I2CControllerDevice.TRC0) |
| 1094 | + |
| 1095 | + def test_start_sets_ackd0_when_target_present(self): |
| 1096 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1097 | + stub = StubI2CTarget() |
| 1098 | + i2c.add_target(0x50, stub) |
| 1099 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1100 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1101 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1102 | + self.assertTrue(i2c.read(I2CControllerDevice.IICS0) & I2CControllerDevice.ACKD0) |
| 1103 | + |
| 1104 | + def test_start_clears_ackd0_when_no_target(self): |
| 1105 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1106 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1107 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1108 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1109 | + self.assertFalse(i2c.read(I2CControllerDevice.IICS0) & I2CControllerDevice.ACKD0) |
| 1110 | + |
| 1111 | + def test_start_clears_stt0(self): |
| 1112 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1113 | + stub = StubI2CTarget() |
| 1114 | + i2c.add_target(0x50, stub) |
| 1115 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1116 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1117 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1118 | + self.assertFalse(i2c.read(I2CControllerDevice.IICC0) & I2CControllerDevice.STT0) |
| 1119 | + |
| 1120 | + def test_start_enters_wait_state(self): |
| 1121 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1122 | + stub = StubI2CTarget() |
| 1123 | + i2c.add_target(0x50, stub) |
| 1124 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1125 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1126 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1127 | + self.assertTrue(i2c._waiting) |
| 1128 | + |
| 1129 | + def test_data_write_triggers_transfer(self): |
| 1130 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1131 | + stub = StubI2CTarget() |
| 1132 | + i2c.add_target(0x50, stub) |
| 1133 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1134 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1135 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1136 | + self._clear_iicif0(intc) |
| 1137 | + i2c.write(I2CControllerDevice.IIC0, 0x42) |
| 1138 | + self.assertTrue(self._iicif0_set(intc)) |
| 1139 | + |
| 1140 | + def test_data_write_gets_ack_from_target(self): |
| 1141 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1142 | + stub = StubI2CTarget() |
| 1143 | + i2c.add_target(0x50, stub) |
| 1144 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1145 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1146 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1147 | + self._clear_iicif0(intc) |
| 1148 | + i2c.write(I2CControllerDevice.IIC0, 0x42) |
| 1149 | + self.assertTrue(i2c.read(I2CControllerDevice.IICS0) & I2CControllerDevice.ACKD0) |
| 1150 | + |
| 1151 | + def test_stop_sets_std0(self): |
| 1152 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1153 | + stub = StubI2CTarget() |
| 1154 | + i2c.add_target(0x50, stub) |
| 1155 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1156 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1157 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1158 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1159 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.SPT0) |
| 1160 | + self.assertTrue(i2c.read(I2CControllerDevice.IICS0) & I2CControllerDevice.STD0) |
| 1161 | + |
| 1162 | + def test_stop_clears_waiting(self): |
| 1163 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1164 | + stub = StubI2CTarget() |
| 1165 | + i2c.add_target(0x50, stub) |
| 1166 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1167 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1168 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1169 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1170 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.SPT0) |
| 1171 | + self.assertFalse(i2c._waiting) |
| 1172 | + |
| 1173 | + def test_waiting_persists_across_bytes(self): |
| 1174 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1175 | + stub = StubI2CTarget() |
| 1176 | + i2c.add_target(0x50, stub) |
| 1177 | + i2c.write(I2CControllerDevice.IIC0, 0xA0) |
| 1178 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1179 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1180 | + self._clear_iicif0(intc) |
| 1181 | + self.assertTrue(i2c._waiting) |
| 1182 | + i2c.write(I2CControllerDevice.IIC0, 0x10) |
| 1183 | + self._clear_iicif0(intc) |
| 1184 | + self.assertTrue(i2c._waiting) |
| 1185 | + i2c.write(I2CControllerDevice.IIC0, 0x42) |
| 1186 | + self._clear_iicif0(intc) |
| 1187 | + self.assertTrue(i2c._waiting) |
| 1188 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1189 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.SPT0) |
| 1190 | + self.assertFalse(i2c._waiting) |
| 1191 | + |
| 1192 | + # reading |
| 1193 | + |
| 1194 | + def test_read_byte_from_target(self): |
| 1195 | + i2c, intc, bus = _make_i2c_on_bus() |
| 1196 | + stub = StubI2CTarget(read_value=0x42) |
| 1197 | + i2c.add_target(0x50, stub) |
| 1198 | + i2c.write(I2CControllerDevice.IIC0, 0xA1) |
| 1199 | + i2c.write(I2CControllerDevice.IICC0, I2CControllerDevice.IICE0 | I2CControllerDevice.WTIM0 |
| 1200 | + | I2CControllerDevice.ACKE0 | I2CControllerDevice.STT0) |
| 1201 | + self._clear_iicif0(intc) |
| 1202 | + i2c.write(I2CControllerDevice.IIC0, 0xFF) |
| 1203 | + self.assertEqual(i2c.read(I2CControllerDevice.IIC0), 0x42) |
| 1204 | + self.assertTrue(self._iicif0_set(intc)) |
0 commit comments