11/*
2- * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+ * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 */
1313
1414namespace esp_expander {
1515
16+ void Base::Config::convertPartialToFull (void )
17+ {
18+ ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
19+
20+ if (isHostConfigValid () && std::holds_alternative<HostPartialConfig>(host.value ())) {
21+ #if ESP_UTILS_CONF_LOG_LEVEL == ESP_UTILS_LOG_LEVEL_DEBUG
22+ printHostConfig ();
23+ #endif // ESP_UTILS_LOG_LEVEL_DEBUG
24+ auto &config = std::get<HostPartialConfig>(host.value ());
25+ host = HostFullConfig{
26+ .mode = I2C_MODE_MASTER,
27+ .sda_io_num = config.sda_io_num ,
28+ .scl_io_num = config.scl_io_num ,
29+ .sda_pullup_en = config.sda_pullup_en ,
30+ .scl_pullup_en = config.scl_pullup_en ,
31+ .master = {
32+ .clk_speed = static_cast <uint32_t >(config.clk_speed ),
33+ },
34+ .clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL,
35+ };
36+ }
37+
38+ ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS ();
39+ }
40+
41+ void Base::Config::printHostConfig (void ) const
42+ {
43+ ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
44+
45+ if (!isHostConfigValid ()) {
46+ ESP_UTILS_LOGI (" \n\t {Host config}[skipped]" );
47+ goto end;
48+ }
49+
50+ if (std::holds_alternative<HostFullConfig>(host.value ())) {
51+ auto &config = std::get<HostFullConfig>(host.value ());
52+ ESP_UTILS_LOGI (
53+ " \n\t {Host config}[full]\n "
54+ " \t\t -> [host_id]: %d\n "
55+ " \t\t -> [mode]: %d\n "
56+ " \t\t -> [sda_io_num]: %d\n "
57+ " \t\t -> [scl_io_num]: %d\n "
58+ " \t\t -> [sda_pullup_en]: %d\n "
59+ " \t\t -> [scl_pullup_en]: %d\n "
60+ " \t\t -> [master.clk_speed]: %d\n "
61+ " \t\t -> [clk_flags]: %d"
62+ , host_id
63+ , config.mode
64+ , config.sda_io_num
65+ , config.scl_io_num
66+ , config.sda_pullup_en
67+ , config.scl_pullup_en
68+ , config.master .clk_speed
69+ , config.clk_flags
70+ );
71+ } else {
72+ auto &config = std::get<HostPartialConfig>(host.value ());
73+ ESP_UTILS_LOGI (
74+ " \n\t {Host config}[partial]\n "
75+ " \t\t -> [host_id]: %d\n "
76+ " \t\t -> [sda_io_num]: %d\n "
77+ " \t\t -> [scl_io_num]: %d\n "
78+ " \t\t -> [sda_pullup_en]: %d\n "
79+ " \t\t -> [scl_pullup_en]: %d\n "
80+ " \t\t -> [clk_speed]: %d"
81+ , host_id
82+ , config.sda_io_num
83+ , config.scl_io_num
84+ , config.sda_pullup_en
85+ , config.scl_pullup_en
86+ , config.clk_speed
87+ );
88+ }
89+
90+ end:
91+ ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS ();
92+ }
93+
94+ void Base::Config::printDeviceConfig (void ) const
95+ {
96+ ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
97+
98+ ESP_UTILS_LOGI (
99+ " \n\t {Device config}[partial]\n "
100+ " \t\t -> [host_id]: %d\n "
101+ " \t\t -> [address]: 0x%02X"
102+ , host_id
103+ , device.address
104+ );
105+
106+ ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS ();
107+ }
108+
109+ bool Base::configHostSkipInit (bool skip_init)
110+ {
111+ ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
112+
113+ ESP_UTILS_CHECK_FALSE_RETURN (!isOverState (State::INIT), false , " Should be called before `init()`" );
114+
115+ _is_host_skip_init = skip_init;
116+
117+ ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS ();
118+
119+ return true ;
120+ }
121+
16122bool Base::init (void )
17123{
18124 ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
19125
20- ESP_UTILS_CHECK_FALSE_RETURN (!checkIsInit (), false , " Already initialized" );
126+ ESP_UTILS_CHECK_FALSE_RETURN (!isOverState (State::INIT), false , " Already initialized" );
127+
128+ // Convert the partial configuration to full configuration
129+ _config.convertPartialToFull ();
130+ #if ESP_UTILS_CONF_LOG_LEVEL == ESP_UTILS_LOG_LEVEL_DEBUG
131+ _config.printHostConfig ();
132+ _config.printDeviceConfig ();
133+ #endif // ESP_UTILS_LOG_LEVEL_DEBUG
21134
22- if (!checkIsSkipInitHost ()) {
23- ESP_UTILS_CHECK_ERROR_RETURN (i2c_param_config (getHostID (), &_host_config), false , " I2C param config failed" );
135+ // Initialize the I2C host if not skipped
136+ if (!isHostSkipInit ()) {
137+ i2c_port_t host_id = static_cast <i2c_port_t >(getConfig ().host_id );
24138 ESP_UTILS_CHECK_ERROR_RETURN (
25- i2c_driver_install ( getHostID (), _host_config. mode , 0 , 0 , 0 ) , false , " I2C driver install failed"
139+ i2c_param_config (host_id, getHostFullConfig ()) , false , " I2C param config failed"
26140 );
27- ESP_UTILS_LOGI (" Init I2C host(%d)" , _host_id);
141+ ESP_UTILS_CHECK_ERROR_RETURN (
142+ i2c_driver_install (host_id, getHostFullConfig ()->mode , 0 , 0 , 0 ), false , " I2C driver install failed"
143+ );
144+ ESP_UTILS_LOGD (" Init I2C host(%d)" , static_cast <int >(host_id));
28145 }
29- _flags.is_init = true ;
146+
147+ setState (State::INIT);
30148
31149 ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS ();
32150
@@ -37,7 +155,7 @@ bool Base::reset(void)
37155{
38156 ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
39157
40- ESP_UTILS_CHECK_FALSE_RETURN (checkIsBegun ( ), false , " Not begun" );
158+ ESP_UTILS_CHECK_FALSE_RETURN (isOverState (State::BEGIN ), false , " Not begun" );
41159
42160 ESP_UTILS_CHECK_ERROR_RETURN (esp_io_expander_reset (device_handle), false , " Reset failed" );
43161
@@ -50,20 +168,20 @@ bool Base::del(void)
50168{
51169 ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
52170
53- if (checkIsBegun () ) {
171+ if (device_handle != nullptr ) {
54172 ESP_UTILS_CHECK_ERROR_RETURN (esp_io_expander_del (device_handle), false , " Delete failed" );
55173 device_handle = nullptr ;
56- ESP_UTILS_LOGD (" Delete IO expander( @%p) " , device_handle);
174+ ESP_UTILS_LOGD (" Delete @%p" , device_handle);
57175 }
58176
59- if (checkIsInit ()) {
60- if (!checkIsSkipInitHost ()) {
61- ESP_UTILS_CHECK_ERROR_RETURN (i2c_driver_delete (getHostID ()), false , " I2C driver delete failed" );
62- ESP_UTILS_LOGI (" Delete I2C host(%d)" , _host_id);
63- }
64- _flags.is_init = false ;
177+ if (isOverState (State::INIT) && !isHostSkipInit ()) {
178+ i2c_port_t host_id = static_cast <i2c_port_t >(getConfig ().host_id );
179+ ESP_UTILS_CHECK_ERROR_RETURN (i2c_driver_delete (host_id), false , " I2C driver delete failed" );
180+ ESP_UTILS_LOGD (" Delete I2C host(%d)" , static_cast <int >(host_id));
65181 }
66182
183+ setState (State::DEINIT);
184+
67185 ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS ();
68186
69187 return true ;
@@ -73,7 +191,7 @@ bool Base::pinMode(uint8_t pin, uint8_t mode)
73191{
74192 ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
75193
76- ESP_UTILS_CHECK_FALSE_RETURN (checkIsBegun ( ), false , " Not begun" );
194+ ESP_UTILS_CHECK_FALSE_RETURN (isOverState (State::BEGIN ), false , " Not begun" );
77195
78196 ESP_UTILS_LOGD (" Param: pin(%d), mode(%d)" , pin, mode);
79197 ESP_UTILS_CHECK_FALSE_RETURN (IS_VALID_PIN (pin), false , " Invalid pin" );
@@ -91,7 +209,7 @@ bool Base::digitalWrite(uint8_t pin, uint8_t value)
91209{
92210 ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
93211
94- ESP_UTILS_CHECK_FALSE_RETURN (checkIsBegun ( ), false , " Not begun" );
212+ ESP_UTILS_CHECK_FALSE_RETURN (isOverState (State::BEGIN ), false , " Not begun" );
95213
96214 ESP_UTILS_LOGD (" Param: pin(%d), value(%d)" , pin, value);
97215 ESP_UTILS_CHECK_FALSE_RETURN (IS_VALID_PIN (pin), false , " Invalid pin" );
@@ -109,7 +227,7 @@ int Base::digitalRead(uint8_t pin)
109227{
110228 ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
111229
112- ESP_UTILS_CHECK_FALSE_RETURN (checkIsBegun ( ), false , " Not begun" );
230+ ESP_UTILS_CHECK_FALSE_RETURN (isOverState (State::BEGIN ), false , " Not begun" );
113231
114232 ESP_UTILS_LOGD (" Param: pin(%d)" , pin);
115233 ESP_UTILS_CHECK_FALSE_RETURN (IS_VALID_PIN (pin), -1 , " Invalid pin" );
@@ -128,7 +246,7 @@ bool Base::multiPinMode(uint32_t pin_mask, uint8_t mode)
128246{
129247 ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
130248
131- ESP_UTILS_CHECK_FALSE_RETURN (checkIsBegun ( ), false , " Not begun" );
249+ ESP_UTILS_CHECK_FALSE_RETURN (isOverState (State::BEGIN ), false , " Not begun" );
132250
133251 ESP_UTILS_LOGD (" Param: pin_mask(%0x), mode(%d)" , pin_mask, mode);
134252 ESP_UTILS_CHECK_FALSE_RETURN ((mode == INPUT) || (mode == OUTPUT), false , " Invalid mode" );
@@ -145,7 +263,7 @@ bool Base::multiDigitalWrite(uint32_t pin_mask, uint8_t value)
145263{
146264 ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
147265
148- ESP_UTILS_CHECK_FALSE_RETURN (checkIsBegun ( ), false , " Not begun" );
266+ ESP_UTILS_CHECK_FALSE_RETURN (isOverState (State::BEGIN ), false , " Not begun" );
149267
150268 ESP_UTILS_LOGD (" Param: pin_mask(%0x), value(%d)" , pin_mask, value);
151269
@@ -160,7 +278,7 @@ int64_t Base::multiDigitalRead(uint32_t pin_mask)
160278{
161279 ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
162280
163- ESP_UTILS_CHECK_FALSE_RETURN (checkIsBegun ( ), false , " Not begun" );
281+ ESP_UTILS_CHECK_FALSE_RETURN (isOverState (State::BEGIN ), false , " Not begun" );
164282
165283 ESP_UTILS_LOGD (" Param: pin_mask(%0x)" , pin_mask);
166284
@@ -172,11 +290,11 @@ int64_t Base::multiDigitalRead(uint32_t pin_mask)
172290 return level;
173291}
174292
175- bool Base::printStatus (void )
293+ bool Base::printStatus (void ) const
176294{
177295 ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS ();
178296
179- ESP_UTILS_CHECK_FALSE_RETURN (checkIsBegun ( ), false , " Not begun" );
297+ ESP_UTILS_CHECK_FALSE_RETURN (isOverState (State::BEGIN ), false , " Not begun" );
180298
181299 ESP_UTILS_CHECK_ERROR_RETURN (esp_io_expander_print_state (device_handle), false , " Print state failed" );
182300
@@ -185,4 +303,13 @@ bool Base::printStatus(void)
185303 return true ;
186304}
187305
306+ Base::HostFullConfig *Base::getHostFullConfig ()
307+ {
308+ if (std::holds_alternative<HostPartialConfig>(_config.host .value ())) {
309+ _config.convertPartialToFull ();
310+ }
311+
312+ return &std::get<HostFullConfig>(_config.host .value ());
313+ }
314+
188315} // namespace esp_expander
0 commit comments