66#include <zephyr/kernel.h>
77#include <zephyr/drivers/i2c.h>
88#include <zephyr/drivers/pinctrl.h>
9+ #include <zephyr/drivers/counter.h>
910#include <soc.h>
1011
1112/* Logging includes */
@@ -76,6 +77,7 @@ struct i2c_mspm0g3xxx_config {
7677 const struct pinctrl_dev_config * pinctrl ;
7778 void (* interrupt_init_function )(const struct device * dev );
7879 uint32_t dt_bitrate ;
80+ const struct device * watchdog_timer ;
7981};
8082
8183struct i2c_mspm0g3xxx_data {
@@ -92,6 +94,7 @@ struct i2c_mspm0g3xxx_data {
9294 int target_rx_valid ;
9395 struct k_sem i2c_busy_sem ;
9496 struct k_sem transfer_timeout_sem ;
97+ struct counter_alarm_cfg watchdog_timer_cfg ;
9598};
9699
97100#ifdef CONFIG_I2C_MSPM0G3XXX_TARGET_SUPPORT
@@ -111,6 +114,58 @@ static K_KERNEL_STACK_DEFINE(i2c_mspm0g3xxx_target_stack,
111114 CONFIG_I2C_MSPM0G3XXX_TARGET_THREAD_STACK_SIZE ) ;
112115static struct k_thread i2c_mspm0g3xxx_target_thread ;
113116
117+ static void i2c_mspm0g3xxx_target_stop_watchdog (struct i2c_mspm0g3xxx_data * data ) {
118+ const struct i2c_mspm0g3xxx_config * config = data -> cfg ;
119+
120+ if (!config -> watchdog_timer ) {
121+ return ;
122+ }
123+
124+ int err = counter_stop (config -> watchdog_timer );
125+ if (err != 0 ) {
126+ LOG_ERR ("Failed to stop the timer, err: %d" , err );
127+ }
128+
129+ err = counter_cancel_channel_alarm (config -> watchdog_timer , 0 );
130+ if (err != 0 ) {
131+ LOG_ERR ("Failed to cancel the timer alarm, err: %d" , err );
132+ }
133+ }
134+
135+ static void i2c_mspm0g3xxx_target_reset (const struct device * dev , uint8_t channel , uint32_t ticks ,
136+ void * user_data )
137+ {
138+ struct i2c_mspm0g3xxx_data * data = user_data ;
139+ const struct i2c_mspm0g3xxx_config * config = data -> cfg ;
140+
141+ DL_I2C_setTargetACKOverrideValue ((I2C_Regs * )config -> base ,
142+ DL_I2C_TARGET_RESPONSE_OVERRIDE_VALUE_NACK );
143+ DL_I2C_disableTargetClockStretching ((I2C_Regs * )config -> base );
144+ DL_I2C_disablePower ((I2C_Regs * )config -> base );
145+ z_except_reason (CONFIG_I2C_MSPM0G3XXX_WATCHDOG_PANIC_CODE );
146+ }
147+
148+ static void i2c_mspm0g3xxx_target_start_watchdog (struct i2c_mspm0g3xxx_data * data )
149+ {
150+ const struct i2c_mspm0g3xxx_config * config = data -> cfg ;
151+ struct counter_alarm_cfg * watchdog_timer_cfg = & data -> watchdog_timer_cfg ;
152+
153+ if (!config -> watchdog_timer )
154+ return ;
155+
156+ i2c_mspm0g3xxx_target_stop_watchdog (data );
157+
158+ int err = counter_set_channel_alarm (config -> watchdog_timer , 0 , watchdog_timer_cfg );
159+ if (err != 0 ) {
160+ LOG_ERR ("Failed to cancel the timer alarm, err: %d" , err );
161+ }
162+
163+ err = counter_start (config -> watchdog_timer );
164+ if (err != 0 ) {
165+ LOG_ERR ("Failed to start the timer, err: %d" , err );
166+ }
167+ }
168+
114169void i2c_mspm0g3xxx_target_thread_work (void )
115170{
116171 struct i2c_mspm0g3xxx_target_msg target_msg ;
@@ -142,8 +197,10 @@ void i2c_mspm0g3xxx_target_thread_work(void)
142197 if (data -> state == I2C_mspm0g3xxx_TARGET_STARTED ) {
143198 data -> state = I2C_mspm0g3xxx_TARGET_RX_INPROGRESS ;
144199 if (tconfig -> callbacks -> write_requested != NULL ) {
200+ i2c_mspm0g3xxx_target_start_watchdog (data );
145201 data -> target_rx_valid =
146202 tconfig -> callbacks -> write_requested (tconfig );
203+ i2c_mspm0g3xxx_target_stop_watchdog (data );
147204 }
148205 }
149206 /* Store received data in buffer */
@@ -154,9 +211,11 @@ void i2c_mspm0g3xxx_target_thread_work(void)
154211 if (data -> target_rx_valid == 0 ) {
155212 nextByte = DL_I2C_receiveTargetData (
156213 (I2C_Regs * )config -> base );
214+ i2c_mspm0g3xxx_target_start_watchdog (data );
157215 data -> target_rx_valid =
158216 tconfig -> callbacks -> write_received (
159217 tconfig , nextByte );
218+ i2c_mspm0g3xxx_target_stop_watchdog (data );
160219
161220 if (data -> target_rx_valid == 0 ) {
162221 DL_I2C_setTargetACKOverrideValue (
@@ -183,8 +242,10 @@ void i2c_mspm0g3xxx_target_thread_work(void)
183242 /* Fill TX FIFO if there are more bytes to send */
184243 if (tconfig -> callbacks -> read_requested != NULL ) {
185244 uint8_t nextByte ;
245+ i2c_mspm0g3xxx_target_start_watchdog (data );
186246 data -> target_tx_valid =
187247 tconfig -> callbacks -> read_requested (tconfig , & nextByte );
248+ i2c_mspm0g3xxx_target_stop_watchdog (data );
188249 if (data -> target_tx_valid == 0 ) {
189250 DL_I2C_transmitTargetData ((I2C_Regs * )config -> base ,
190251 nextByte );
@@ -203,8 +264,10 @@ void i2c_mspm0g3xxx_target_thread_work(void)
203264 * will be filled in */
204265 uint8_t nextByte ;
205266 if (data -> target_tx_valid == 0 ) {
267+ i2c_mspm0g3xxx_target_start_watchdog (data );
206268 data -> target_tx_valid = tconfig -> callbacks -> read_processed (
207269 tconfig , & nextByte );
270+ i2c_mspm0g3xxx_target_stop_watchdog (data );
208271 }
209272
210273 if (data -> target_tx_valid == 0 ) {
@@ -221,7 +284,9 @@ void i2c_mspm0g3xxx_target_thread_work(void)
221284 data -> state = I2C_mspm0g3xxx_IDLE ;
222285 k_sem_give (& data -> i2c_busy_sem );
223286 if (tconfig -> callbacks -> stop ) {
287+ i2c_mspm0g3xxx_target_start_watchdog (data );
224288 tconfig -> callbacks -> stop (tconfig );
289+ i2c_mspm0g3xxx_target_stop_watchdog (data );
225290 }
226291 break ;
227292 default :
@@ -768,12 +833,25 @@ static int i2c_mspm0g3xxx_init(const struct device *dev)
768833 config -> clock_frequency );
769834 return - EINVAL ;
770835 }
836+
771837 LOG_DBG ("DT bitrate %uHz (%u)" , config -> clock_frequency ,
772838 config -> dt_bitrate );
773839
774840 k_sem_init (& data -> i2c_busy_sem , 0 , 1 );
775841 k_sem_init (& data -> transfer_timeout_sem , 1 , 1 );
776842
843+ if (config -> watchdog_timer ) {
844+ if (!device_is_ready (config -> watchdog_timer )) {
845+ LOG_ERR ("Watchdog timer is not ready" );
846+ return - EINVAL ;
847+ }
848+
849+ data -> watchdog_timer_cfg .user_data = (void * )data ;
850+ data -> watchdog_timer_cfg .callback = i2c_mspm0g3xxx_target_reset ;
851+ data -> watchdog_timer_cfg .ticks = counter_us_to_ticks (
852+ config -> watchdog_timer , CONFIG_I2C_MSPM0G3XXX_WATCHDOG_TIMEOUT );
853+ }
854+
777855 /* Init power */
778856 DL_I2C_reset ((I2C_Regs * )config -> base );
779857 DL_I2C_enablePower ((I2C_Regs * )config -> base );
@@ -895,6 +973,7 @@ static const struct i2c_driver_api i2c_mspm0g3xxx_driver_api = {
895973 .divideRatio = DL_I2C_CLOCK_DIVIDE_1}, \
896974 .dt_bitrate = CALC_DT_BITRATE(DT_INST_PROP(index, clock_frequency), \
897975 DT_INST_PROP_BY_PHANDLE(index, clocks, clock_frequency)), \
976+ .watchdog_timer = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(DT_DRV_INST(index), watchdog_timer)),\
898977 }; \
899978 \
900979 static struct i2c_mspm0g3xxx_data i2c_mspm0g3xxx_data_##index = { \
@@ -903,7 +982,7 @@ static const struct i2c_driver_api i2c_mspm0g3xxx_driver_api = {
903982 \
904983 I2C_DEVICE_DT_INST_DEFINE(index, i2c_mspm0g3xxx_init, NULL, &i2c_mspm0g3xxx_data_##index, \
905984 &i2c_mspm0g3xxx_cfg_##index, POST_KERNEL, \
906- CONFIG_I2C_INIT_PRIORITY , &i2c_mspm0g3xxx_driver_api); \
985+ CONFIG_COUNTER_INIT_PRIORITY , &i2c_mspm0g3xxx_driver_api); \
907986 \
908987 INTERRUPT_INIT_FUNCTION(index)
909988
0 commit comments