Hello, I've been working with a custom board that uses the MIMXRT1062DVJ6B for a while. Recently, as I wanted to start working on the OTA, I've tried reducing the code size by changing the gcc flag from -O0 to -Os. When I do this, the i2c communication breaks: when writing data to the slave, I get a timeout error when sending the STOP (LPI2C_MasterStop returns 909 which matches kStatus_LPI2C_Timeout). I got the same results with -O1.
The code I use for the i2c is pretty much identical to the master polling_b2b example from the SDK. The only differences are that I use LPI2C_MasterStart instead of LPI2C_MasterRepeatedStart when reading from a slave and that I included a mutex to lock access to the bus.
Is there anything specific I should look at in this case ?
Environment:
- arm-none-eabi-gcc 10.3.1 20210824
- SDK 2.13.0 built for linux
My flags:
SET(CMAKE_C_FLAGS_FLEXSPI_NOR_DEBUG " \
${CMAKE_C_FLAGS_FLEXSPI_NOR_DEBUG} \
-include ${ProjDirPath}/../app_config.h \
-DXIP_EXTERNAL_FLASH=1 \
-DXIP_BOOT_HEADER_ENABLE=1 \
-DXIP_BOOT_HEADER_DCD_ENABLE=1 \
-DSKIP_SYSCLK_INIT\
-DDEBUG \
-DCPU_MIMXRT1062DVL6B \
-DSDIO_ENABLED=1 \
-DMMC_ENABLED=1 \
-DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 \
-DAPPL_USE_STANDARD_IO \
-DGATT_CLIENT \
-DGATT_DB \
-DFSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ=0 \
-DSDK_COMPONENT_INTEGRATION=1 \
-DgNvStorageIncluded_d=1 \
-DgNvTableKeptInRam_d=1 \
-DIOT_WIFI_ENABLE_SAVE_NETWORK=1 \
-DFSL_OSA_MAIN_FUNC_ENABLE=0 \
-DHAL_UART_ADAPTER_FIFO=1 \
-DFSL_FEATURE_FLASH_PAGE_SIZE_BYTES=4096 \
-DgMemManagerLight=0 \
-DUSE_RTOS=1 \
-DOSA_USED=1 \
-DPH_OSAL_FREERTOS \
-DPRINTF_ADVANCED_ENABLE=1 \
-DSDK_OS_FREE_RTOS \
-DFSL_OSA_TASK_ENABLE=1 \
-DDEBUG_CONSOLE_TRANSFER_NON_BLOCKING \
-DCFG_BLE \
-DLPUART_RING_BUFFER_SIZE=1024U \
-DNVM_NO_COMPONNET=1 \
-DCPU_MIMXRT1062DVL6B_cm7 \
-DHAL_UART_DMA_ENABLE=1 \
-DHAL_AUDIO_DMA_INIT_ENABLE=0 \
-DLFS_NO_INTRINSICS=1 \
-DLFS_NO_ERROR=1 \
-DSERIAL_PORT_TYPE_UART=1 \
-DLOG_ENABLE_ASYNC_MODE=1 \
-DLOG_MAX_ARGUMENT_COUNT=10 \
-DLOG_ENABLE_OVERWRITE=0 \
-DCONFIG_ARM=1 \
-DDATA_SECTION_IS_CACHEABLE=0 \
-DMFLASH_FILE_BASEADDR=7340032 \
-DMCUXPRESSO_SDK \
-g \
-Os \
-mcpu=cortex-m7 \
-Wall \
-mthumb \
-MMD \
-MP \
-fomit-frame-pointer \
-Wno-unused-function \
-fno-common \
-ffunction-sections \
-fdata-sections \
-ffreestanding \
-fno-builtin \
-mapcs \
-std=gnu99 \
${FPU} \
${DEBUG_CONSOLE_CONFIG} \
")
Solved! Go to Solution.
At some point, the issue started appearing without enabling code optimization.
I managed to solve it by changing I2C_RETRY_TIMES from 1000 to 30000 (in fsl_lpi2c.h and fsl_flexio_i2c_master.h).
My understanding is that one of the slaves (ST1633i) was, sometimes, too slow to answer. Once a MasterReceive timed out, all transactions on the bus were failing.
The issue is not solved with code optimization enabled but I am now closing this topic as this seem to be related to hardware timings.
NB: I never try other SDK versions as CMake is used differently on newer versions and the transition seemed like it would have taken too long.
At some point, the issue started appearing without enabling code optimization.
I managed to solve it by changing I2C_RETRY_TIMES from 1000 to 30000 (in fsl_lpi2c.h and fsl_flexio_i2c_master.h).
My understanding is that one of the slaves (ST1633i) was, sometimes, too slow to answer. Once a MasterReceive timed out, all transactions on the bus were failing.
The issue is not solved with code optimization enabled but I am now closing this topic as this seem to be related to hardware timings.
NB: I never try other SDK versions as CMake is used differently on newer versions and the transition seemed like it would have taken too long.
Hi,
Could you please try with the latest SDK version and tell me if the problem still occurs?
Regards,
Daniel.
Hi, thank you for your answer.
Could you confirm that there is no automated way to switch SDK version ? I've noticed that the new version does not use CMake in the same way. I have written a lot of code on that version so it would be a lot of work to manually change version and retest everything.
Regards,
Nicolas
Do you mean a way to switch between SDK versions without interfering with the application? I'm afraid there is no way to do this, since some code from the SDK like drivers, can change between versions and might cause conflicts with the application.
If you are not able to test the latest SDK version, is there a way I can try to replicate this in an EVK? Could you please give the SDK example name and the steps to try to replicate it?
Regards,
Daniel.
Yes, that is what I meant. I may be able to switch SDK version but that would probably take some time as i've had to modify the edgefast stack a bit and our board uses a lot of features.
Since I only have one evkbmimxrt1060, I cannot test the evkbmimxrt1060/driver_examples/lpi2c/polling_b2b/master example on which I based my code.
So I've tried playing around with the other examples that use I2C and when trying the evkbmimxrt1060/demo_apps/sai, I noticed something :
- When using the armgcc version for Linux, the I2C get stuck on the first write with a timeout error (kStatus_LPI2C_Timeout). This occurs during the CODEC init for the WM8960 (in the fsl_wm8960.c file, in WM8960_Init, line 178 when trying to reset).
- When using the exact same example from MCUXpresso IDE from the same SDK version, I don't have this issue
The only change I made to the code is to disable the SD card (by setting BOARD_HAS_SDCARD to 0 in board.h).
Hi @nsi,
I'm sorry for the late response.
I tried the lpi2c_polling_b2b example with the -0s optimization, and seems to be working on my side. I didn't find any problem with the transfer.
This makes me think that the problem might be related to your application. I'd recommend you to check your code and try to see if there is any wrong use of variables, registers or any other thing that can cause a bad optimization.
Regards,
Daniel.
I understand.
Let me try lpi2c_polling_b2b example on my side. I will try the latest release, and I'll compile it with GCC and MCUXpresso in Windows.
I'll let you know my findings.
Regards,
Daniel.