@@ -1375,16 +1375,18 @@ static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num)
1375
1375
//Check whether read or write buffer in cmd_link is internal.
1376
1376
static bool is_cmd_link_buffer_internal (const i2c_cmd_link_t * link )
1377
1377
{
1378
- const i2c_cmd_link_t * cmd_link = link ;
1379
- while (cmd_link != NULL ) {
1380
- if (cmd_link -> cmd .hw_cmd .op_code == I2C_LL_CMD_WRITE || cmd_link -> cmd .hw_cmd .op_code == I2C_LL_CMD_READ ) {
1381
- if (cmd_link -> cmd .data != NULL && !esp_ptr_internal (cmd_link -> cmd .data )) {
1382
- return false;
1383
- }
1384
- }
1385
- cmd_link = cmd_link -> next ;
1378
+ bool is_internal = true;
1379
+ for (const i2c_cmd_link_t * cmd_link = link ;
1380
+ cmd_link != NULL && is_internal ;
1381
+ cmd_link = cmd_link -> next )
1382
+ {
1383
+ /* A command node has a valid pointer if it is a read command or a write command with more than one byte. */
1384
+ const bool data_pointer = (cmd_link -> cmd .hw_cmd .op_code == I2C_LL_CMD_WRITE && !i2c_cmd_is_single_byte (& cmd_link -> cmd ))
1385
+ || cmd_link -> cmd .hw_cmd .op_code == I2C_LL_CMD_READ ;
1386
+ /* Check if the (non-NULL) pointer points to internal memory. */
1387
+ is_internal &= !data_pointer || cmd_link -> cmd .data == NULL || esp_ptr_internal (cmd_link -> cmd .data );
1386
1388
}
1387
- return true ;
1389
+ return is_internal ;
1388
1390
}
1389
1391
#endif
1390
1392
@@ -1398,11 +1400,10 @@ esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle,
1398
1400
#if CONFIG_SPIRAM_USE_MALLOC
1399
1401
//If the i2c read or write buffer is not in internal RAM, we will return ESP_FAIL
1400
1402
//to avoid the ISR handler function crashing when the cache is disabled.
1401
- if ((p_i2c_obj [i2c_num ]-> intr_alloc_flags & ESP_INTR_FLAG_IRAM )) {
1402
- if (!is_cmd_link_buffer_internal (((const i2c_cmd_desc_t * )cmd_handle )-> head ) ) {
1403
- ESP_LOGE (I2C_TAG , I2C_PSRAM_BUFFER_WARN_STR );
1404
- return ESP_ERR_INVALID_ARG ;
1405
- }
1403
+ if ( (p_i2c_obj [i2c_num ]-> intr_alloc_flags & ESP_INTR_FLAG_IRAM ) &&
1404
+ !is_cmd_link_buffer_internal (((const i2c_cmd_desc_t * )cmd_handle )-> head ) ) {
1405
+ ESP_LOGE (I2C_TAG , I2C_PSRAM_BUFFER_WARN_STR );
1406
+ return ESP_ERR_INVALID_ARG ;
1406
1407
}
1407
1408
#endif
1408
1409
// Sometimes when the FSM get stuck, the ACK_ERR interrupt will occur endlessly until we reset the FSM and clear bus.
0 commit comments