mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-26 03:37:51 +00:00 
			
		
		
		
	Merge branch 'bugfix/i2c_incorrect_speed_v4.3' into 'release/v4.3'
I2C: Fix SCL period timings on ESP targets (backport v4.3) See merge request espressif/esp-idf!18272
This commit is contained in:
		| @@ -1,16 +1,8 @@ | |||||||
| // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD | /* | ||||||
| // |  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  * | ||||||
| // you may not use this file except in compliance with the License. |  * SPDX-License-Identifier: Apache-2.0 | ||||||
| // You may obtain a copy of the License at |  */ | ||||||
| // |  | ||||||
| //     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| // The LL layer for I2C register operations | // The LL layer for I2C register operations | ||||||
|  |  | ||||||
| @@ -121,9 +113,29 @@ static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2 | |||||||
|  */ |  */ | ||||||
| static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg) | static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg) | ||||||
| { | { | ||||||
|     //scl period |     /* SCL period. According to the TRM, we should always subtract 1 to SCL low period */ | ||||||
|     hw->scl_low_period.period = bus_cfg->scl_low; |     assert(bus_cfg->scl_low > 0); | ||||||
|     hw->scl_high_period.period = bus_cfg->scl_high; |     hw->scl_low_period.period = bus_cfg->scl_low - 1; | ||||||
|  |     /* Still according to the TRM, if filter is not enbled, we have to subtract 7, | ||||||
|  |      * if SCL filter is enabled, we have to subtract: | ||||||
|  |      *   8 if SCL filter is between 0 and 2 (included) | ||||||
|  |      *   6 + SCL threshold if SCL filter is between 3 and 7 (included) | ||||||
|  |      * to SCL high period */ | ||||||
|  |     uint16_t scl_high = bus_cfg->scl_high; | ||||||
|  |     /* In the "worst" case, we will subtract 13, make sure the result will still be correct */ | ||||||
|  |     assert(scl_high > 13); | ||||||
|  |     if (hw->scl_filter_cfg.en) { | ||||||
|  |         if (hw->scl_filter_cfg.thres <= 2) { | ||||||
|  |             scl_high -= 8; | ||||||
|  |         } else if (hw->scl_filter_cfg.thres <= 7) { | ||||||
|  |             scl_high -= hw->scl_filter_cfg.thres + 6; | ||||||
|  |         } else { | ||||||
|  |             assert(false); | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         scl_high -= 7; | ||||||
|  |     } | ||||||
|  |     hw->scl_high_period.period = scl_high; | ||||||
|     //sda sample |     //sda sample | ||||||
|     hw->sda_hold.time = bus_cfg->sda_hold; |     hw->sda_hold.time = bus_cfg->sda_hold; | ||||||
|     hw->sda_sample.time = bus_cfg->sda_sample; |     hw->sda_sample.time = bus_cfg->sda_sample; | ||||||
|   | |||||||
| @@ -1,16 +1,8 @@ | |||||||
| // Copyright 2020 Espressif Systems (Shanghai) PTE LTD | /* | ||||||
| // |  * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  * | ||||||
| // you may not use this file except in compliance with the License. |  * SPDX-License-Identifier: Apache-2.0 | ||||||
| // You may obtain a copy of the License at |  */ | ||||||
| // |  | ||||||
| //     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| // The LL layer for I2C register operations | // The LL layer for I2C register operations | ||||||
|  |  | ||||||
| @@ -156,17 +148,17 @@ static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg) | |||||||
| { | { | ||||||
|     HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, bus_cfg->clkm_div - 1); |     HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, bus_cfg->clkm_div - 1); | ||||||
|     //scl period |     //scl period | ||||||
|     hw->scl_low_period.period = bus_cfg->scl_low - 1; |     hw->scl_low_period.period = bus_cfg->scl_low - 2; | ||||||
|     hw->scl_high_period.period = bus_cfg->scl_high; |     hw->scl_high_period.period = bus_cfg->scl_high - 3; | ||||||
|     //sda sample |     //sda sample | ||||||
|     hw->sda_hold.time = bus_cfg->sda_hold; |     hw->sda_hold.time = bus_cfg->sda_hold - 1; | ||||||
|     hw->sda_sample.time = bus_cfg->sda_sample; |     hw->sda_sample.time = bus_cfg->sda_sample - 1; | ||||||
|     //setup |     //setup | ||||||
|     hw->scl_rstart_setup.time = bus_cfg->setup; |     hw->scl_rstart_setup.time = bus_cfg->setup - 1; | ||||||
|     hw->scl_stop_setup.time = bus_cfg->setup; |     hw->scl_stop_setup.time = bus_cfg->setup - 1; | ||||||
|     //hold |     //hold | ||||||
|     hw->scl_start_hold.time = bus_cfg->hold - 1; |     hw->scl_start_hold.time = bus_cfg->hold - 1; | ||||||
|     hw->scl_stop_hold.time = bus_cfg->hold; |     hw->scl_stop_hold.time = bus_cfg->hold - 1; | ||||||
|     hw->timeout.time_out_value = bus_cfg->tout; |     hw->timeout.time_out_value = bus_cfg->tout; | ||||||
|     hw->timeout.time_out_en = 1; |     hw->timeout.time_out_en = 1; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,16 +1,8 @@ | |||||||
| // Copyright 2020 Espressif Systems (Shanghai) PTE LTD | /* | ||||||
| // |  * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  * | ||||||
| // you may not use this file except in compliance with the License. |  * SPDX-License-Identifier: Apache-2.0 | ||||||
| // You may obtain a copy of the License at |  */ | ||||||
| // |  | ||||||
| //     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| // The LL layer for I2C register operations | // The LL layer for I2C register operations | ||||||
|  |  | ||||||
| @@ -147,18 +139,20 @@ static inline void i2c_ll_update(i2c_dev_t *hw) | |||||||
| static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg) | static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg) | ||||||
| { | { | ||||||
|     hw->clk_conf.sclk_div_num = bus_cfg->clkm_div - 1; |     hw->clk_conf.sclk_div_num = bus_cfg->clkm_div - 1; | ||||||
|  |     /* According to the Technical Reference Manual, the following timings must be subtracted by 1. | ||||||
|  |      * Moreover, the frequency calculation also shows that we must subtract 3 to the total SCL */ | ||||||
|     //scl period |     //scl period | ||||||
|     hw->scl_low_period.period = bus_cfg->scl_low - 1; |     hw->scl_low_period.period = bus_cfg->scl_low - 1 - 2; | ||||||
|     hw->scl_high_period.period = bus_cfg->scl_high; |     hw->scl_high_period.period = bus_cfg->scl_high - 1 - 1; | ||||||
|     //sda sample |     //sda sample | ||||||
|     hw->sda_hold.time = bus_cfg->sda_hold; |     hw->sda_hold.time = bus_cfg->sda_hold - 1; | ||||||
|     hw->sda_sample.time = bus_cfg->sda_sample; |     hw->sda_sample.time = bus_cfg->sda_sample - 1; | ||||||
|     //setup |     //setup | ||||||
|     hw->scl_rstart_setup.time = bus_cfg->setup; |     hw->scl_rstart_setup.time = bus_cfg->setup - 1; | ||||||
|     hw->scl_stop_setup.time = bus_cfg->setup; |     hw->scl_stop_setup.time = bus_cfg->setup - 1; | ||||||
|     //hold |     //hold | ||||||
|     hw->scl_start_hold.time = bus_cfg->hold - 1; |     hw->scl_start_hold.time = bus_cfg->hold - 1; | ||||||
|     hw->scl_stop_hold.time = bus_cfg->hold; |     hw->scl_stop_hold.time = bus_cfg->hold - 1; | ||||||
|     hw->timeout.time_out_value = bus_cfg->tout; |     hw->timeout.time_out_value = bus_cfg->tout; | ||||||
|     hw->timeout.time_out_en = 1; |     hw->timeout.time_out_en = 1; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zim Kalinowski
					Zim Kalinowski