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,57 @@ 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+ int err = counter_stop (config -> watchdog_timer );
124+ if (err != 0 ) {
125+ LOG_ERR ("Failed to stop the timer, err: %d" , err );
126+ }
127+
128+ err = counter_cancel_channel_alarm (config -> watchdog_timer , 0 );
129+ if (err != 0 ) {
130+ LOG_ERR ("Failed to cancel the timer alarm, err: %d" , err );
131+ }
132+ }
133+
134+ static void i2c_mspm0g3xxx_target_reset (const struct device * dev , uint8_t channel , uint32_t ticks ,
135+ void * user_data )
136+ {
137+ struct i2c_mspm0g3xxx_data * data = user_data ;
138+ const struct i2c_mspm0g3xxx_config * config = data -> cfg ;
139+
140+ DL_I2C_setTargetACKOverrideValue ((I2C_Regs * )config -> base ,
141+ DL_I2C_TARGET_RESPONSE_OVERRIDE_VALUE_NACK );
142+ DL_I2C_disableTargetClockStretching ((I2C_Regs * )config -> base );
143+ DL_I2C_disablePower ((I2C_Regs * )config -> base );
144+ z_except_reason (CONFIG_I2C_MSPM0G3XXX_WATCHDOG_PANIC_CODE );
145+ }
146+
147+ static void i2c_mspm0g3xxx_target_start_watchdog (struct i2c_mspm0g3xxx_data * data )
148+ {
149+ const struct i2c_mspm0g3xxx_config * config = data -> cfg ;
150+ struct counter_alarm_cfg * watchdog_timer_cfg = & data -> watchdog_timer_cfg ;
151+
152+ if (!config -> watchdog_timer )
153+ return ;
154+
155+ i2c_mspm0g3xxx_target_stop_watchdog (data );
156+
157+ int err = counter_set_channel_alarm (config -> watchdog_timer , 0 , watchdog_timer_cfg );
158+ if (err != 0 ) {
159+ LOG_ERR ("Failed to cancel the timer alarm, err: %d" , err );
160+ }
161+
162+ err = counter_start (config -> watchdog_timer );
163+ if (err != 0 ) {
164+ LOG_ERR ("Failed to start the timer, err: %d" , err );
165+ }
166+ }
167+
114168void i2c_mspm0g3xxx_target_thread_work (void )
115169{
116170 struct i2c_mspm0g3xxx_target_msg target_msg ;
@@ -142,8 +196,10 @@ void i2c_mspm0g3xxx_target_thread_work(void)
142196 if (data -> state == I2C_mspm0g3xxx_TARGET_STARTED ) {
143197 data -> state = I2C_mspm0g3xxx_TARGET_RX_INPROGRESS ;
144198 if (tconfig -> callbacks -> write_requested != NULL ) {
199+ i2c_mspm0g3xxx_target_start_watchdog (data );
145200 data -> target_rx_valid =
146201 tconfig -> callbacks -> write_requested (tconfig );
202+ i2c_mspm0g3xxx_target_stop_watchdog (data );
147203 }
148204 }
149205 /* Store received data in buffer */
@@ -154,9 +210,11 @@ void i2c_mspm0g3xxx_target_thread_work(void)
154210 if (data -> target_rx_valid == 0 ) {
155211 nextByte = DL_I2C_receiveTargetData (
156212 (I2C_Regs * )config -> base );
213+ i2c_mspm0g3xxx_target_start_watchdog (data );
157214 data -> target_rx_valid =
158215 tconfig -> callbacks -> write_received (
159216 tconfig , nextByte );
217+ i2c_mspm0g3xxx_target_stop_watchdog (data );
160218
161219 if (data -> target_rx_valid == 0 ) {
162220 DL_I2C_setTargetACKOverrideValue (
@@ -183,8 +241,10 @@ void i2c_mspm0g3xxx_target_thread_work(void)
183241 /* Fill TX FIFO if there are more bytes to send */
184242 if (tconfig -> callbacks -> read_requested != NULL ) {
185243 uint8_t nextByte ;
244+ i2c_mspm0g3xxx_target_start_watchdog (data );
186245 data -> target_tx_valid =
187246 tconfig -> callbacks -> read_requested (tconfig , & nextByte );
247+ i2c_mspm0g3xxx_target_stop_watchdog (data );
188248 if (data -> target_tx_valid == 0 ) {
189249 DL_I2C_transmitTargetData ((I2C_Regs * )config -> base ,
190250 nextByte );
@@ -203,8 +263,10 @@ void i2c_mspm0g3xxx_target_thread_work(void)
203263 * will be filled in */
204264 uint8_t nextByte ;
205265 if (data -> target_tx_valid == 0 ) {
266+ i2c_mspm0g3xxx_target_start_watchdog (data );
206267 data -> target_tx_valid = tconfig -> callbacks -> read_processed (
207268 tconfig , & nextByte );
269+ i2c_mspm0g3xxx_target_stop_watchdog (data );
208270 }
209271
210272 if (data -> target_tx_valid == 0 ) {
@@ -221,7 +283,9 @@ void i2c_mspm0g3xxx_target_thread_work(void)
221283 data -> state = I2C_mspm0g3xxx_IDLE ;
222284 k_sem_give (& data -> i2c_busy_sem );
223285 if (tconfig -> callbacks -> stop ) {
286+ i2c_mspm0g3xxx_target_start_watchdog (data );
224287 tconfig -> callbacks -> stop (tconfig );
288+ i2c_mspm0g3xxx_target_stop_watchdog (data );
225289 }
226290 break ;
227291 default :
@@ -768,12 +832,24 @@ static int i2c_mspm0g3xxx_init(const struct device *dev)
768832 config -> clock_frequency );
769833 return - EINVAL ;
770834 }
835+
771836 LOG_DBG ("DT bitrate %uHz (%u)" , config -> clock_frequency ,
772837 config -> dt_bitrate );
773838
774839 k_sem_init (& data -> i2c_busy_sem , 0 , 1 );
775840 k_sem_init (& data -> transfer_timeout_sem , 1 , 1 );
776841
842+ if (config -> watchdog_timer ) {
843+ if (!device_is_ready (config -> watchdog_timer )) {
844+ LOG_ERR ("Watchdog timer is not ready" );
845+ return - EINVAL ;
846+ }
847+
848+ data -> watchdog_timer_cfg .user_data = (void * )data ;
849+ data -> watchdog_timer_cfg .callback = i2c_mspm0g3xxx_target_reset ;
850+ data -> watchdog_timer_cfg .ticks = counter_us_to_ticks (config -> watchdog_timer , CONFIG_I2C_MSPM0G3XXX_WATCHDOG_TIMEOUT );
851+ }
852+
777853 /* Init power */
778854 DL_I2C_reset ((I2C_Regs * )config -> base );
779855 DL_I2C_enablePower ((I2C_Regs * )config -> base );
@@ -895,6 +971,7 @@ static const struct i2c_driver_api i2c_mspm0g3xxx_driver_api = {
895971 .divideRatio = DL_I2C_CLOCK_DIVIDE_1}, \
896972 .dt_bitrate = CALC_DT_BITRATE(DT_INST_PROP(index, clock_frequency), \
897973 DT_INST_PROP_BY_PHANDLE(index, clocks, clock_frequency)), \
974+ .watchdog_timer = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(DT_DRV_INST(index), watchdog_timer)),\
898975 }; \
899976 \
900977 static struct i2c_mspm0g3xxx_data i2c_mspm0g3xxx_data_##index = { \
@@ -903,7 +980,7 @@ static const struct i2c_driver_api i2c_mspm0g3xxx_driver_api = {
903980 \
904981 I2C_DEVICE_DT_INST_DEFINE(index, i2c_mspm0g3xxx_init, NULL, &i2c_mspm0g3xxx_data_##index, \
905982 &i2c_mspm0g3xxx_cfg_##index, POST_KERNEL, \
906- CONFIG_I2C_INIT_PRIORITY , &i2c_mspm0g3xxx_driver_api); \
983+ CONFIG_COUNTER_INIT_PRIORITY , &i2c_mspm0g3xxx_driver_api); \
907984 \
908985 INTERRUPT_INIT_FUNCTION(index)
909986
0 commit comments