On Wed, Sep 18, 2024 at 2:31 PM Corey Minyard <co...@minyard.net> wrote: > > On Wed, Sep 18, 2024 at 02:04:58PM -0700, Octavian Purdila wrote: > > On Wed, Sep 18, 2024 at 1:17???PM Corey Minyard <co...@minyard.net> wrote: > > > > > > On Wed, Sep 18, 2024 at 12:22:36PM -0700, Octavian Purdila wrote: > > > > Add support for NXP's flexcomm i2c. It does not support slave mode or > > > > DMA. > > > > > > > > The patch includes an automatically generated header which contains > > > > the register layout and helpers. > > > > > > > > The header can be regenerated with the svd-flexcomm-i2c target when > > > > the build is configured with --enable-mcux-soc-svd. > > > > > > > > Signed-off-by: Octavian Purdila <ta...@google.com> > > > > --- > > > > include/hw/arm/svd/flexcomm_i2c.h | 1190 +++++++++++++++++++++++++++++ > > > > include/hw/i2c/flexcomm_i2c.h | 40 + > > > > include/hw/misc/flexcomm.h | 2 + > > > > hw/i2c/flexcomm_i2c.c | 250 ++++++ > > > > hw/misc/flexcomm.c | 3 + > > > > hw/arm/svd/meson.build | 3 + > > > > hw/i2c/meson.build | 1 + > > > > hw/i2c/trace-events | 10 + > > > > hw/misc/Kconfig | 1 + > > > > 9 files changed, 1500 insertions(+) > > > > create mode 100644 include/hw/arm/svd/flexcomm_i2c.h > > > > create mode 100644 include/hw/i2c/flexcomm_i2c.h > > > > create mode 100644 hw/i2c/flexcomm_i2c.c > > > > > > > > diff --git a/include/hw/arm/svd/flexcomm_i2c.h > > > > b/include/hw/arm/svd/flexcomm_i2c.h > > > > new file mode 100644 > > > > index 0000000000..9017d48446 > > > > --- /dev/null > > > > +++ b/include/hw/arm/svd/flexcomm_i2c.h > > > > @@ -0,0 +1,1190 @@ > > > > +/* > > > > + * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause > > > > + * > > > > + * Automatically generated by svd-gen-header.py from > > > > MIMXRT595S_cm33.xml > > > > + */ > > > > +#pragma once > > > > + > > > > +#include "hw/register.h" > > > > + > > > > +/* I2C Bus Interface */ > > > > +#define FLEXCOMM_I2C_REGS_NO (1024) > > > > + > > > > +/* Configuration Register */ > > > > +REG32(FLEXCOMM_I2C_CFG, 2048); > > > > +/* Master Enable */ > > > > +FIELD(FLEXCOMM_I2C_CFG, MSTEN, 0, 1); > > > > +/* Slave Enable */ > > > > +FIELD(FLEXCOMM_I2C_CFG, SLVEN, 1, 1); > > > > +/* Monitor Enable */ > > > > +FIELD(FLEXCOMM_I2C_CFG, MONEN, 2, 1); > > > > +/* I2C bus Time-out Enable */ > > > > +FIELD(FLEXCOMM_I2C_CFG, TIMEOUTEN, 3, 1); > > > > +/* Monitor function Clock Stretching */ > > > > +FIELD(FLEXCOMM_I2C_CFG, MONCLKSTR, 4, 1); > > > > +/* High Speed mode Capable enable */ > > > > +FIELD(FLEXCOMM_I2C_CFG, HSCAPABLE, 5, 1); > > > > + > > > > +/* Status Register */ > > > > +REG32(FLEXCOMM_I2C_STAT, 2052); > > > > +/* Master Pending */ > > > > +FIELD(FLEXCOMM_I2C_STAT, MSTPENDING, 0, 1); > > > > +/* Master State code */ > > > > +FIELD(FLEXCOMM_I2C_STAT, MSTSTATE, 1, 3); > > > > +/* Master Arbitration Loss flag */ > > > > +FIELD(FLEXCOMM_I2C_STAT, MSTARBLOSS, 4, 1); > > > > +/* Master Start/Stop Error flag */ > > > > +FIELD(FLEXCOMM_I2C_STAT, MSTSTSTPERR, 6, 1); > > > > +/* Slave Pending */ > > > > +FIELD(FLEXCOMM_I2C_STAT, SLVPENDING, 8, 1); > > > > +/* Slave State */ > > > > +FIELD(FLEXCOMM_I2C_STAT, SLVSTATE, 9, 2); > > > > +/* Slave Not Stretching */ > > > > +FIELD(FLEXCOMM_I2C_STAT, SLVNOTSTR, 11, 1); > > > > +/* Slave address match Index T */ > > > > +FIELD(FLEXCOMM_I2C_STAT, SLVIDX, 12, 2); > > > > +/* Slave selected flag */ > > > > +FIELD(FLEXCOMM_I2C_STAT, SLVSEL, 14, 1); > > > > +/* Slave Deselected flag */ > > > > +FIELD(FLEXCOMM_I2C_STAT, SLVDESEL, 15, 1); > > > > +/* Monitor Ready */ > > > > +FIELD(FLEXCOMM_I2C_STAT, MONRDY, 16, 1); > > > > +/* Monitor Overflow flag */ > > > > +FIELD(FLEXCOMM_I2C_STAT, MONOV, 17, 1); > > > > +/* Monitor Active flag */ > > > > +FIELD(FLEXCOMM_I2C_STAT, MONACTIVE, 18, 1); > > > > +/* Monitor Idle flag */ > > > > +FIELD(FLEXCOMM_I2C_STAT, MONIDLE, 19, 1); > > > > +/* Event Time-out Interrupt flag */ > > > > +FIELD(FLEXCOMM_I2C_STAT, EVENTTIMEOUT, 24, 1); > > > > +/* SCL Time-out Interrupt flag */ > > > > +FIELD(FLEXCOMM_I2C_STAT, SCLTIMEOUT, 25, 1); > > > > + > > > > +/* Interrupt Enable Set Register */ > > > > +REG32(FLEXCOMM_I2C_INTENSET, 2056); > > > > +/* Master Pending interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, MSTPENDINGEN, 0, 1); > > > > +/* Master Arbitration Loss interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, MSTARBLOSSEN, 4, 1); > > > > +/* Master Start/Stop Error interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, MSTSTSTPERREN, 6, 1); > > > > +/* Slave Pending interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, SLVPENDINGEN, 8, 1); > > > > +/* Slave Not Stretching interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, SLVNOTSTREN, 11, 1); > > > > +/* Slave Deselect interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, SLVDESELEN, 15, 1); > > > > +/* Monitor data Ready interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, MONRDYEN, 16, 1); > > > > +/* Monitor Overrun interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, MONOVEN, 17, 1); > > > > +/* Monitor Idle interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, MONIDLEEN, 19, 1); > > > > +/* Event Time-out interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, EVENTTIMEOUTEN, 24, 1); > > > > +/* SCL Time-out interrupt Enable */ > > > > +FIELD(FLEXCOMM_I2C_INTENSET, SCLTIMEOUTEN, 25, 1); > > > > + > > > > +/* Interrupt Enable Clear Register */ > > > > +REG32(FLEXCOMM_I2C_INTENCLR, 2060); > > > > +/* Master Pending interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTPENDINGCLR, 0, 1); > > > > +/* Master Arbitration Loss interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTARBLOSSCLR, 4, 1); > > > > +/* Master Start/Stop Error interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTSTSTPERRCLR, 6, 1); > > > > +/* Slave Pending interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVPENDINGCLR, 8, 1); > > > > +/* Slave Not Stretching interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVNOTSTRCLR, 11, 1); > > > > +/* Slave Deselect interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVDESELCLR, 15, 1); > > > > +/* Monitor data Ready interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MONRDYCLR, 16, 1); > > > > +/* Monitor Overrun interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MONOVCLR, 17, 1); > > > > +/* Monitor Idle interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MONIDLECLR, 19, 1); > > > > +/* Event time-out interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, EVENTTIMEOUTCLR, 24, 1); > > > > +/* SCL time-out interrupt clear */ > > > > +FIELD(FLEXCOMM_I2C_INTENCLR, SCLTIMEOUTCLR, 25, 1); > > > > + > > > > +/* Time-out Register */ > > > > +REG32(FLEXCOMM_I2C_TIMEOUT, 2064); > > > > +/* Time-out time value, the bottom 4 bits */ > > > > +FIELD(FLEXCOMM_I2C_TIMEOUT, TOMIN, 0, 4); > > > > +/* Time-out time value */ > > > > +FIELD(FLEXCOMM_I2C_TIMEOUT, TO, 4, 12); > > > > + > > > > +/* Clock Divider Register */ > > > > +REG32(FLEXCOMM_I2C_CLKDIV, 2068); > > > > +/* Divider Value */ > > > > +FIELD(FLEXCOMM_I2C_CLKDIV, DIVVAL, 0, 16); > > > > + > > > > +/* Interrupt Status Register */ > > > > +REG32(FLEXCOMM_I2C_INTSTAT, 2072); > > > > +/* Master Pending */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTPENDING, 0, 1); > > > > +/* Master Arbitration Loss flag */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTARBLOSS, 4, 1); > > > > +/* Master Start/Stop Error flag */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTSTSTPERR, 6, 1); > > > > +/* Slave Pending */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVPENDING, 8, 1); > > > > +/* Slave Not Stretching status */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVNOTSTR, 11, 1); > > > > +/* Slave Deselected flag */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVDESEL, 15, 1); > > > > +/* Monitor Ready */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MONRDY, 16, 1); > > > > +/* Monitor Overflow flag */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MONOV, 17, 1); > > > > +/* Monitor Idle flag */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MONIDLE, 19, 1); > > > > +/* Event Time-out Interrupt flag */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, EVENTTIMEOUT, 24, 1); > > > > +/* SCL Time-out Interrupt flag */ > > > > +FIELD(FLEXCOMM_I2C_INTSTAT, SCLTIMEOUT, 25, 1); > > > > + > > > > +/* Master Control Register */ > > > > +REG32(FLEXCOMM_I2C_MSTCTL, 2080); > > > > +/* Master Continue(write-only) */ > > > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTCONTINUE, 0, 1); > > > > +/* Master Start control(write-only) */ > > > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTART, 1, 1); > > > > +/* Master Stop control(write-only) */ > > > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTOP, 2, 1); > > > > +/* Master DMA enable */ > > > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTDMA, 3, 1); > > > > + > > > > +/* Master Timing Register */ > > > > +REG32(FLEXCOMM_I2C_MSTTIME, 2084); > > > > +/* Master SCL Low time */ > > > > +FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLLOW, 0, 3); > > > > +/* Master SCL High time */ > > > > +FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLHIGH, 4, 3); > > > > + > > > > +/* Master Data Register */ > > > > +REG32(FLEXCOMM_I2C_MSTDAT, 2088); > > > > +/* Master function data register */ > > > > +FIELD(FLEXCOMM_I2C_MSTDAT, DATA, 0, 8); > > > > + > > > > +/* Slave Control Register */ > > > > +REG32(FLEXCOMM_I2C_SLVCTL, 2112); > > > > +/* Slave Continue */ > > > > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVCONTINUE, 0, 1); > > > > +/* Slave NACK */ > > > > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVNACK, 1, 1); > > > > +/* Slave DMA enable */ > > > > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVDMA, 3, 1); > > > > +/* Automatic Acknowledge */ > > > > +FIELD(FLEXCOMM_I2C_SLVCTL, AUTOACK, 8, 1); > > > > +/* Automatic Match Read */ > > > > +FIELD(FLEXCOMM_I2C_SLVCTL, AUTOMATCHREAD, 9, 1); > > > > + > > > > +/* Slave Data Register */ > > > > +REG32(FLEXCOMM_I2C_SLVDAT, 2116); > > > > +/* Slave function data register */ > > > > +FIELD(FLEXCOMM_I2C_SLVDAT, DATA, 0, 8); > > > > + > > > > +/* Slave Address Register */ > > > > +REG32(FLEXCOMM_I2C_SLVADR0, 2120); > > > > +/* Slave Address n Disable */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR0, SADISABLE, 0, 1); > > > > +/* Slave Address. */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR0, SLVADR, 1, 7); > > > > +/* Automatic NACK operation */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR0, AUTONACK, 15, 1); > > > > + > > > > +/* Slave Address Register */ > > > > +REG32(FLEXCOMM_I2C_SLVADR1, 2124); > > > > +/* Slave Address n Disable */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR1, SADISABLE, 0, 1); > > > > +/* Slave Address. */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR1, SLVADR, 1, 7); > > > > +/* Automatic NACK operation */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR1, AUTONACK, 15, 1); > > > > + > > > > +/* Slave Address Register */ > > > > +REG32(FLEXCOMM_I2C_SLVADR2, 2128); > > > > +/* Slave Address n Disable */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR2, SADISABLE, 0, 1); > > > > +/* Slave Address. */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR2, SLVADR, 1, 7); > > > > +/* Automatic NACK operation */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR2, AUTONACK, 15, 1); > > > > + > > > > +/* Slave Address Register */ > > > > +REG32(FLEXCOMM_I2C_SLVADR3, 2132); > > > > +/* Slave Address n Disable */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR3, SADISABLE, 0, 1); > > > > +/* Slave Address. */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR3, SLVADR, 1, 7); > > > > +/* Automatic NACK operation */ > > > > +FIELD(FLEXCOMM_I2C_SLVADR3, AUTONACK, 15, 1); > > > > + > > > > +/* Slave Qualification for Address 0 Register */ > > > > +REG32(FLEXCOMM_I2C_SLVQUAL0, 2136); > > > > +/* Qualify mode for slave address 0 */ > > > > +FIELD(FLEXCOMM_I2C_SLVQUAL0, QUALMODE0, 0, 1); > > > > +/* Slave address Qualifier for address 0 */ > > > > +FIELD(FLEXCOMM_I2C_SLVQUAL0, SLVQUAL0, 1, 7); > > > > + > > > > +/* Monitor Receiver Data Register */ > > > > +REG32(FLEXCOMM_I2C_MONRXDAT, 2176); > > > > +/* Monitor function Receiver Data */ > > > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONRXDAT, 0, 8); > > > > +/* Monitor Received Start */ > > > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONSTART, 8, 1); > > > > +/* Monitor Received Repeated Start */ > > > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONRESTART, 9, 1); > > > > +/* Monitor Received NACK */ > > > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONNACK, 10, 1); > > > > + > > > > +/* Peripheral Identification Register */ > > > > +REG32(FLEXCOMM_I2C_ID, 4092); > > > > +/* Aperture */ > > > > +FIELD(FLEXCOMM_I2C_ID, APERTURE, 0, 8); > > > > +/* Minor revision of module implementation */ > > > > +FIELD(FLEXCOMM_I2C_ID, MINOR_REV, 8, 4); > > > > +/* Major revision of module implementation */ > > > > +FIELD(FLEXCOMM_I2C_ID, MAJOR_REV, 12, 4); > > > > +/* Module identifier for the selected function */ > > > > +FIELD(FLEXCOMM_I2C_ID, ID, 16, 16); > > > > + > > > > > > Are any of the below enums even used? Or for that matter, most of the > > > above fields? > > > > > > If these are just here for documentation, I would prefer English text; > > > it's more dense and easier to read. It's very difficult to tie all this > > > together into a cohesive view of the device registers. > > > > > > > Since this is autogenerated for the full set of the device registers > > there will be fields that are not used either because the emulation is > > incomplete or because they don't have effect for emulation. > > > > I think it is still valuable to have this generated automatically > > instead of doing it by hand. > > > > Would adding options to only generate certain definitions help? As > > long as we are reasonable with the granularity (e.g. register level) I > > think it could trim *most* of the unused generated code without > > becoming too tedious on how to instruct the tool to generate the code. > > However, I expect to still have *some* unused generated code. > > Generally it's frowned upon to have a ton of extra stuff that's not > used. I would think some is ok, like defining bits in registers that > aren't used yet, but I have no idea how all the enums below here > actually tie into anything. I'm guessing these are just bitmasks into > registers, but really, it's a lot easier to read if you have something > like: > > /* > * The I2C Master function enable. When disabled, the Master > * configuration settings are not changed, but the Master function is > * internally reset. > */ > #define FLEXCOMM_I2C_CFG_MSTEN (1 << 4) > > and them have them grouped together with the register they belong to. I > don't know how you would even use these enums. AFAICT, none of them are > used. >
Ah, I see. You are right, it is not useful for 1 bit fields, I'll fix the generator to skip these for bits. The purpose of the enums is for the case where a certain field can have more than two options. To give an example that is used: typedef enum { FLEXCOMM_I2C_STAT_MSTSTATE_IDLE = 0, FLEXCOMM_I2C_STAT_MSTSTATE_RECEIVE_READY = 1, FLEXCOMM_I2C_STAT_MSTSTATE_TRANSMIT_READY = 2, FLEXCOMM_I2C_STAT_MSTSTATE_NACK_ADDRESS = 3, FLEXCOMM_I2C_STAT_MSTSTATE_NACK_DATA = 4, } FLEXCOMM_I2C_STAT_MSTSTATE_Enum; > And the whole idea of this is to make the code more readable. So if > you define these things, you should use them. Look around through the > code of other devices to get a feel of how things are done. > Thanks for the review and sorry for the rough edges, I should have caught the bits enums thing. > -corey > > > > > > > > The .c file itself seems ok. > > > > > > -corey > > > > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Disabled. The I2C Master function is disabled. When disabled, > > > > the Master > > > > + * configuration settings are not changed, but the Master function > > > > is > > > > + * internally reset. > > > > + */ > > > > + FLEXCOMM_I2C_CFG_MSTEN_DISABLED = 0, > > > > + /* Enabled. The I2C Master function is enabled. */ > > > > + FLEXCOMM_I2C_CFG_MSTEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_CFG_MSTEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Disabled. The I2C slave function is disabled. When disabled, > > > > the Slave > > > > + * configuration settings are not changed, but the Slave function > > > > is > > > > + * internally reset. > > > > + */ > > > > + FLEXCOMM_I2C_CFG_SLVEN_DISABLED = 0, > > > > + /* Enabled. The I2C slave function is enabled. */ > > > > + FLEXCOMM_I2C_CFG_SLVEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_CFG_SLVEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Disabled. The I2C Monitor function is disabled. When disabled, > > > > the > > > > + * Monitor function configuration settings are not changed, but > > > > the Monitor > > > > + * function is internally reset. > > > > + */ > > > > + FLEXCOMM_I2C_CFG_MONEN_DISABLED = 0, > > > > + /* Enabled. The I2C Monitor function is enabled. */ > > > > + FLEXCOMM_I2C_CFG_MONEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_CFG_MONEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Disabled. The time-out function is disabled. When disabled, the > > > > time-out > > > > + * function is internally reset. > > > > + */ > > > > + FLEXCOMM_I2C_CFG_TIMEOUTEN_DISABLED = 0, > > > > + /* > > > > + * Enabled. The time-out function is enabled. Both types of > > > > time-out flags > > > > + * will be generated and will cause interrupts if those flags are > > > > enabled. > > > > + * Typically, only one time-out flag will be used in a system. > > > > + */ > > > > + FLEXCOMM_I2C_CFG_TIMEOUTEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_CFG_TIMEOUTEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Disabled. The Monitor function will not perform clock > > > > stretching. > > > > + * Software or DMA may not always be able to read data provided by > > > > the > > > > + * Monitor function before it (the data) is overwritten. This mode > > > > can be > > > > + * used when non-invasive monitoring is critical. > > > > + */ > > > > + FLEXCOMM_I2C_CFG_MONCLKSTR_DISABLED = 0, > > > > + /* > > > > + * Enabled. The Monitor function will perform clock stretching, to > > > > ensure > > > > + * that the software or DMA can read all incoming data supplied by > > > > the > > > > + * Monitor function. > > > > + */ > > > > + FLEXCOMM_I2C_CFG_MONCLKSTR_ENABLED = 1, > > > > +} FLEXCOMM_I2C_CFG_MONCLKSTR_Enum; > > > > + > > > > +typedef enum { > > > > + /* Fast mode Plus enable */ > > > > + FLEXCOMM_I2C_CFG_HSCAPABLE_FAST_MODE_PLUS = 0, > > > > + /* High Speed mode enable */ > > > > + FLEXCOMM_I2C_CFG_HSCAPABLE_HIGH_SPEED = 1, > > > > +} FLEXCOMM_I2C_CFG_HSCAPABLE_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * In progress. Communication is in progress and the Master > > > > function is > > > > + * busy and cannot currently accept a command. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_MSTPENDING_IN_PROGRESS = 0, > > > > + /* > > > > + * Pending. The Master function needs software service or is in > > > > the idle > > > > + * state. If the master is not in the idle state, then the master > > > > is > > > > + * waiting to receive or transmit data, or is waiting for the NACK > > > > bit. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_MSTPENDING_PENDING = 1, > > > > +} FLEXCOMM_I2C_STAT_MSTPENDING_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Idle. The Master function is available to be used for a new > > > > transaction. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_MSTSTATE_IDLE = 0, > > > > + /* > > > > + * Receive ready. Received data is available (in Master Receiver > > > > mode). > > > > + * Address plus Read was previously sent and Acknowledged by a > > > > slave. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_MSTSTATE_RECEIVE_READY = 1, > > > > + /* > > > > + * Transmit ready. Data can be transmitted (in Master Transmitter > > > > mode). > > > > + * Address plus Write was previously sent and Acknowledged by a > > > > slave. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_MSTSTATE_TRANSMIT_READY = 2, > > > > + /* NACK Address. Slave NACKed address. */ > > > > + FLEXCOMM_I2C_STAT_MSTSTATE_NACK_ADDRESS = 3, > > > > + /* NACK Data. Slave NACKed transmitted data. */ > > > > + FLEXCOMM_I2C_STAT_MSTSTATE_NACK_DATA = 4, > > > > +} FLEXCOMM_I2C_STAT_MSTSTATE_Enum; > > > > + > > > > +typedef enum { > > > > + /* No Arbitration Loss has occurred */ > > > > + FLEXCOMM_I2C_STAT_MSTARBLOSS_NO_LOSS = 0, > > > > + /* > > > > + * Arbitration loss. The Master function has experienced an > > > > Arbitration > > > > + * Loss. At this point, the Master function has already stopped > > > > driving the > > > > + * bus and has gone into an idle state. Software can respond by > > > > doing > > > > + * nothing, or by sending a Start (to attempt to gain control of > > > > the bus > > > > + * when the bus next becomes idle). > > > > + */ > > > > + FLEXCOMM_I2C_STAT_MSTARBLOSS_ARBITRATION_LOSS = 1, > > > > +} FLEXCOMM_I2C_STAT_MSTARBLOSS_Enum; > > > > + > > > > +typedef enum { > > > > + /* No Start/Stop Error has occurred. */ > > > > + FLEXCOMM_I2C_STAT_MSTSTSTPERR_NO_ERROR = 0, > > > > + /* > > > > + * The Master function has experienced a Start/Stop Error. A Start > > > > or Stop > > > > + * was detected at a time when Start or Stop is not allowed by the > > > > I2C > > > > + * specification. The Master interface has stopped driving the bus > > > > and gone > > > > + * into an idle state; no action is required. A request for a > > > > Start could > > > > + * be made, or software could attempt to make sure that the bus > > > > has not > > > > + * stalled. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_MSTSTSTPERR_ERROR = 1, > > > > +} FLEXCOMM_I2C_STAT_MSTSTSTPERR_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * In progress. The Slave function does not currently need software > > > > + * service. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_SLVPENDING_IN_PROGRESS = 0, > > > > + /* > > > > + * Pending. The Slave function needs software service. Information > > > > about > > > > + * what is needed is in the Slave state field (SLVSTATE). > > > > + */ > > > > + FLEXCOMM_I2C_STAT_SLVPENDING_PENDING = 1, > > > > +} FLEXCOMM_I2C_STAT_SLVPENDING_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Slave address. Address plus R/W received. At least one of the 4 > > > > slave > > > > + * addresses has been matched by hardware. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_ADDRESS = 0, > > > > + /* Slave receive. Received data is available (in Slave Receiver > > > > mode). */ > > > > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_RECEIVE = 1, > > > > + /* Slave transmit. Data can be transmitted (in Slave Transmitter > > > > mode). */ > > > > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_TRANSMIT = 2, > > > > +} FLEXCOMM_I2C_STAT_SLVSTATE_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Stretching. The slave function is currently stretching the I2C > > > > bus > > > > + * clock. Deep-Sleepmode cannot be entered at this time. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_SLVNOTSTR_STRETCHING = 0, > > > > + /* > > > > + * Not stretching. The slave function is not currently stretching > > > > the I2C > > > > + * bus clock. Deep-sleep mode can be entered at this time. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_SLVNOTSTR_NOT_STRETCHING = 1, > > > > +} FLEXCOMM_I2C_STAT_SLVNOTSTR_Enum; > > > > + > > > > +typedef enum { > > > > + /* Address 0. Slave address 0 was matched. */ > > > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS0 = 0, > > > > + /* Address 1. Slave address 1 was matched. */ > > > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS1 = 1, > > > > + /* Address 2. Slave address 2 was matched. */ > > > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS2 = 2, > > > > + /* Address 3. Slave address 3 was matched. */ > > > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS3 = 3, > > > > +} FLEXCOMM_I2C_STAT_SLVIDX_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not selected. The Slave function is not currently selected. */ > > > > + FLEXCOMM_I2C_STAT_SLVSEL_NOT_SELECTED = 0, > > > > + /* Selected. The Slave function is currently selected. */ > > > > + FLEXCOMM_I2C_STAT_SLVSEL_SELECTED = 1, > > > > +} FLEXCOMM_I2C_STAT_SLVSEL_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Not deselected. The Slave function has not become deselected. > > > > This does > > > > + * not mean that the Slave is currently selected. That information > > > > is in > > > > + * the SLVSEL flag. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_SLVDESEL_NOT_DESELECTED = 0, > > > > + /* > > > > + * Deselected. The Slave function has become deselected. This is > > > > + * specifically caused by the SLVSEL flag changing from 1 to 0. > > > > See SLVSEL > > > > + * for details about when that event occurs. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_SLVDESEL_DESELECTED = 1, > > > > +} FLEXCOMM_I2C_STAT_SLVDESEL_Enum; > > > > + > > > > +typedef enum { > > > > + /* No data. The Monitor function does not currently have data > > > > available. */ > > > > + FLEXCOMM_I2C_STAT_MONRDY_NO_DATA = 0, > > > > + /* Data waiting. The Monitor function has data waiting to be read. > > > > */ > > > > + FLEXCOMM_I2C_STAT_MONRDY_DATA_WAITING = 1, > > > > +} FLEXCOMM_I2C_STAT_MONRDY_Enum; > > > > + > > > > +typedef enum { > > > > + /* No overrun. Monitor data has not overrun. */ > > > > + FLEXCOMM_I2C_STAT_MONOV_NO_OVERRUN = 0, > > > > + /* > > > > + * Overrun. A Monitor data overrun has occurred. An overrun can > > > > only happen > > > > + * when Monitor clock stretching not enabled via the > > > > CFG[MONCLKSTR] bit. > > > > + * Writing 1 to MONOV bit clears the MONOV flag. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_MONOV_OVERRUN = 1, > > > > +} FLEXCOMM_I2C_STAT_MONOV_Enum; > > > > + > > > > +typedef enum { > > > > + /* Inactive. The Monitor function considers the I2C bus to be > > > > inactive. */ > > > > + FLEXCOMM_I2C_STAT_MONACTIVE_INACTIVE = 0, > > > > + /* Active. The Monitor function considers the I2C bus to be > > > > active. */ > > > > + FLEXCOMM_I2C_STAT_MONACTIVE_ACTIVE = 1, > > > > +} FLEXCOMM_I2C_STAT_MONACTIVE_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Not idle. The I2C bus is not idle, or MONIDLE flag has been > > > > cleared by > > > > + * software. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_MONIDLE_NOT_IDLE = 0, > > > > + /* > > > > + * Idle. The I2C bus has gone idle at least once, since the last > > > > time > > > > + * MONIDLE flag was cleared by software. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_MONIDLE_IDLE = 1, > > > > +} FLEXCOMM_I2C_STAT_MONIDLE_Enum; > > > > + > > > > +typedef enum { > > > > + /* No time-out. I2C bus events have not caused a time-out. */ > > > > + FLEXCOMM_I2C_STAT_EVENTTIMEOUT_NO_TIMEOUT = 0, > > > > + /* > > > > + * Event time-out. The time between I2C bus events has been longer > > > > than the > > > > + * time specified by the TIMEOUT register. > > > > + */ > > > > + FLEXCOMM_I2C_STAT_EVENTTIMEOUT_EVEN_TIMEOUT = 1, > > > > +} FLEXCOMM_I2C_STAT_EVENTTIMEOUT_Enum; > > > > + > > > > +typedef enum { > > > > + /* No time-out. SCL low time has not caused a time-out. */ > > > > + FLEXCOMM_I2C_STAT_SCLTIMEOUT_NO_TIMEOUT = 0, > > > > + /* Time-out. SCL low time has caused a time-out. */ > > > > + FLEXCOMM_I2C_STAT_SCLTIMEOUT_TIMEOUT = 1, > > > > +} FLEXCOMM_I2C_STAT_SCLTIMEOUT_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The MstPending interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_DISABLED = 0, > > > > + /* Enabled. The MstPending interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The MstArbLoss interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_DISABLED = 0, > > > > + /* Enabled. The MstArbLoss interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The MstStStpErr interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_DISABLED = 0, > > > > + /* Enabled. The MstStStpErr interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The SlvPending interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_DISABLED = 0, > > > > + /* Enabled. The SlvPending interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The SlvNotStr interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_DISABLED = 0, > > > > + /* Enabled. The SlvNotStr interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The SlvDeSel interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_SLVDESELEN_DISABLED = 0, > > > > + /* Enabled. The SlvDeSel interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_SLVDESELEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_SLVDESELEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The MonRdy interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MONRDYEN_DISABLED = 0, > > > > + /* Enabled. The MonRdy interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MONRDYEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_MONRDYEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The MonOv interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MONOVEN_DISABLED = 0, > > > > + /* Enabled. The MonOv interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MONOVEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_MONOVEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The MonIdle interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MONIDLEEN_DISABLED = 0, > > > > + /* Enabled. The MonIdle interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_MONIDLEEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_MONIDLEEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The Event time-out interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_DISABLED = 0, > > > > + /* Enabled. The Event time-out interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. The SCL time-out interrupt is disabled. */ > > > > + FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_DISABLED = 0, > > > > + /* Enabled. The SCL time-out interrupt is enabled. */ > > > > + FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_ENABLED = 1, > > > > +} FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_CLEAR_MSTPENDING = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_CLEAR_MSTARBLOSS = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_CLEAR_MSTSTSTPERR = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_CLEAR_SLVPENDING = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_CLEAR_SLVNOTSTR = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_CLEAR_SLVDESEL = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_MONRDYCLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_MONRDYCLR_CLEAR_MONRDY = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_MONRDYCLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_MONOVCLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_MONOVCLR_CLEAR_MONOV = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_MONOVCLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_MONIDLECLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_MONIDLECLR_CLEAR_MONIDLE = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_MONIDLECLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_CLEAR_EVENTTIMEOUT = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect on interrupt */ > > > > + FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_NO_EFFECT = 0, > > > > + /* Clears the interrupt bit in INTENSET register */ > > > > + FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_CLEAR_SCLTIMEOUT = 1, > > > > +} FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_Enum; > > > > + > > > > +typedef enum { > > > > + /* A time-out will occur after 16 counts of the I2C function > > > > clock. */ > > > > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT16 = 0, > > > > + /* A time-out will occur after 32 counts of the I2C function > > > > clock. */ > > > > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT32 = 1, > > > > + /* A time-out will occur after 65,536 counts of the I2C function > > > > clock. */ > > > > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT65K = 4095, > > > > +} FLEXCOMM_I2C_TIMEOUT_TO_Enum; > > > > + > > > > +typedef enum { > > > > + /* FCLK is used directly by the I2C. */ > > > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKUNDIVIDED = 0, > > > > + /* FCLK is divided by 2 before being used by the I2C. */ > > > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV2 = 1, > > > > + /* FCLK is divided by 3 before being used by the I2C. */ > > > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV3 = 2, > > > > + /* FCLK is divided by 65,536 before being used by the I2C. */ > > > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV65K = 65535, > > > > +} FLEXCOMM_I2C_CLKDIV_DIVVAL_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_MSTPENDING_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_SLVPENDING_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_SLVDESEL_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_MONRDY_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_MONOV_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_MONIDLE_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_Enum; > > > > + > > > > +typedef enum { > > > > + /* Not active */ > > > > + FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISNOTACTIVE = 0, > > > > + /* Active */ > > > > + FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISACTIVE = 1, > > > > +} FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect */ > > > > + FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_NO_EFFECT = 0, > > > > + /* > > > > + * Continue. Informs the Master function to continue to the next > > > > operation. > > > > + * This action must done after writing transmit data, reading > > > > received > > > > + * data, or any other housekeeping related to the next bus > > > > operation. > > > > + */ > > > > + FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_CONTINUE = 1, > > > > +} FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect */ > > > > + FLEXCOMM_I2C_MSTCTL_MSTSTART_NO_EFFECT = 0, > > > > + /* > > > > + * Start. A Start will be generated on the I2C bus at the next > > > > allowed > > > > + * time. > > > > + */ > > > > + FLEXCOMM_I2C_MSTCTL_MSTSTART_START = 1, > > > > +} FLEXCOMM_I2C_MSTCTL_MSTSTART_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect */ > > > > + FLEXCOMM_I2C_MSTCTL_MSTSTOP_NO_EFFECT = 0, > > > > + /* > > > > + * Stop. A Stop will be generated on the I2C bus at the next > > > > allowed time, > > > > + * preceded by a NACK to the slave if the master is receiving data > > > > from the > > > > + * slave (in Master Receiver mode). > > > > + */ > > > > + FLEXCOMM_I2C_MSTCTL_MSTSTOP_STOP = 1, > > > > +} FLEXCOMM_I2C_MSTCTL_MSTSTOP_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disable. No DMA requests are generated for master operation. */ > > > > + FLEXCOMM_I2C_MSTCTL_MSTDMA_DISABLED = 0, > > > > + /* > > > > + * Enable. A DMA request is generated for I2C master data > > > > operations. When > > > > + * this I2C master is generating Acknowledge bits in Master > > > > Receiver mode, > > > > + * the acknowledge is generated automatically. > > > > + */ > > > > + FLEXCOMM_I2C_MSTCTL_MSTDMA_ENABLED = 1, > > > > +} FLEXCOMM_I2C_MSTCTL_MSTDMA_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * 2 clocks. Minimum SCL low time is 2 clocks of the I2C clock > > > > pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_2CLOCKS = 0, > > > > + /* > > > > + * 3 clocks. Minimum SCL low time is 3 clocks of the I2C clock > > > > pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_3CLOCKS = 1, > > > > + /* > > > > + * 4 clocks. Minimum SCL low time is 4 clocks of the I2C clock > > > > pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_4CLOCKS = 2, > > > > + /* > > > > + * 5 clocks. Minimum SCL low time is 5 clocks of the I2C clock > > > > pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_5CLOCKS = 3, > > > > + /* > > > > + * 6 clocks. Minimum SCL low time is 6 clocks of the I2C clock > > > > pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_6CLOCKS = 4, > > > > + /* > > > > + * 7 clocks. Minimum SCL low time is 7 clocks of the I2C clock > > > > pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_7CLOCKS = 5, > > > > + /* > > > > + * 8 clocks. Minimum SCL low time is 8 clocks of the I2C clock > > > > pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_8CLOCKS = 6, > > > > + /* > > > > + * 9 clocks. Minimum SCL low time is 9 clocks of the I2C clock > > > > pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_9CLOCKS = 7, > > > > +} FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * 2 clocks. Minimum SCL high time is 2 clocks of the I2C clock > > > > + * pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_2CLOCKS = 0, > > > > + /* > > > > + * 3 clocks. Minimum SCL high time is 3 clocks of the I2C clock > > > > pre-divider > > > > + * . > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_3CLOCKS = 1, > > > > + /* > > > > + * 4 clocks. Minimum SCL high time is 4 clocks of the I2C clock > > > > + * pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_4CLOCKS = 2, > > > > + /* > > > > + * 5 clocks. Minimum SCL high time is 5 clocks of the I2C clock > > > > + * pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_5CLOCKS = 3, > > > > + /* > > > > + * 6 clocks. Minimum SCL high time is 6 clocks of the I2C clock > > > > + * pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_6CLOCKS = 4, > > > > + /* > > > > + * 7 clocks. Minimum SCL high time is 7 clocks of the I2C clock > > > > + * pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_7CLOCKS = 5, > > > > + /* > > > > + * 8 clocks. Minimum SCL high time is 8 clocks of the I2C clock > > > > + * pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_8CLOCKS = 6, > > > > + /* > > > > + * 9 clocks. Minimum SCL high time is 9 clocks of the I2C clock > > > > + * pre-divider. > > > > + */ > > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_9CLOCKS = 7, > > > > +} FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect */ > > > > + FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_NO_EFFECT = 0, > > > > + /* > > > > + * Continue. Informs the Slave function to continue to the next > > > > operation, > > > > + * by clearing the STAT[SLVPENDING] flag. This must be done after > > > > writing > > > > + * transmit data, reading received data, or any other housekeeping > > > > related > > > > + * to the next bus operation. Automatic Operation has different > > > > + * requirements. SLVCONTINUE should not be set unless SLVPENDING = > > > > 1. > > > > + */ > > > > + FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_CONTINUE = 1, > > > > +} FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_Enum; > > > > + > > > > +typedef enum { > > > > + /* No effect */ > > > > + FLEXCOMM_I2C_SLVCTL_SLVNACK_NO_EFFECT = 0, > > > > + /* > > > > + * NACK. Causes the Slave function to NACK the master when the > > > > slave is > > > > + * receiving data from the master (in Slave Receiver mode). > > > > + */ > > > > + FLEXCOMM_I2C_SLVCTL_SLVNACK_NACK = 1, > > > > +} FLEXCOMM_I2C_SLVCTL_SLVNACK_Enum; > > > > + > > > > +typedef enum { > > > > + /* Disabled. No DMA requests are issued for Slave mode operation. > > > > */ > > > > + FLEXCOMM_I2C_SLVCTL_SLVDMA_DISABLED = 0, > > > > + /* > > > > + * Enabled. DMA requests are issued for I2C slave data > > > > transmission and > > > > + * reception. > > > > + */ > > > > + FLEXCOMM_I2C_SLVCTL_SLVDMA_ENABLED = 1, > > > > +} FLEXCOMM_I2C_SLVCTL_SLVDMA_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Normal, non-automatic operation. If AUTONACK = 0, then a > > > > SlvPending > > > > + * interrupt is generated when a matching address is received. If > > > > AUTONACK > > > > + * = 1, then received addresses are NACKed (ignored). > > > > + */ > > > > + FLEXCOMM_I2C_SLVCTL_AUTOACK_NORMAL = 0, > > > > + /* > > > > + * A header with matching SLVADR0 and matching direction as set by > > > > + * AUTOMATCHREAD will be ACKed immediately, allowing the master to > > > > move on > > > > + * to the data bytes. If the address matches SLVADR0, but the > > > > direction > > > > + * does not match AUTOMATCHREAD, then the behavior will depend on > > > > the > > > > + * SLVADR0[AUTONACK] bit: if AUTONACK is set, then it will be > > > > Nacked; if > > > > + * AUTONACK is clear, then a SlvPending interrupt is generated. > > > > + */ > > > > + FLEXCOMM_I2C_SLVCTL_AUTOACK_AUTOMATIC_ACK = 1, > > > > +} FLEXCOMM_I2C_SLVCTL_AUTOACK_Enum; > > > > + > > > > +typedef enum { > > > > + /* In Automatic Mode, the expected next operation is an I2C write. > > > > */ > > > > + FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_WRITE = 0, > > > > + /* In Automatic Mode, the expected next operation is an I2C read. > > > > */ > > > > + FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_READ = 1, > > > > +} FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_Enum; > > > > + > > > > +typedef enum { > > > > + /* Enabled. Slave Address n is enabled. */ > > > > + FLEXCOMM_I2C_SLVADR0_SADISABLE_ENABLED = 0, > > > > + /* Ignored. Slave Address n is ignored. */ > > > > + FLEXCOMM_I2C_SLVADR0_SADISABLE_DISABLED = 1, > > > > +} FLEXCOMM_I2C_SLVADR0_SADISABLE_Enum; > > > > + > > > > +typedef enum { > > > > + /* Normal operation, matching I2C addresses are not ignored. */ > > > > + FLEXCOMM_I2C_SLVADR0_AUTONACK_NORMAL = 0, > > > > + /* > > > > + * Automatic-only mode. All incoming addresses are ignored > > > > (NACKed), unless > > > > + * AUTOACK is set, and the address matches SLVADRn, and > > > > AUTOMATCHREAD > > > > + * matches the direction. > > > > + */ > > > > + FLEXCOMM_I2C_SLVADR0_AUTONACK_AUTOMATIC = 1, > > > > +} FLEXCOMM_I2C_SLVADR0_AUTONACK_Enum; > > > > + > > > > +typedef enum { > > > > + /* Enabled. Slave Address n is enabled. */ > > > > + FLEXCOMM_I2C_SLVADR1_SADISABLE_ENABLED = 0, > > > > + /* Ignored. Slave Address n is ignored. */ > > > > + FLEXCOMM_I2C_SLVADR1_SADISABLE_DISABLED = 1, > > > > +} FLEXCOMM_I2C_SLVADR1_SADISABLE_Enum; > > > > + > > > > +typedef enum { > > > > + /* Normal operation, matching I2C addresses are not ignored. */ > > > > + FLEXCOMM_I2C_SLVADR1_AUTONACK_NORMAL = 0, > > > > + /* > > > > + * Automatic-only mode. All incoming addresses are ignored > > > > (NACKed), unless > > > > + * AUTOACK is set, and the address matches SLVADRn, and > > > > AUTOMATCHREAD > > > > + * matches the direction. > > > > + */ > > > > + FLEXCOMM_I2C_SLVADR1_AUTONACK_AUTOMATIC = 1, > > > > +} FLEXCOMM_I2C_SLVADR1_AUTONACK_Enum; > > > > + > > > > +typedef enum { > > > > + /* Enabled. Slave Address n is enabled. */ > > > > + FLEXCOMM_I2C_SLVADR2_SADISABLE_ENABLED = 0, > > > > + /* Ignored. Slave Address n is ignored. */ > > > > + FLEXCOMM_I2C_SLVADR2_SADISABLE_DISABLED = 1, > > > > +} FLEXCOMM_I2C_SLVADR2_SADISABLE_Enum; > > > > + > > > > +typedef enum { > > > > + /* Normal operation, matching I2C addresses are not ignored. */ > > > > + FLEXCOMM_I2C_SLVADR2_AUTONACK_NORMAL = 0, > > > > + /* > > > > + * Automatic-only mode. All incoming addresses are ignored > > > > (NACKed), unless > > > > + * AUTOACK is set, and the address matches SLVADRn, and > > > > AUTOMATCHREAD > > > > + * matches the direction. > > > > + */ > > > > + FLEXCOMM_I2C_SLVADR2_AUTONACK_AUTOMATIC = 1, > > > > +} FLEXCOMM_I2C_SLVADR2_AUTONACK_Enum; > > > > + > > > > +typedef enum { > > > > + /* Enabled. Slave Address n is enabled. */ > > > > + FLEXCOMM_I2C_SLVADR3_SADISABLE_ENABLED = 0, > > > > + /* Ignored. Slave Address n is ignored. */ > > > > + FLEXCOMM_I2C_SLVADR3_SADISABLE_DISABLED = 1, > > > > +} FLEXCOMM_I2C_SLVADR3_SADISABLE_Enum; > > > > + > > > > +typedef enum { > > > > + /* Normal operation, matching I2C addresses are not ignored. */ > > > > + FLEXCOMM_I2C_SLVADR3_AUTONACK_NORMAL = 0, > > > > + /* > > > > + * Automatic-only mode. All incoming addresses are ignored > > > > (NACKed), unless > > > > + * AUTOACK is set, and the address matches SLVADRn, and > > > > AUTOMATCHREAD > > > > + * matches the direction. > > > > + */ > > > > + FLEXCOMM_I2C_SLVADR3_AUTONACK_AUTOMATIC = 1, > > > > +} FLEXCOMM_I2C_SLVADR3_AUTONACK_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Mask. The SLVQUAL0 field is used as a logical mask for matching > > > > address > > > > + * 0. > > > > + */ > > > > + FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_MASK = 0, > > > > + /* > > > > + * Extend. The SLVQUAL0 field is used to extend address 0 matching > > > > in a > > > > + * range of addresses. > > > > + */ > > > > + FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_EXTEND = 1, > > > > +} FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * No start detected. The Monitor function has not detected a > > > > Start event > > > > + * on the I2C bus. > > > > + */ > > > > + FLEXCOMM_I2C_MONRXDAT_MONSTART_NO_START_DETECTED = 0, > > > > + /* > > > > + * Start detected. The Monitor function has detected a Start event > > > > on the > > > > + * I2C bus. > > > > + */ > > > > + FLEXCOMM_I2C_MONRXDAT_MONSTART_START_DETECTED = 1, > > > > +} FLEXCOMM_I2C_MONRXDAT_MONSTART_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * No repeated start detected. The Monitor function has not > > > > detected a > > > > + * Repeated Start event on the I2C bus. > > > > + */ > > > > + FLEXCOMM_I2C_MONRXDAT_MONRESTART_NOT_DETECTED = 0, > > > > + /* > > > > + * Repeated start detected. The Monitor function has detected a > > > > Repeated > > > > + * Start event on the I2C bus. > > > > + */ > > > > + FLEXCOMM_I2C_MONRXDAT_MONRESTART_DETECTED = 1, > > > > +} FLEXCOMM_I2C_MONRXDAT_MONRESTART_Enum; > > > > + > > > > +typedef enum { > > > > + /* > > > > + * Acknowledged. The data currently being provided by the Monitor > > > > function > > > > + * was acknowledged by at least one master or slave receiver. > > > > + */ > > > > + FLEXCOMM_I2C_MONRXDAT_MONNACK_ACKNOWLEDGED = 0, > > > > + /* > > > > + * Not acknowledged. The data currently being provided by the > > > > Monitor > > > > + * function was not acknowledged by any receiver. > > > > + */ > > > > + FLEXCOMM_I2C_MONRXDAT_MONNACK_NOT_ACKNOWLEDGED = 1, > > > > +} FLEXCOMM_I2C_MONRXDAT_MONNACK_Enum; > > > > + > > > > + > > > > +#define FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(_name) \ > > > > + struct RegisterAccessInfo _name[FLEXCOMM_I2C_REGS_NO] = { \ > > > > + [0 ... FLEXCOMM_I2C_REGS_NO - 1] = { \ > > > > + .name = "", \ > > > > + .addr = -1, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_CFG] = { \ > > > > + .name = "CFG", \ > > > > + .addr = 0x800, \ > > > > + .ro = 0xFFFFFFC0, \ > > > > + .reset = 0x0, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_STAT] = { \ > > > > + .name = "STAT", \ > > > > + .addr = 0x804, \ > > > > + .ro = 0xFCF57FAF, \ > > > > + .reset = 0x801, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_INTENSET] = { \ > > > > + .name = "INTENSET", \ > > > > + .addr = 0x808, \ > > > > + .ro = 0xFCF476AE, \ > > > > + .reset = 0x0, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_INTENCLR] = { \ > > > > + .name = "INTENCLR", \ > > > > + .addr = 0x80C, \ > > > > + .ro = 0xFCF476AE, \ > > > > + .reset = 0x0, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_TIMEOUT] = { \ > > > > + .name = "TIMEOUT", \ > > > > + .addr = 0x810, \ > > > > + .ro = 0xFFFF0000, \ > > > > + .reset = 0xFFFF, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_CLKDIV] = { \ > > > > + .name = "CLKDIV", \ > > > > + .addr = 0x814, \ > > > > + .ro = 0xFFFF0000, \ > > > > + .reset = 0x0, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_INTSTAT] = { \ > > > > + .name = "INTSTAT", \ > > > > + .addr = 0x818, \ > > > > + .ro = 0xFFFFFFFF, \ > > > > + .reset = 0x801, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_MSTCTL] = { \ > > > > + .name = "MSTCTL", \ > > > > + .addr = 0x820, \ > > > > + .ro = 0xFFFFFFF0, \ > > > > + .reset = 0x0, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_MSTTIME] = { \ > > > > + .name = "MSTTIME", \ > > > > + .addr = 0x824, \ > > > > + .ro = 0xFFFFFF88, \ > > > > + .reset = 0x77, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_MSTDAT] = { \ > > > > + .name = "MSTDAT", \ > > > > + .addr = 0x828, \ > > > > + .ro = 0xFFFFFF00, \ > > > > + .reset = 0x0, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_SLVCTL] = { \ > > > > + .name = "SLVCTL", \ > > > > + .addr = 0x840, \ > > > > + .ro = 0xFFFFFCF4, \ > > > > + .reset = 0x0, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_SLVDAT] = { \ > > > > + .name = "SLVDAT", \ > > > > + .addr = 0x844, \ > > > > + .ro = 0xFFFFFF00, \ > > > > + .reset = 0x0, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_SLVADR0] = { \ > > > > + .name = "SLVADR0", \ > > > > + .addr = 0x848, \ > > > > + .ro = 0xFFFF7F00, \ > > > > + .reset = 0x1, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_SLVADR1] = { \ > > > > + .name = "SLVADR1", \ > > > > + .addr = 0x84C, \ > > > > + .ro = 0xFFFF7F00, \ > > > > + .reset = 0x1, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_SLVADR2] = { \ > > > > + .name = "SLVADR2", \ > > > > + .addr = 0x850, \ > > > > + .ro = 0xFFFF7F00, \ > > > > + .reset = 0x1, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_SLVADR3] = { \ > > > > + .name = "SLVADR3", \ > > > > + .addr = 0x854, \ > > > > + .ro = 0xFFFF7F00, \ > > > > + .reset = 0x1, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_SLVQUAL0] = { \ > > > > + .name = "SLVQUAL0", \ > > > > + .addr = 0x858, \ > > > > + .ro = 0xFFFFFF00, \ > > > > + .reset = 0x0, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_MONRXDAT] = { \ > > > > + .name = "MONRXDAT", \ > > > > + .addr = 0x880, \ > > > > + .ro = 0xFFFFFFFF, \ > > > > + .reset = 0x0, \ > > > > + }, \ > > > > + [R_FLEXCOMM_I2C_ID] = { \ > > > > + .name = "ID", \ > > > > + .addr = 0xFFC, \ > > > > + .ro = 0xFFFFFFFF, \ > > > > + .reset = 0xE0301300, \ > > > > + }, \ > > > > + } > > > > diff --git a/include/hw/i2c/flexcomm_i2c.h > > > > b/include/hw/i2c/flexcomm_i2c.h > > > > new file mode 100644 > > > > index 0000000000..7b27e333d7 > > > > --- /dev/null > > > > +++ b/include/hw/i2c/flexcomm_i2c.h > > > > @@ -0,0 +1,40 @@ > > > > +/* > > > > + * QEMU model for NXP's FLEXCOMM I2C > > > > + * > > > > + * Copyright (c) 2024 Google LLC > > > > + * > > > > + * SPDX-License-Identifier: GPL-2.0-or-later > > > > + * > > > > + * This work is licensed under the terms of the GNU GPL, version 2 or > > > > later. > > > > + * See the COPYING file in the top-level directory. > > > > + */ > > > > + > > > > +#ifndef HW_FLEXCOMM_I2C_H > > > > +#define HW_FLEXCOMM_I2C_H > > > > + > > > > +#include "hw/i2c/i2c.h" > > > > +#include "hw/misc/flexcomm_function.h" > > > > + > > > > +#define TYPE_FLEXCOMM_I2C "flexcomm-i2c" > > > > +OBJECT_DECLARE_TYPE(FlexcommI2cState, FlexcommI2cClass, FLEXCOMM_I2C); > > > > + > > > > +struct FlexcommI2cState { > > > > + FlexcommFunction parent_obj; > > > > + > > > > + I2CBus *bus; > > > > +}; > > > > + > > > > +struct FlexcommI2cClass { > > > > + FlexcommFunctionClass parent_obj; > > > > + > > > > + FlexcommFunctionSelect select; > > > > +}; > > > > + > > > > +#define MSTSTATE_IDLE 0 > > > > +#define MSTSTATE_RXRDY 1 > > > > +#define MSTSTATE_TXRDY 2 > > > > +#define MSTSTATE_NAKADR 3 > > > > +#define MSTSTATE_NAKDAT 4 > > > > + > > > > + > > > > +#endif /* HW_FLEXCOMM_I2C_H */ > > > > diff --git a/include/hw/misc/flexcomm.h b/include/hw/misc/flexcomm.h > > > > index 679b7ea64d..c9f1cd3890 100644 > > > > --- a/include/hw/misc/flexcomm.h > > > > +++ b/include/hw/misc/flexcomm.h > > > > @@ -16,6 +16,7 @@ > > > > #include "hw/arm/svd/flexcomm.h" > > > > #include "qemu/fifo32.h" > > > > #include "hw/char/flexcomm_usart.h" > > > > +#include "hw/i2c/flexcomm_i2c.h" > > > > > > > > #define FLEXCOMM_FUNC_USART 0 > > > > #define FLEXCOMM_FUNC_SPI 1 > > > > @@ -48,6 +49,7 @@ struct FlexcommState { > > > > Fifo32 rx_fifo; > > > > Fifo32 tx_fifo; > > > > FlexcommUsartState usart; > > > > + FlexcommI2cState i2c; > > > > }; > > > > > > > > #endif /* HW_FLEXCOMM_H */ > > > > diff --git a/hw/i2c/flexcomm_i2c.c b/hw/i2c/flexcomm_i2c.c > > > > new file mode 100644 > > > > index 0000000000..e5341ec241 > > > > --- /dev/null > > > > +++ b/hw/i2c/flexcomm_i2c.c > > > > @@ -0,0 +1,250 @@ > > > > +/* > > > > + * QEMU model for NXP's FLEXCOMM I2C > > > > + * > > > > + * Copyright (c) 2024 Google LLC > > > > + * > > > > + * SPDX-License-Identifier: GPL-2.0-or-later > > > > + * > > > > + * This work is licensed under the terms of the GNU GPL, version 2 or > > > > later. > > > > + * See the COPYING file in the top-level directory. > > > > + */ > > > > + > > > > +#include "qemu/osdep.h" > > > > +#include "qemu/cutils.h" > > > > +#include "hw/irq.h" > > > > +#include "hw/qdev-properties.h" > > > > +#include "qemu/log.h" > > > > +#include "qemu/module.h" > > > > +#include "exec/address-spaces.h" > > > > +#include "qapi/error.h" > > > > +#include "trace.h" > > > > +#include "hw/i2c/flexcomm_i2c.h" > > > > +#include "hw/arm/svd/flexcomm_i2c.h" > > > > + > > > > +#define REG(s, reg) (s->regs[R_FLEXCOMM_I2C_##reg]) > > > > +#define RF_WR(s, reg, field, val) \ > > > > + ARRAY_FIELD_DP32(s->regs, FLEXCOMM_I2C_##reg, field, val) > > > > +#define RF_RD(s, reg, field) \ > > > > + ARRAY_FIELD_EX32(s->regs, FLEXCOMM_I2C_##reg, field) > > > > + > > > > +static FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(reg_info); > > > > + > > > > +static void flexcomm_i2c_reset(FlexcommFunction *f) > > > > +{ > > > > + for (int i = 0; i < FLEXCOMM_I2C_REGS_NO; i++) { > > > > + hwaddr addr = reg_info[i].addr; > > > > + > > > > + if (addr != -1) { > > > > + struct RegisterInfo ri = { > > > > + .data = &f->regs[addr / 4], > > > > + .data_size = 4, > > > > + .access = ®_info[i], > > > > + }; > > > > + > > > > + register_reset(&ri); > > > > + } > > > > + } > > > > +} > > > > + > > > > +static void flexcomm_i2c_irq_update(FlexcommFunction *f) > > > > +{ > > > > + bool enabled = RF_RD(f, CFG, MSTEN); > > > > + bool irq, per_irqs; > > > > + > > > > + REG(f, INTSTAT) = REG(f, STAT) & REG(f, INTENSET); > > > > + per_irqs = REG(f, INTSTAT) != 0; > > > > + > > > > + irq = enabled && per_irqs; > > > > + > > > > + trace_flexcomm_i2c_irq(DEVICE(f)->id, irq, per_irqs, enabled); > > > > + flexcomm_set_irq(f, irq); > > > > +} > > > > + > > > > +static MemTxResult flexcomm_i2c_reg_read(void *opaque, hwaddr addr, > > > > + uint64_t *data, unsigned size, > > > > + MemTxAttrs attrs) > > > > +{ > > > > + FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque); > > > > + MemTxResult ret = MEMTX_OK; > > > > + const struct RegisterAccessInfo *rai = ®_info[addr / 4]; > > > > + > > > > + if (size != 4) { > > > > + ret = MEMTX_ERROR; > > > > + goto out; > > > > + } > > > > + > > > > + *data = f->regs[addr / 4]; > > > > + > > > > + flexcomm_i2c_irq_update(f); > > > > + > > > > +out: > > > > + trace_flexcomm_i2c_reg_read(DEVICE(f)->id, rai->name, addr, *data); > > > > + return ret; > > > > +} > > > > + > > > > +static MemTxResult flexcomm_i2c_reg_write(void *opaque, hwaddr addr, > > > > + uint64_t value, unsigned > > > > size, > > > > + MemTxAttrs attrs) > > > > +{ > > > > + FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque); > > > > + FlexcommI2cState *s = FLEXCOMM_I2C(opaque); > > > > + const struct RegisterAccessInfo *rai = ®_info[addr / 4]; > > > > + struct RegisterInfo ri = { > > > > + .data = &f->regs[addr / 4], > > > > + .data_size = 4, > > > > + .access = rai, > > > > + }; > > > > + > > > > + trace_flexcomm_i2c_reg_write(DEVICE(f)->id, rai->name, addr, > > > > value); > > > > + > > > > + if (size != 4) { > > > > + return MEMTX_ERROR; > > > > + } > > > > + > > > > + switch (addr) { > > > > + case A_FLEXCOMM_I2C_CFG: > > > > + { > > > > + register_write(&ri, value, ~0, NULL, false); > > > > + if (RF_RD(f, CFG, SLVEN)) { > > > > + qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported"); > > > > + } > > > > + if (RF_RD(f, CFG, MONEN)) { > > > > + qemu_log_mask(LOG_GUEST_ERROR, "I2C monitoring not > > > > supported"); > > > > + } > > > > + break; > > > > + } > > > > + case A_FLEXCOMM_I2C_INTENCLR: > > > > + { > > > > + REG(f, INTENSET) &= ~value; > > > > + break; > > > > + } > > > > + case A_FLEXCOMM_I2C_TIMEOUT: > > > > + { > > > > + register_write(&ri, value, ~0, NULL, false); > > > > + /* The bottom 4 bits are hard-wired to 0xF */ > > > > + RF_WR(f, TIMEOUT, TOMIN, 0xf); > > > > + break; > > > > + } > > > > + case A_FLEXCOMM_I2C_MSTCTL: > > > > + { > > > > + register_write(&ri, value, ~0, NULL, false); > > > > + if (RF_RD(f, MSTCTL, MSTSTART)) { > > > > + uint8_t i2c_addr = RF_RD(f, MSTDAT, DATA); > > > > + bool recv = i2c_addr & 1; > > > > + > > > > + trace_flexcomm_i2c_start(DEVICE(s)->id, i2c_addr, recv); > > > > + if (i2c_start_transfer(s->bus, i2c_addr, recv)) { > > > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKADR); > > > > + trace_flexcomm_i2c_nak(DEVICE(s)->id); > > > > + } else { > > > > + if (recv) { > > > > + uint8_t data = i2c_recv(s->bus); > > > > + > > > > + RF_WR(f, MSTDAT, DATA, data); > > > > + trace_flexcomm_i2c_rx(DEVICE(s)->id, data); > > > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_RXRDY); > > > > + } else { > > > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_TXRDY); > > > > + } > > > > + } > > > > + } > > > > + if (RF_RD(f, MSTCTL, MSTSTOP)) { > > > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_IDLE); > > > > + i2c_end_transfer(s->bus); > > > > + } > > > > + if (RF_RD(f, MSTCTL, MSTCONTINUE)) { > > > > + if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_TXRDY) { > > > > + uint8_t data = RF_RD(f, MSTDAT, DATA); > > > > + > > > > + trace_flexcomm_i2c_tx(DEVICE(s)->id, data); > > > > + if (i2c_send(s->bus, data)) { > > > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKDAT); > > > > + } > > > > + } else if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_RXRDY) { > > > > + uint8_t data = i2c_recv(s->bus); > > > > + > > > > + RF_WR(f, MSTDAT, DATA, data); > > > > + trace_flexcomm_i2c_rx(DEVICE(s)->id, data); > > > > + } > > > > + } > > > > + break; > > > > + } > > > > + case A_FLEXCOMM_I2C_STAT: > > > > + { > > > > + /* write 1 to clear bits */ > > > > + REG(f, STAT) &= ~value; > > > > + break; > > > > + } > > > > + case A_FLEXCOMM_I2C_SLVCTL: > > > > + case A_FLEXCOMM_I2C_SLVDAT: > > > > + case A_FLEXCOMM_I2C_SLVADR0: > > > > + case A_FLEXCOMM_I2C_SLVADR1: > > > > + case A_FLEXCOMM_I2C_SLVADR2: > > > > + case A_FLEXCOMM_I2C_SLVADR3: > > > > + case A_FLEXCOMM_I2C_SLVQUAL0: > > > > + { > > > > + qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported\n"); > > > > + break; > > > > + } > > > > + default: > > > > + register_write(&ri, value, ~0, NULL, false); > > > > + break; > > > > + } > > > > + > > > > + flexcomm_i2c_irq_update(f); > > > > + > > > > + return MEMTX_OK; > > > > +} > > > > + > > > > +static void flexcomm_i2c_select(FlexcommFunction *f, bool selected) > > > > +{ > > > > + FlexcommI2cClass *ic = FLEXCOMM_I2C_GET_CLASS(f); > > > > + > > > > + if (selected) { > > > > + flexcomm_i2c_reset(f); > > > > + } > > > > + ic->select(f, selected); > > > > +} > > > > + > > > > +static const MemoryRegionOps flexcomm_i2c_ops = { > > > > + .read_with_attrs = flexcomm_i2c_reg_read, > > > > + .write_with_attrs = flexcomm_i2c_reg_write, > > > > + .endianness = DEVICE_NATIVE_ENDIAN, > > > > + .valid = { > > > > + .min_access_size = 4, > > > > + .max_access_size = 4, > > > > + .unaligned = false, > > > > + }, > > > > +}; > > > > + > > > > +static void flexcomm_i2c_realize(DeviceState *dev, Error **errp) > > > > +{ > > > > + FlexcommI2cState *s = FLEXCOMM_I2C(dev); > > > > + > > > > + s->bus = i2c_init_bus(DEVICE(s), "bus"); > > > > +} > > > > + > > > > +static void flexcomm_i2c_class_init(ObjectClass *klass, void *data) > > > > +{ > > > > + DeviceClass *dc = DEVICE_CLASS(klass); > > > > + FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_CLASS(klass); > > > > + FlexcommI2cClass *ic = FLEXCOMM_I2C_CLASS(klass); > > > > + > > > > + dc->realize = flexcomm_i2c_realize; > > > > + ic->select = fc->select; > > > > + fc->select = flexcomm_i2c_select; > > > > + fc->name = "i2c"; > > > > + fc->mmio_ops = &flexcomm_i2c_ops; > > > > +} > > > > + > > > > +static const TypeInfo flexcomm_i2c_types[] = { > > > > + { > > > > + .name = TYPE_FLEXCOMM_I2C, > > > > + .parent = TYPE_FLEXCOMM_FUNCTION, > > > > + .instance_size = sizeof(FlexcommI2cState), > > > > + .class_init = flexcomm_i2c_class_init, > > > > + .class_size = sizeof(FlexcommI2cClass), > > > > + }, > > > > +}; > > > > + > > > > +DEFINE_TYPES(flexcomm_i2c_types); > > > > diff --git a/hw/misc/flexcomm.c b/hw/misc/flexcomm.c > > > > index a291148f27..b1a2f01acf 100644 > > > > --- a/hw/misc/flexcomm.c > > > > +++ b/hw/misc/flexcomm.c > > > > @@ -24,6 +24,7 @@ > > > > #include "hw/misc/flexcomm.h" > > > > #include "hw/arm/svd/flexcomm_usart.h" > > > > #include "hw/char/flexcomm_usart.h" > > > > +#include "hw/i2c/flexcomm_i2c.h" > > > > > > > > #define REG(s, reg) (s->regs[R_FLEXCOMM_##reg]) > > > > #define RF_WR(s, reg, field, val) \ > > > > @@ -220,6 +221,7 @@ static void flexcomm_init(Object *obj) > > > > sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container); > > > > sysbus_init_irq(sbd, &s->irq); > > > > object_initialize_child(obj, "usart", &s->usart, > > > > TYPE_FLEXCOMM_USART); > > > > + object_initialize_child(obj, "i2c", &s->i2c, TYPE_FLEXCOMM_I2C); > > > > } > > > > > > > > static void flexcomm_finalize(Object *obj) > > > > @@ -250,6 +252,7 @@ static void flexcomm_realize(DeviceState *dev, > > > > Error **errp) > > > > > > > > memory_region_add_subregion_overlap(&s->container, 0, &s->mmio, > > > > -1); > > > > flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->usart), > > > > errp); > > > > + flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->i2c), errp); > > > > } > > > > > > > > static const VMStateDescription vmstate_flexcomm = { > > > > diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build > > > > index 2bde34d15b..417491cd5c 100644 > > > > --- a/hw/arm/svd/meson.build > > > > +++ b/hw/arm/svd/meson.build > > > > @@ -7,4 +7,7 @@ if get_option('mcux-soc-svd') > > > > run_target('svd-flexcomm-usart', command: svd_gen_header + > > > > [ '-i', rt595, '-o', > > > > '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_usart.h', > > > > '-p', 'USART0', '-t', 'FLEXCOMM_USART']) > > > > + run_target('svd-flexcomm-i2c', command: svd_gen_header + > > > > + [ '-i', rt595, '-o', > > > > '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_i2c.h', > > > > + '-p', 'I2C0', '-t', 'FLEXCOMM_I2C']) > > > > endif > > > > diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build > > > > index c459adcb59..e7d79e6938 100644 > > > > --- a/hw/i2c/meson.build > > > > +++ b/hw/i2c/meson.build > > > > @@ -18,4 +18,5 @@ i2c_ss.add(when: 'CONFIG_PPC4XX', if_true: > > > > files('ppc4xx_i2c.c')) > > > > i2c_ss.add(when: 'CONFIG_PCA954X', if_true: files('i2c_mux_pca954x.c')) > > > > i2c_ss.add(when: 'CONFIG_PMBUS', if_true: files('pmbus_device.c')) > > > > i2c_ss.add(when: 'CONFIG_BCM2835_I2C', if_true: files('bcm2835_i2c.c')) > > > > +i2c_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm_i2c.c')) > > > > system_ss.add_all(when: 'CONFIG_I2C', if_true: i2c_ss) > > > > diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events > > > > index 6900e06eda..9f0175fab7 100644 > > > > --- a/hw/i2c/trace-events > > > > +++ b/hw/i2c/trace-events > > > > @@ -51,3 +51,13 @@ npcm7xx_smbus_recv_fifo(const char *id, uint8_t > > > > received, uint8_t expected) "%s > > > > > > > > pca954x_write_bytes(uint8_t value) "PCA954X write data: 0x%02x" > > > > pca954x_read_data(uint8_t value) "PCA954X read data: 0x%02x" > > > > + > > > > +# flexcomm_i2c.c > > > > + > > > > +flexcomm_i2c_reg_read(const char *id, const char *reg_name, uint32_t > > > > addr, uint32_t val) " %s: %s[0x%04x] -> 0x%08x" > > > > +flexcomm_i2c_reg_write(const char *id, const char *reg_name, uint32_t > > > > addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x" > > > > +flexcomm_i2c_start(const char *id, uint8_t addr, uint8_t recv) "%s: > > > > 0x%02x %d" > > > > +flexcomm_i2c_rx(const char *id, uint8_t data) "%s: <- 0x%02x" > > > > +flexcomm_i2c_tx(const char *id, uint8_t data) "%s: -> 0x%02x" > > > > +flexcomm_i2c_nak(const char *id) "%s: <- nak" > > > > +flexcomm_i2c_irq(const char *id, bool irq, bool perirqs, bool enabled) > > > > "%s: %d %d %d" > > > > diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig > > > > index 14167ae9e8..9a244fa01d 100644 > > > > --- a/hw/misc/Kconfig > > > > +++ b/hw/misc/Kconfig > > > > @@ -215,5 +215,6 @@ config XLNX_VERSAL_TRNG > > > > > > > > config FLEXCOMM > > > > bool > > > > + select I2C > > > > > > > > source macio/Kconfig > > > > -- > > > > 2.46.0.662.g92d0881bb0-goog > > > > > > > >