Skip to content

Conversation

@d-philpot
Copy link
Contributor

Adds I2C controller and target support for MSPM0. Includes driver changes, dts and board updates.

@pdgendt pdgendt dismissed their stale review August 19, 2025 14:39

comment addressed

@parthitce parthitce linked an issue Aug 20, 2025 that may be closed by this pull request
Copy link
Member

@parthitce parthitce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This driver needs lot of re-factor. In summary,

  • ISR context is handling all the data path, which needs to be abstracted.
  • Target and Controller support needs to be split.
  • Multi target support needs to be compile time based on devicetree target nodes.
  • Current usage of data section is high and needs to be optimized based on rodata / data place-holding.

Current code base is not compilable as well. So IMO it makes sense to put in DRAFT until it's ready for review.

Copy link
Contributor

@teburd teburd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some confusing things going on, maybe because the HAL is handling interrupts? It's unclear, but those should be handled by Zephyr not by the HAL if that's the case.

DL_I2C_startControllerTransfer(config->base, data->addr, DL_I2C_CONTROLLER_DIRECTION_TX,
data->msg.len);

while (!(DL_I2C_getControllerStatus(config->base) & DL_I2C_CONTROLLER_STATUS_IDLE)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tight polling loops like this aren't inherently wrong but typically there's an interrupt signal available.

Would recommend changing the driver, if possible, to use an interrupt (event driven) state machine that is kicked off by the transfer function, and completed when the state machine signals back to the thread that had called transfer blocking on a k_sem_take by giving a semaphore.

If you really want the tight poll loop here instead, or there's no other option, use a WAIT_FOR() macro with a timeout such that even given a faulty i2c transfer the caller isn't blocked forever and instead may get an error.

https://docs.zephyrproject.org/latest/doxygen/html/group__sys-util.html#ga68eb35df6b4715714312df90209accee

Copy link
Contributor Author

@d-philpot d-philpot Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into refactoring transfer to use semaphores

while (!(DL_I2C_getControllerStatus(config->base) & DL_I2C_CONTROLLER_STATUS_IDLE)) {
}

if (data->state == I2C_MSPM0_TIMEOUT) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I maybe spoke too soon if there's a hardware timeout available.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a configurable SCL low hardware timeout available

reg:
required: true

interrupts:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the interrupts being used?

#address-cells = <1>;
#size-cells = <0>;
reg = <0x400f2000 0x2000>;
interrupts = <26 0>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem like the driver supports interrupts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interrupts are used for controller and target logic

@d-philpot
Copy link
Contributor Author

This driver needs lot of re-factor. In summary,

  • ISR context is handling all the data path, which needs to be abstracted.
  • Target and Controller support needs to be split.
  • Multi target support needs to be compile time based on devicetree target nodes.
  • Current usage of data section is high and needs to be optimized based on rodata / data place-holding.

Current code base is not compilable as well. So IMO it makes sense to put in DRAFT until it's ready for review.

The code base is compliable. Target support is split and optional from controller via kconfig define. Multi target support is compile time based on Kconfig defines

@d-philpot d-philpot force-pushed the i2c_dev branch 3 times, most recently from 1f122c6 to b708dc5 Compare August 27, 2025 18:27
@d-philpot d-philpot requested review from pdgendt and teburd August 27, 2025 19:27
@d-philpot
Copy link
Contributor Author

@teburd Ping for re-review. Refactored transmit logic to use semaphores instead of busy wait looping

Copy link
Contributor

@tbursztyka tbursztyka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ISR handler would gain in clarity being split: irq types handled in dedicated inline functions and as noted already: target stuff being on their own as well.

@github-actions
Copy link

github-actions bot commented Sep 11, 2025

The following west manifest projects have changed revision in this Pull Request:

Name Old Revision New Revision Diff
hal_ti zephyrproject-rtos/hal_ti@cc04902 zephyrproject-rtos/hal_ti@7b34b50 zephyrproject-rtos/hal_ti@cc049020..7b34b502

All manifest checks OK

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@github-actions github-actions bot added manifest manifest-hal_ti DNM (manifest) This PR should not be merged (controlled by action-manifest) labels Sep 11, 2025
tbursztyka
tbursztyka previously approved these changes Oct 1, 2025
@d-philpot
Copy link
Contributor Author

@teburd @tbursztyka @ssekar15 Please review

tbursztyka
tbursztyka previously approved these changes Oct 8, 2025
teburd
teburd previously approved these changes Oct 21, 2025
@github-actions github-actions bot removed the DNM (manifest) This PR should not be merged (controlled by action-manifest) label Oct 27, 2025
@zephyrbot zephyrbot requested a review from teburd October 27, 2025 14:21
@d-philpot d-philpot requested a review from tbursztyka October 27, 2025 15:29
@d-philpot
Copy link
Contributor Author

@teburd ping for re-review, updated manifest

Copy link
Member

@parthitce parthitce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am still having a closer look.

struct i2c_msg transaction_msg;
int ret = 0;

k_sem_take(data->i2c_busy_sem, K_FOREVER);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO there is no real protection against the target mode here. Move below the is_target condition check?

uint32_t speed_config;

/* Init power */
DL_I2C_reset(config->base);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure reset before enabling power will work

ret = clock_control_get_rate(clk_dev, (clock_control_subsys_t)config->clock_subsys,
&clock_rate);
if (ret < 0) {
ret = -ENODEV;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

propagate the clock error instead?

goto out;
}

if (dev_config & I2C_MSG_ADDR_10_BITS) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this sanity check can be done as entry into the function and return directly

ti,pwm-mode = "EDGE_ALIGN";
ti,period = <1000>;
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this commit can be dropped. Sample or App can decide the whole usage in dts, pins and Kconfig. Doesn't needs to be enabled by default.


/ {
soc {
i2c0: i2c@400f0000 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we keep the common i2c which is available across all series in mspm0.dtsi?

Copy link
Contributor Author

@d-philpot d-philpot Nov 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

future mspm0 devices will not all have base i2c0 peripheral

@@ -0,0 +1,814 @@
/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bindings is not part of this commit. either adjust the commit message or add the bindings file here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amended

return 0;
}

static int i2c_mspm0_reset_peripheral_target(const struct device *dev)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we instead wrap this with recover_bus and leave the decision to consumer?

struct i2c_target_config *target_config;
const struct i2c_target_callbacks *target_callbacks;
#endif /* CONFIG_I2C_TARGET */
bool is_target;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be dropped IMO

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_target is used during runtime for apis and ISRs

goto out;
}

k_sem_take(data->i2c_busy_sem, K_FOREVER);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Protecting the controller / IP as a resource doesn't need to lock for the whole function. Applies everywhere.

{
struct i2c_mspm0_data *data = dev->data;
*dev_config = data->dev_config;
return 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the i2c is not configured, this API shall return error as per API description

data->dev_config = dev_config;

#if (CONFIG_I2C_SCL_LOW_TIMEOUT != 0)
ret = i2c_mspm0_configure_timeout(dev, period, CONFIG_I2C_SCL_LOW_TIMEOUT);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proceeding on error?

DL_I2C_setTargetOwnAddress(config->base, data->target_config->address);
DL_I2C_setTargetTXFIFOThreshold(config->base, DL_I2C_TX_FIFO_LEVEL_BYTES_1);
DL_I2C_setTargetRXFIFOThreshold(config->base, DL_I2C_RX_FIFO_LEVEL_BYTES_1);
DL_I2C_enableTargetTXTriggerInTXMode(config->base);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but the trigger levels aren't handled in ISR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FIFO trigger interrupts are used in the ISR

@d-philpot d-philpot force-pushed the i2c_dev branch 2 times, most recently from 46a5870 to 04a2416 Compare November 3, 2025 20:58
Changes default pin properties for I2C. Signed-off-by: Dylan Philpot <d-philpot@ti.com>
Includes driver implementation for I2C controller and peripheral support. Signed-off-by: Dylan Philpot <d-philpot@ti.com>
Adds devicetree entries for different I2C peripherals on MSPM0 devices and dts binding changes for I2C driver. Signed-off-by: Dylan Philpot <d-philpot@ti.com>
@d-philpot d-philpot requested a review from parthitce November 5, 2025 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment