1.1 --- a/pkg/devices/lib/i2c/src/x1600.cc Sat Oct 28 01:15:45 2023 +0200
1.2 +++ b/pkg/devices/lib/i2c/src/x1600.cc Sun Oct 29 16:14:38 2023 +0100
1.3 @@ -20,146 +20,6 @@
1.4 */
1.5
1.6 #include <l4/devices/i2c-x1600.h>
1.7 -#include <l4/devices/hw_mmio_register_block.h>
1.8 -
1.9 -#include <l4/sys/icu.h>
1.10 -#include <l4/util/util.h>
1.11 -#include <sys/time.h>
1.12 -
1.13 -/* NOTE: This peripheral is very similar to the JZ4780 with the registers
1.14 - renamed to I2C from SMB, with a few high speed registers added, and
1.15 - with I2C_SDAHD appearing at a different location. */
1.16 -
1.17 -enum Regs
1.18 -{
1.19 - I2c_control = 0x000, // I2C_CON
1.20 - I2c_target_address = 0x004, // I2C_TAR
1.21 - I2c_slave_address = 0x008, // I2C_SAR
1.22 - I2c_master_code = 0x00c, // I2C_HS_MADDR
1.23 - I2c_data_command = 0x010, // I2C_DC
1.24 - Std_high_count = 0x014, // I2C_SHCNT
1.25 - Std_low_count = 0x018, // I2C_SLCNT
1.26 - Fast_high_count = 0x01c, // I2C_FHCNT
1.27 - Fast_low_count = 0x020, // I2C_FLCNT
1.28 - High_high_count = 0x024, // I2C_HHCNT
1.29 - High_low_count = 0x028, // I2C_HLCNT
1.30 - Int_status = 0x02c, // I2C_INTST (read-only)
1.31 - Int_mask = 0x030, // I2C_INTM
1.32 - Int_raw_status = 0x034, // I2C_RINTST (read-only)
1.33 - Rx_fifo_thold = 0x038, // I2C_RXTL
1.34 - Tx_fifo_thold = 0x03c, // I2C_TXTL
1.35 - Int_combined_clear = 0x040, // I2C_CINT (read-only)
1.36 - Int_rx_uf_clear = 0x044, // I2C_CRXUF (read-only)
1.37 - Int_rx_of_clear = 0x048, // I2C_CRXOF (read-only)
1.38 - Int_tx_of_clear = 0x04c, // I2C_CTXOF (read-only)
1.39 - Int_rd_req_clear = 0x050, // I2C_CRXREQ (read-only)
1.40 - Int_tx_abort_clear = 0x054, // I2C_CTXABT (read-only)
1.41 - Int_rx_done_clear = 0x058, // I2C_CRXDN (read-only)
1.42 - Int_activity_clear = 0x05c, // I2C_CACT (read-only)
1.43 - Int_stop_clear = 0x060, // I2C_CSTP (read-only)
1.44 - Int_start_clear = 0x064, // I2C_CSTT (read-only)
1.45 - Int_call_clear = 0x068, // I2C_CGC (read-only)
1.46 - I2c_enable = 0x06c, // I2C_ENB
1.47 - I2c_status = 0x070, // I2C_ST (read-only)
1.48 - Tx_fifo_count = 0x074, // I2C_TXFLR (read-only)
1.49 - Rx_fifo_count = 0x078, // I2C_RXFLR (read-only)
1.50 - I2c_sda_hold_time = 0x07c, // I2C_SDAHD
1.51 - Trans_abort_status = 0x080, // I2C_ABTSRC (read-only)
1.52 - Slv_data_nack = 0x084, // I2CSDNACK
1.53 - I2c_dma_ctrl = 0x088, // I2C_DMACR
1.54 - I2c_trans_data_lvl = 0x08c, // I2C_DMATDLR
1.55 - I2c_recv_data_lvl = 0x090, // I2C_DMARDLR
1.56 - I2c_sda_setup_time = 0x094, // I2C_SDASU
1.57 - I2c_ack_call = 0x098, // I2C_ACKGC
1.58 - I2c_enable_status = 0x09c, // I2C_ENBST (read-only)
1.59 - I2c_spike_suppress = 0x0a0, // I2C_FSPKLEN
1.60 -
1.61 - I2c_block_offset = 0x1000
1.62 -};
1.63 -
1.64 -enum I2c_control_bits : unsigned
1.65 -{
1.66 - I2c_disable_slave = 0x40, // SLVDIS (slave disabled)
1.67 - I2c_enable_restart = 0x20, // RESTART
1.68 - I2c_master_10bit = 0x10, // MATP (read-only)
1.69 - I2c_slave_10bit = 0x08, // SATP
1.70 - I2c_speed_mode_mask = 0x06, // SPEED
1.71 - I2c_enable_master = 0x01, // MD (master enabled)
1.72 - I2c_speed_bit = 1, // SPD
1.73 -};
1.74 -
1.75 -enum I2c_speed_mode_values : unsigned
1.76 -{
1.77 - I2c_speed_standard = 1,
1.78 - I2c_speed_fast = 2,
1.79 - I2c_speed_high = 3,
1.80 -};
1.81 -
1.82 -enum I2c_enable_bits : unsigned
1.83 -{
1.84 - I2c_enable_enabled = 0x01, // I2CEN
1.85 -};
1.86 -
1.87 -enum I2c_status_bits : unsigned
1.88 -{
1.89 - I2c_status_master_act = 0x20, // MSTACT (master active)
1.90 - I2c_status_rx_nempty = 0x08, // RFNE (read queue not empty)
1.91 - I2c_status_tx_empty = 0x04, // TFE (write queue empty)
1.92 - I2c_status_tx_nfull = 0x02, // TFNF (write queue not full)
1.93 - I2c_status_active = 0x01, // ACT (device active as master or slave)
1.94 -};
1.95 -
1.96 -enum I2c_target_bits : unsigned
1.97 -{
1.98 - I2c_target_master_10bit = 0x1000,
1.99 - I2c_target_special = 0x0800, // SPECIAL: perform general call or start byte
1.100 - I2c_target_start_byte = 0x0400, // Special: start byte (1) or general call (0)
1.101 - I2c_target_10bits = 0x3ff, // Mask for 10-bit address
1.102 - I2c_target_7bits = 0x7f, // Mask for 7-bit address
1.103 -};
1.104 -
1.105 -enum I2c_hold_control_bits : unsigned
1.106 -{
1.107 - /* The hold enable flag has been removed since the JZ4780 and the hold time
1.108 - field widened. */
1.109 -
1.110 - I2c_hold_mask = 0xffff,
1.111 -};
1.112 -
1.113 -enum I2c_setup_control_bits : unsigned
1.114 -{
1.115 - I2c_setup_mask = 0x0ff, // SDASU
1.116 -};
1.117 -
1.118 -enum I2c_command_bits : unsigned
1.119 -{
1.120 - I2c_command_restart = 0x400, // RESTART: explicit restart before next byte
1.121 - I2c_command_stop = 0x200, // STOP: explicit stop after next byte
1.122 - I2c_command_no_stop = 0x000,
1.123 - I2c_command_read = 0x100, // CMD
1.124 - I2c_command_write = 0x000, // CMD
1.125 -};
1.126 -
1.127 -enum I2c_fifo_bits : unsigned
1.128 -{
1.129 - I2c_fifo_limit = 64, // RXTL, TXTL (256 noted in field description)
1.130 -};
1.131 -
1.132 -enum Int_bits : unsigned
1.133 -{
1.134 - Int_call = 0x800, // IGC (general call received)
1.135 - Int_start = 0x400, // ISTT (start/restart condition occurred)
1.136 - Int_stop = 0x200, // ISTP (stop condition occurred)
1.137 - Int_activity = 0x100, // IACT (bus activity interrupt)
1.138 - Int_rx_done = 0x080, // RXDN (read from master device done)
1.139 - Int_tx_abort = 0x040, // TXABT (transmit abort)
1.140 - Int_rd_req = 0x020, // RDREQ (read request from master device)
1.141 - Int_tx_empty = 0x010, // TXEMP (threshold reached or passed)
1.142 - Int_tx_of = 0x008, // TXOF (overflow when writing to queue)
1.143 - Int_rx_full = 0x004, // RXFL (threshold reached or exceeded)
1.144 - Int_rx_of = 0x002, // RXOF (overflow from device)
1.145 - Int_rx_uf = 0x001, // RXUF (underflow when reading from queue)
1.146 -};
1.147
1.148
1.149
1.150 @@ -167,508 +27,9 @@
1.151
1.152 I2c_x1600_channel::I2c_x1600_channel(l4_addr_t start,
1.153 enum Clock_identifiers clock,
1.154 - Cpm_x1600_chip *cpm,
1.155 + Cpm_chip *cpm,
1.156 uint32_t frequency)
1.157 -: _cpm(cpm), _frequency(frequency)
1.158 -{
1.159 - _regs = new Hw::Mmio_register_block<32>(start);
1.160 - _cpm->start_clock(clock);
1.161 -}
1.162 -
1.163 -// Enable the channel.
1.164 -
1.165 -void
1.166 -I2c_x1600_channel::enable()
1.167 -{
1.168 - _regs[I2c_enable] = I2c_enable_enabled;
1.169 - while (!(_regs[I2c_enable_status] & I2c_enable_enabled));
1.170 -}
1.171 -
1.172 -// Disable the channel.
1.173 -
1.174 -void
1.175 -I2c_x1600_channel::disable()
1.176 -{
1.177 - _regs[I2c_enable] = 0;
1.178 - while (_regs[I2c_enable_status] & I2c_enable_enabled);
1.179 -}
1.180 -
1.181 -// Return the configured frequency.
1.182 -
1.183 -uint32_t
1.184 -I2c_x1600_channel::get_frequency()
1.185 -{
1.186 - return _frequency;
1.187 -}
1.188 -
1.189 -// Set the frequency-related peripheral parameters.
1.190 -
1.191 -void
1.192 -I2c_x1600_channel::set_frequency()
1.193 -{
1.194 - // The APB clock (PCLK) is used to drive I2C transfers. Its value must be
1.195 - // obtained from the CPM unit. It is known as I2C_DEV_CLK here and is scaled
1.196 - // to kHz in order to keep the numbers easily representable, as is the bus
1.197 - // frequency.
1.198 -
1.199 - uint32_t i2c_dev_clk = _cpm->get_frequency(Clock_pclock) / 1000;
1.200 -
1.201 - // Note that this is not I2C_DEV_CLK but the actual I2C bus frequency.
1.202 -
1.203 - uint32_t i2c_clk = _frequency / 1000;
1.204 -
1.205 - // Select the appropriate speed.
1.206 -
1.207 - unsigned int speed = (i2c_clk <= 100) ? I2c_speed_standard
1.208 - : (i2c_clk <= 400 ? I2c_speed_fast
1.209 - : I2c_speed_high);
1.210 -
1.211 - // NOTE: Permit broader configuration elsewhere.
1.212 -
1.213 - _regs[I2c_control] = (speed << I2c_speed_bit) |
1.214 - I2c_disable_slave |
1.215 - I2c_enable_restart |
1.216 - I2c_enable_master;
1.217 -
1.218 - // According to the programming manual, if the PCLK period is T{I2C_DEV_CLK}
1.219 - // then the I2C clock period is...
1.220 -
1.221 - // T{SCL} = T{SCL_high} + T{SCL_low}
1.222 -
1.223 - // Where...
1.224 -
1.225 - // T{SCL_low} = T{I2C_DEV_CLK} * (#cycles for low signal)
1.226 - // T{SCL_high} = T{I2C_DEV_CLK} * (#cycles for high signal)
1.227 -
1.228 - // Since, with minimum periods being defined...
1.229 -
1.230 - // T{SCL} >= T{min_SCL}
1.231 - // T{SCL_low} >= T{min_SCL_low}
1.232 - // T{SCL_high} >= T{min_SCL_high}
1.233 - // T{min_SCL} = T{min_SCL_low} + T{min_SCL_high}
1.234 -
1.235 - // Then the following applies...
1.236 -
1.237 - // T{I2C_DEV_CLK} * (#cycles for low signal)) >= T{min_SCL_low}
1.238 - // T{I2C_DEV_CLK} * (#cycles for high signal) >= T{min_SCL_high}
1.239 -
1.240 - // To work with different clock speeds while maintaining the low-to-high
1.241 - // ratios:
1.242 -
1.243 - // T{min_SCL_low} = T{min_SCL} * T{min_SCL_low} / T{min_SCL}
1.244 - // = T{min_SCL} * (T{min_SCL_low} / (T{min_SCL_low} + T{min_SCL_high}))
1.245 -
1.246 - // T{min_SCL_high} = T{min_SCL} * T{min_SCL_high} / T{min_SCL}
1.247 - // = T{min_SCL} * (T{min_SCL_high} / (T{min_SCL_low} + T{min_SCL_high}))
1.248 -
1.249 - // Constraints are given with respect to the high and low count registers.
1.250 -
1.251 - // #cycles for high signal = I2CxHCNT + 8
1.252 - // #cycles for low signal = I2CxLCNT + 1
1.253 -
1.254 - // From earlier, this yields...
1.255 -
1.256 - // T{I2C_DEV_CLK} * (I2CxLCNT + 1) >= T{min_SCL_low}
1.257 - // T{I2C_DEV_CLK} * (I2CxHCNT + 8) >= T{min_SCL_high}
1.258 -
1.259 - // Rearranging...
1.260 -
1.261 - // I2CxLCNT >= (T{min_SCL_low} / T{I2C_DEV_CLK}) - 1
1.262 - // >= T{min_SCL_low} * I2C_DEV_CLK - 1
1.263 -
1.264 - // I2CxHCNT >= (T{min_SCL_high} / T{I2C_DEV_CLK}) - 8
1.265 - // >= T{min_SCL_high} * I2C_DEV_CLK - 8
1.266 -
1.267 - // Introducing the definitions for the high and low periods...
1.268 -
1.269 - // I2CxLCNT >= T{min_SCL} * (T{min_SCL_low} / (T{min_SCL_low} + T{min_SCL_high})) * I2C_DEV_CLK - 1
1.270 - // >= (T{min_SCL_low} / T{min_SCL}) * I2C_DEV_CLK / I2C_BUS_CLK - 1
1.271 -
1.272 - // I2CxHCNT >= T{min_SCL} * (T{min_SCL_high} / (T{min_SCL_low} + T{min_SCL_high})) * I2C_DEV_CLK - 8
1.273 - // >= (T{min_SCL_high} / T{min_SCL}) * I2C_DEV_CLK / I2C_BUS_CLK - 8
1.274 -
1.275 - uint32_t high_reg, low_reg;
1.276 - uint32_t high_count, low_count;
1.277 - int32_t hold_count;
1.278 - uint32_t setup_count;
1.279 -
1.280 - // Level hold times:
1.281 -
1.282 - // Standard Fast High
1.283 - // SCL low 4.7us 1.3us 0.5us
1.284 - // SCL high 4.0us 0.6us 0.26us +
1.285 - // SCL period 8.7us 1.9us 0.76us =
1.286 -
1.287 - // See: UM10204 "I2C-bus specification and user manual"
1.288 - // Table 10: t{LOW} and t{HIGH}
1.289 -
1.290 - if (i2c_clk <= 100) // 100 kHz
1.291 - {
1.292 - low_count = (i2c_dev_clk * 47) / (i2c_clk * 87) - 1;
1.293 - high_count = (i2c_dev_clk * 40) / (i2c_clk * 87) - 8;
1.294 - low_reg = Std_low_count;
1.295 - high_reg = Std_high_count;
1.296 - }
1.297 - else if (i2c_clk <= 400) // 400 kHz
1.298 - {
1.299 - low_count = (i2c_dev_clk * 13) / (i2c_clk * 19) - 1;
1.300 - high_count = (i2c_dev_clk * 6) / (i2c_clk * 19) - 8;
1.301 - low_reg = Fast_low_count;
1.302 - high_reg = Fast_high_count;
1.303 - }
1.304 - else // > 400 kHz
1.305 - {
1.306 - // Note how the frequencies are scaled to accommodate the extra precision
1.307 - // required.
1.308 -
1.309 - low_count = (i2c_dev_clk / 10 * 50) / (i2c_clk / 10 * 76) - 1;
1.310 - high_count = (i2c_dev_clk / 10 * 26) / (i2c_clk / 10 * 76) - 8;
1.311 - low_reg = High_low_count;
1.312 - high_reg = High_high_count;
1.313 - }
1.314 -
1.315 - // Minimum counts are 8 and 6 for low and high respectively.
1.316 -
1.317 - _regs[low_reg] = low_count < 8 ? 8 : low_count;
1.318 - _regs[high_reg] = high_count < 6 ? 6 : high_count;
1.319 -
1.320 - // Data hold and setup times:
1.321 -
1.322 - // Standard Fast High
1.323 - // t{HD;DAT} 300ns 300ns 300ns
1.324 - // t{SU;DAT} 250ns 100ns 50ns
1.325 -
1.326 - // See: UM10204 "I2C-bus specification and user manual"
1.327 - // Table 10: t{HD;DAT} and t{SU;DAT}, also note [3]
1.328 -
1.329 - // T{delay} = (I2CSDAHD + 2) * T{I2C_DEV_CLK}
1.330 - // I2CSDAHD = T{delay} / T{I2C_DEV_CLK} - 2
1.331 - // I2CSDAHD = I2C_DEV_CLK * T{delay} - 2
1.332 -
1.333 - // Since the device clock is in kHz (scaled down by 1000) and the times are
1.334 - // given in ns (scaled up by 1000000000), a division of 1000000 is introduced.
1.335 -
1.336 - hold_count = (i2c_dev_clk * 300) / 1000000 - 1;
1.337 -
1.338 - _regs[I2c_sda_hold_time] = (_regs[I2c_sda_hold_time] & ~I2c_hold_mask) |
1.339 - (hold_count < 0 ? 0
1.340 - : (hold_count < (int) I2c_hold_mask ? (uint32_t) hold_count
1.341 - : I2c_hold_mask));
1.342 -
1.343 - // I2C_SDASU is apparently not used in master mode.
1.344 -
1.345 - // T{delay} = (I2CSDASU - 1) * T{I2C_DEV_CLK}
1.346 - // I2CSDASU = T{delay} / T{I2C_DEV_CLK} + 1
1.347 - // I2CSDASU = I2C_DEV_CLK * T{delay} + 1
1.348 -
1.349 - if (i2c_clk <= 100)
1.350 - setup_count = (i2c_dev_clk * 250) / 1000000 + 1;
1.351 - else if (i2c_clk <= 400)
1.352 - setup_count = (i2c_dev_clk * 100) / 1000000 + 1;
1.353 - else
1.354 - setup_count = (i2c_dev_clk * 50) / 1000000 + 1;
1.355 -
1.356 - _regs[I2c_sda_setup_time] = (_regs[I2c_sda_setup_time] & ~I2c_setup_mask) |
1.357 - (setup_count < I2c_setup_mask ? setup_count : I2c_setup_mask);
1.358 -}
1.359 -
1.360 -// Set the target address and enable transfer.
1.361 -// NOTE: Only supporting 7-bit addresses currently.
1.362 -
1.363 -void
1.364 -I2c_x1600_channel::set_target(uint8_t address)
1.365 -{
1.366 - disable();
1.367 - set_frequency();
1.368 - _regs[I2c_target_address] = address & I2c_target_7bits;
1.369 - init_parameters();
1.370 - enable();
1.371 -}
1.372 -
1.373 -
1.374 -
1.375 -// Reset interrupt flags upon certain conditions.
1.376 -
1.377 -void
1.378 -I2c_x1600_channel::reset_flags()
1.379 -{
1.380 - volatile uint32_t r;
1.381 -
1.382 - _regs[Int_mask] = 0;
1.383 -
1.384 - // Read from the register to clear interrupts.
1.385 -
1.386 - r = _regs[Int_combined_clear];
1.387 - (void) r;
1.388 -}
1.389 -
1.390 -// Initialise interrupt flags and queue thresholds for reading and writing.
1.391 -
1.392 -void
1.393 -I2c_x1600_channel::init_parameters()
1.394 -{
1.395 - // Handle read queue conditions for data, write queue conditions for commands.
1.396 -
1.397 - reset_flags();
1.398 -
1.399 - _regs[Tx_fifo_thold] = 0; // write when 0 in queue
1.400 -}
1.401 -
1.402 -
1.403 -
1.404 -// Return whether the device is active.
1.405 -
1.406 -int
1.407 -I2c_x1600_channel::active()
1.408 -{
1.409 - return _regs[I2c_status] & I2c_status_master_act;
1.410 -}
1.411 -
1.412 -// Return whether data is available to receive.
1.413 -
1.414 -int
1.415 -I2c_x1600_channel::have_input()
1.416 -{
1.417 - return _regs[I2c_status] & I2c_status_rx_nempty;
1.418 -}
1.419 -
1.420 -// Return whether data is queued for sending.
1.421 -
1.422 -int
1.423 -I2c_x1600_channel::have_output()
1.424 -{
1.425 - return !(_regs[I2c_status] & I2c_status_tx_empty);
1.426 -}
1.427 -
1.428 -// Return whether data can be queued for sending.
1.429 -
1.430 -int
1.431 -I2c_x1600_channel::can_send()
1.432 -{
1.433 - return _regs[I2c_status] & I2c_status_tx_nfull;
1.434 -}
1.435 -
1.436 -// Return whether a receive operation has failed.
1.437 -
1.438 -int
1.439 -I2c_x1600_channel::read_failed()
1.440 -{
1.441 - return _regs[Int_status] & Int_rx_of;
1.442 -}
1.443 -
1.444 -// Return whether a send operation has failed.
1.445 -
1.446 -int
1.447 -I2c_x1600_channel::write_failed()
1.448 -{
1.449 - return _regs[Int_status] & Int_tx_abort;
1.450 -}
1.451 -
1.452 -int
1.453 -I2c_x1600_channel::read_done()
1.454 -{
1.455 - return _pos == _total;
1.456 -}
1.457 -
1.458 -int
1.459 -I2c_x1600_channel::write_done()
1.460 -{
1.461 - return (_reqpos == _total) && !have_output();
1.462 -}
1.463 -
1.464 -unsigned
1.465 -I2c_x1600_channel::have_read()
1.466 -{
1.467 - return _pos;
1.468 -}
1.469 -
1.470 -unsigned
1.471 -I2c_x1600_channel::have_written()
1.472 -{
1.473 - return _reqpos;
1.474 -}
1.475 -
1.476 -int
1.477 -I2c_x1600_channel::failed()
1.478 -{
1.479 - return _fail;
1.480 -}
1.481 -
1.482 -
1.483 -
1.484 -// Send read commands for empty queue entries.
1.485 -
1.486 -void
1.487 -I2c_x1600_channel::queue_reads()
1.488 -{
1.489 - unsigned int remaining = _total - _reqpos;
1.490 - unsigned int queued = _reqpos - _pos;
1.491 - unsigned int can_queue = I2c_fifo_limit - queued;
1.492 -
1.493 - // Keep the number of reads in progress below the length of the read queue.
1.494 -
1.495 - if (!can_queue)
1.496 - return;
1.497 -
1.498 - // At most, only queue as many reads as are remaining.
1.499 -
1.500 - if (remaining < can_queue)
1.501 - can_queue = remaining;
1.502 -
1.503 - // Queue read requests for any remaining queue entries.
1.504 -
1.505 - while (can_queue && can_send())
1.506 - {
1.507 - uint32_t stop = _stop && (_reqpos == _total - 1) ? I2c_command_stop : I2c_command_no_stop;
1.508 -
1.509 - _regs[I2c_data_command] = I2c_command_read | stop;
1.510 - _reqpos++;
1.511 - can_queue--;
1.512 - }
1.513 -
1.514 - // Update the threshold to be notified of any reduced remaining amount.
1.515 -
1.516 - set_read_threshold();
1.517 -}
1.518 -
1.519 -// Send write commands for empty queue entries.
1.520 -
1.521 -void
1.522 -I2c_x1600_channel::queue_writes()
1.523 -{
1.524 - unsigned int remaining = _total - _reqpos;
1.525 - unsigned int can_queue = I2c_fifo_limit;
1.526 -
1.527 - if (remaining < can_queue)
1.528 - can_queue = remaining;
1.529 -
1.530 - // Queue write requests for any remaining queue entries.
1.531 -
1.532 - while (can_queue && can_send())
1.533 - {
1.534 - uint32_t stop = _stop && (_reqpos == _total - 1) ? I2c_command_stop : I2c_command_no_stop;
1.535 -
1.536 - _regs[I2c_data_command] = I2c_command_write | _buf[_reqpos] | stop;
1.537 - _reqpos++;
1.538 - can_queue--;
1.539 - }
1.540 -}
1.541 -
1.542 -// Store read command results from the queue.
1.543 -
1.544 -void
1.545 -I2c_x1600_channel::store_reads()
1.546 -{
1.547 - // Read any input and store it in the buffer.
1.548 -
1.549 - while (have_input() && (_pos < _reqpos))
1.550 - {
1.551 - _buf[_pos] = _regs[I2c_data_command] & 0xff;
1.552 - _pos++;
1.553 - }
1.554 -}
1.555 -
1.556 -void
1.557 -I2c_x1600_channel::set_read_threshold()
1.558 -{
1.559 - unsigned int queued = _reqpos - _pos;
1.560 -
1.561 - if (!queued)
1.562 - return;
1.563 -
1.564 - // Read all expected.
1.565 -
1.566 - _regs[Rx_fifo_thold] = queued - 1;
1.567 -}
1.568 -
1.569 -// Read from the target device.
1.570 -
1.571 -void
1.572 -I2c_x1600_channel::start_read(uint8_t buf[], unsigned int total, int stop)
1.573 -{
1.574 - _buf = buf;
1.575 - _total = total;
1.576 - _pos = 0;
1.577 - _reqpos = 0;
1.578 - _fail = 0;
1.579 - _stop = stop;
1.580 -
1.581 - reset_flags();
1.582 -
1.583 - _regs[Int_mask] = Int_rx_full | // read condition (reading needed)
1.584 - Int_rx_of | // abort condition
1.585 - Int_tx_abort; // general abort condition
1.586 -
1.587 - // Perform initial read requests.
1.588 -
1.589 - read();
1.590 -}
1.591 -
1.592 -void
1.593 -I2c_x1600_channel::read()
1.594 -{
1.595 - // Test for the general transfer abort condition.
1.596 -
1.597 - if (read_failed() || write_failed())
1.598 - {
1.599 - _fail = 1;
1.600 - _regs[Int_mask] = 0;
1.601 - disable();
1.602 - enable();
1.603 - return;
1.604 - }
1.605 -
1.606 - if (_regs[Int_status] & Int_rx_full)
1.607 - store_reads();
1.608 -
1.609 - // Always attempt to queue more read requests.
1.610 -
1.611 - queue_reads();
1.612 -}
1.613 -
1.614 -// Write to the target device.
1.615 -
1.616 -void
1.617 -I2c_x1600_channel::start_write(uint8_t buf[], unsigned int total, int stop)
1.618 -{
1.619 - _buf = buf;
1.620 - _total = total;
1.621 - _reqpos = 0;
1.622 - _fail = 0;
1.623 - _stop = stop;
1.624 -
1.625 - reset_flags();
1.626 -
1.627 - // Enable interrupts for further writes.
1.628 -
1.629 - _regs[Int_mask] = Int_tx_empty | // write condition (writing needed)
1.630 - Int_tx_abort; // abort condition
1.631 -
1.632 - // Perform initial writes.
1.633 -
1.634 - write();
1.635 -}
1.636 -
1.637 -void
1.638 -I2c_x1600_channel::write()
1.639 -{
1.640 - if (write_failed())
1.641 - {
1.642 - _fail = 1;
1.643 - _regs[Int_mask] = 0;
1.644 - disable();
1.645 - enable();
1.646 - return;
1.647 - }
1.648 -
1.649 - if (_regs[Int_status] & Int_tx_empty)
1.650 - queue_writes();
1.651 -}
1.652 -
1.653 -// Explicitly stop communication.
1.654 -
1.655 -void
1.656 -I2c_x1600_channel::stop()
1.657 +: I2c_channel(start, clock, cpm, frequency)
1.658 {
1.659 }
1.660
1.661 @@ -677,33 +38,19 @@
1.662 // Initialise the I2C controller.
1.663
1.664 I2c_x1600_chip::I2c_x1600_chip(l4_addr_t start, l4_addr_t end,
1.665 - Cpm_x1600_chip *cpm,
1.666 - uint32_t frequency)
1.667 -: _start(start), _end(end), _cpm(cpm), _frequency(frequency)
1.668 + Cpm_chip *cpm,
1.669 + uint32_t frequency)
1.670 +: I2c_chip(start, end, cpm, frequency)
1.671 {
1.672 }
1.673
1.674 -// Obtain a channel object.
1.675 -
1.676 -I2c_x1600_channel *
1.677 -I2c_x1600_chip::get_channel(uint8_t channel)
1.678 -{
1.679 - l4_addr_t block = _start + channel * I2c_block_offset;
1.680 - enum Clock_identifiers clocks[] = {Clock_i2c0, Clock_i2c1};
1.681 -
1.682 - if (channel < 2)
1.683 - return new I2c_x1600_channel(block, clocks[channel], _cpm, _frequency);
1.684 - else
1.685 - throw -L4_EINVAL;
1.686 -}
1.687 -
1.688
1.689
1.690 // C language interface functions.
1.691
1.692 void *x1600_i2c_init(l4_addr_t start, l4_addr_t end, void *cpm, uint32_t frequency)
1.693 {
1.694 - return (void *) new I2c_x1600_chip(start, end, static_cast<Cpm_x1600_chip *>(cpm), frequency);
1.695 + return (void *) new I2c_x1600_chip(start, end, static_cast<Cpm_chip *>(cpm), frequency);
1.696 }
1.697
1.698 void *x1600_i2c_get_channel(void *i2c, uint8_t channel)