i.MX Processors Knowledge Base

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX Processors Knowledge Base

Discussions

Sort by:
Sometimes we need to use an SPI bus to communicate with sensors or another device. Unfortunately, by default on iMX8MN-EVK, we have the ECSPI2 disabled on our BSP.   We can use that peripheral on Linux enabling it in the device tree.   To enable the ECSPI2 on the device tree we have to add the next on imx8mn-evk.dtsi:     status = "okay"; }; +&ecspi2 { + #address-cells = <1>; + #size-cells = <0>; + fsl,spi-num-chipselects = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi2 &pinctrl_ecspi2_cs>; + cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; + status = "okay"; + + spidev0: spi@0 { + reg = <0>; + compatible = "rohm,dh2228fv"; + spi-max-frequency = <500000>; + }; +}; + &fec1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec1>;   On iomux node:   + pinctrl_ecspi2: ecspi2grp { + fsl,pins = < + MX8MN_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82 + MX8MN_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82 + MX8MN_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82 + >; + }; + + pinctrl_ecspi2_cs: ecspi2cs { + fsl,pins = < + MX8MN_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x40000 + >; + }; + pinctrl_ir_recv: ir-recv { fsl,pins = < MX8MN_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x4f    after modifying and compiling the device tree you can see the device active like this:     Connection:   Test: spidev_test -D /dev/spidev1.0 -v       You can use the devsheell of yocto to make the changes:   https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/How-to-use-Devshell-to-compile-device-tree-files/ta-p/1727428
View full article
  For some applications, we need to reduce the CPU Frequency, but if you are not familiar with our BSP or our devices probably you need some help to do some configurations.   In this post, I will share the configuration to set up lower frequencies (100MHz, 200MHz, 400Mhz, 600MHz, 800MHz, and 1000MHz) on iMX8MP, iMX8MN, and iMX8MM.   Note: Works on Kernel 6.1.xx (not tested on oldest BSP)   1- We have to modify the PLL driver to set the proper parameters to lower frequencies. The file to modify is "clk-pll14xx.c" adding the following lines:   https://github.com/nxp-imx/linux-imx/blob/770c5fe2c1d1529fae21b7043911cd50c6cf087e/drivers/clk/imx/clk-pll14xx.c#L57   static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { PLL_1416X_RATE(1800000000U, 225, 3, 0), PLL_1416X_RATE(1600000000U, 200, 3, 0), PLL_1416X_RATE(1500000000U, 375, 3, 1), PLL_1416X_RATE(1400000000U, 350, 3, 1), PLL_1416X_RATE(1200000000U, 300, 3, 1), PLL_1416X_RATE(1000000000U, 250, 3, 1), PLL_1416X_RATE(800000000U, 200, 3, 1), PLL_1416X_RATE(750000000U, 250, 2, 2), PLL_1416X_RATE(700000000U, 350, 3, 2), PLL_1416X_RATE(600000000U, 300, 3, 2), + PLL_1416X_RATE(400000000U, 200, 3, 2), + PLL_1416X_RATE(200000000U, 200, 3, 3), + PLL_1416X_RATE(100000000U, 200, 3, 4), };   2- Once the pll driver has been modified, only we have to add the values on the opp-table according to the device that you will use.   2.1- For iMX 8MP:   https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/arch/arm64/boot/dts/freescale/imx8mp.dtsi         a53_opp_table: opp-table { compatible = "operating-points-v2"; opp-shared; + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0x8a0>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0x8a0>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0x8a0>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0x8a0>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0x8a0>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0x8a0>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; opp-1200000000 { opp-hz = /bits/ 64 <1200000000>;   2.2 For iMX8MM:   https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/arch/arm64/boot/dts/freescale/imx8mm.dtsi     a53_opp_table: opp-table { compatible = "operating-points-v2"; opp-shared; + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xe>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xe>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xe>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xe>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xe>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xe>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; opp-1200000000 { opp-hz = /bits/ 64 <1200000000>;   2.3- For iMX8MN:   https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/arch/arm64/boot/dts/freescale/imx8mn.dtsi   compatible = "operating-points-v2"; opp-shared; + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xb00>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xb00>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xb00>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xb00>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xb00>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0xb00>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; opp-microvolt = <850000>;   After that, you should note the changes under Linux.   These commands return information about the system and the current settings.   • The kernel is pre-configured to support only certain frequencies. The list of frequencies currently supported can be obtained from: cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies   • To get the available scaling governors: cat /sys/devices/system/cpu/*/cpufreq/scaling_available_governors   • To check the current CPU frequency: cat /sys/devices/system/cpu/*/cpufreq/cpuinfo_cur_freq   The frequency is displayed depending on the governor set.   • To check the maximum frequency: cat /sys/devices/system/cpu/*/cpufreq/cpuinfo_max_freq   • To check the minimum frequency: cat /sys/devices/system/cpu/*/cpufreq/cpuinfo_min_freq   These commands set a constant CPU frequency:   • Use the maximum frequency: echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor   • Use the current frequency to be the constant frequency: echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor   • The following two commands set the scaling governor to a specified frequency, if that frequency is supported.   If the frequency is not supported, the closest supported frequency is used:   echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor echo <frequency> > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed    
View full article
Dynamic debug is designed to allow you to dynamically at runtime  enable/disable  kernel code to obtain additional kernel information. Currently, if ``CONFIG_DYNAMIC_DEBUG`` is set, then all ``pr_debug()``/``dev_dbg()`` and ``print_hex_dump_debug()``/``print_hex_dump_bytes()`` calls can be dynamically enabled per-callsite.    
View full article
Symptoms   Trying to initialize a repo, for example:  $repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-mickledore -m imx-6.1.36-2.1.0.xml we have the below log: File "/home/username/bin/repo", line 51 def print(self, *args, **kwargs): ^ SyntaxError: invalid syntax   Workaround (1)   The first workaround consist in change the python alternatives (caused when you have installed two or more python versions). NOTE: in my case, the python version that i want to change as first priority is python3.8 $sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1   Then we run: $sudo update-alternatives --config python    To verify if your python priority was changed successfully try: $python --version   You should see the version configured as priority number 1.     Workaround (2)   The workaround is very simple, only we need modify the repo file $ nano ~/bin/repo   and we will change the python interpreter in the first line (from python to python3): ORIGINAL FILE   EDITED FILE   After to do this change, repo will works fine again.     I hope this can helps to you!   Best regards.
View full article
  Environment i.MX8MP EVK, SDK2.15   The default rpmsg buffer size in SDK is 512Bytes(16 Bytes header + 496Bytes payload). This knowledge base will try to change the default buffer size in rpmsg framework. Steps:   1.Modify rpmsg payload size in SDK PATH: SDK\evkmimx8mp_rpmsg_lite_str_echo_rtos_imxcm7\rpmsg_config.h     //! RL_BUFFER_PAYLOAD_SIZE //! //! Size of the buffer payload, it must be equal to (240, 496, 1008, ...) //! [2^n - 16]. Ensure the same value is defined on both sides of rpmsg //! communication. The default value is 496U. #define RL_BUFFER_PAYLOAD_SIZE (1008)     2. Modify buffer size in rpmsg linux framework and buffer pool in dts. PATH: drivers/rpmsg/virtio_rpmsg_bus.c            arch/arm64/boot/dts/freescale/imx8mp-evk-rpmsg.dts   Test steps:   Modify the send buffer in imx_rpmsg_tty.c     #define MSG "hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world! hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world! hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!"       Modify buffer limitation in SDK PATH: evkmimx8mp_rpmsg_lite_str_echo_rtos_imxcm7\main_remote.c     /* Globals */ static char app_buf[1024]; /* Each RPMSG buffer can carry less than 512 payload */       Terminal output We can see that the MAX buffer size received in SDK is not limited to 512Bytes     Nameservice sent, ready for incoming messages... Get Message From Master Side : "hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world! hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world! hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!hello world!" [len : 674]       If we use a larger buffer like 2022 Bytes, we will see error when driver load.     [ 2673.447384] imx_rpmsg_tty virtio0.rpmsg-virtual-tty-channel-1.-1.30: message is too big (2022) [ 2673.456271] imx_rpmsg_tty virtio0.rpmsg-virtual-tty-channel-1.-1.30: rpmsg_send failed: -90 [ 2673.465556] imx_rpmsg_tty virtio0.rpmsg-virtual-tty-channel-1.-1.30: rpmsg_dev_probe: failed: -90 [ 2673.474496] imx_rpmsg_tty: probe of virtio0.rpmsg-virtual-tty-channel-1.-1.30 failed with error -90          
View full article
In the IMX8MM SDK unfortunately we cannot find any example about of use a GPIO as an input with interrupt.  To use a GPIO as input with interrupt we need to keep in mind how the GPIO IRQs works in the ARM Cortex M4.   We can find in Table 7-2 (CM4 Interrupt Summary) of IMX8MMRM (IMX8MM Reference Manual) the GPIOs IRQs are divided by two parts:     Combined interrupt indication for GPIOn signal 0 throughout 15  Combined interrupt indication for GPIOn signal 16 throughout 31    This basically means, the pines of GPIOn from 0 to 15 are handled by Combined interrupt indication for GPIOn signal 0 throughout 15 and the pines from 16 to 31 are handled by Combined interrupt indication for GPIOn signal 16 throughout 31.    In SDK we can find these definitions in:  <SDK root>/devices/MIMX8MM6/MIMX8MM6_cm4.h (Remember this is for IM8MM SDK)    In this example I will use GPIO5_IO12 (ECSPI2_MISO) as Input with IRQ and GPIO5_IO11 (ECSPI_MOSI) as Output of IMX8MM-EVK. I will connect the Output to the Input and will see the behavior of the IRQ in Rising and Falling edge.    For this example I will connect ECSPI2_MOSI (GPIO5_IO11) to ECSPI_MISO (GPIO5_IO12):   See the below definitions:   #define IN_GPIO   GPIO5  This define the GPIO base of the IN pin  #define IN_GPIO_PIN  12u  This define the pin number (for in)  #define IN_IRQ  GPIO5_Combined_0_15_IRQn  This define the IRQ number (72 in this case)  #define GPIO_IRQ_HANDLER  GPIO5_Combined_0_15_IRQHandler  This is a "pointer" to function that will handle the interrupt  #define IN_NAME  "IN GPIO5_IO12"  This is only a name or description for the pin    See below definitions:    #define OUT_GPIO  GPIO5  This is the GPIO base of OUT pin  #define OUT_GPIO_PIN  11u  This define the pin number (for out)  #define OUT_NAME  "OUT GPIO5_IO11"  This is only a name or description for the pin      Now the below section is the IRQ handler (which was defined before)😞   The GPIO_ClearPinsInterruptFlags(IN_GPIO, 1u << IN_GPIO_PIN); refers to GPIOx_ISR register:      For this example, the IRQ Handler will print "IRQ detected ............" in each interrupt.    We will create two different GPIOs config, one for Output and other one for Input with IRQ Falling edge:    Then configure the GPIOs and IRQ:     EnableIRQ refers to enable the 72 IRQ.   GPIO_PortEnableInterrupts refers to GPIOx_IMR: Finally, the example put the out GPIO5_IO11 in High state and then in low state many. First the IRQ is configured as Falling edge, then as Rising edge.     I will attach the complete source file.    To compile it you can use ARMGCC toolchain directly, but I like to use VSCode with MCUXpresso integration.  Once, when you have your .bin file (in my case igpio_led_output.bin) you can load to board with UUU tool: In your Linux machine: sudo uuu -b fat_write igpio_led_output.bin mmc 2:1 gpio.bin In U-boot board: u-boot=> fastboot 0   Then, when the .bin file was loaded, you can load to the CORTEX M4 in U-boot whit: u-boot=> fatload mmc 2:1 ${loadaddr} gpio.bin 7076 bytes read in 14 ms (493.2 KiB/s) u-boot=> cp.b 0x80000000 0x7e0000 0x10000 u-boot=> bootaux 0x7e0000 ## No elf image ar address 0x007e0000 ## Starting auxiliary core stack = 0x20020000, pc = 0x1FFE02CD... u-boot=>   NOTE: You can load the binary to cortex m4 with Custom bootscripts for practicity.   Once the binary loaded in M4 core you should see in seria terminal this logs (Remember GPIO5_IO11 and GPIO5_IO12 must be connected to get the same logs):    And the logs when you disconnect the GPIO5_IO11 and GPIO5_IO12 in execution time:  🔴Disconnection (Red color) 🔵Reconnection (Blue color)   I hope this can helps.     Best regards!    Salas. 
View full article
some customers doesn't have any issue on old bsp, but have bring up issue on new 6.1 bsp, this article is about this and how to fix this
View full article
Hello there. Here is a good way to use U-boot in an efficient way with custom scripts. The bootscript is an script that is automatically executed when the boot loader starts, and before the OS auto boot process. The bootscript allows the user to execute a set of predefined U-Boot commands automatically before proceeding with normal OS boot. This is especially useful for production environments and targets which don’t have an available serial port for showing the U-Boot monitor. This information can be find in U-Boot Reference Manual.   I will take the example load a binary file in CORTEX M4 of IMX8MM-EVK. In my case, I have the binary file in MMC 2:1 called gpio.bin and I will skip those steps because that is not the goal.   First, you need the u-boot-tools installed in your Linux machine: sudo apt install u-boot-tools   That package provide to us the tool mkimage to convert a text file (.src, .txt) file to a bootscript file for U-Boot.   Now, create your custom script, in this case a simple script for load binary file in Cortex M4: nano mycustomscript.scr  and write your U-Boot commands: fatload mmc 2:1 0x80000000 gpio.bin cp.b 0x80000000 0x7e0000 0x10000 bootaux 0x7e0000   Now we can convert the text file to bootscript with mkimage. Syntax: mkimage -T script -n "Bootscript" -C none -d <input_file> <output_file> mkimage -T script -n "Bootscript" -C none -d mycustomscript.scr LCM4-bootscript   This will create a file called LCM4-bootscript (Or as your called it).   A way to load this bootscript file to U-Boot is using the UUU tool, in U-Boot set the device in fastboot with command: u-boot=> fastboot 0 Then in linux with the board connected through USB to PC run the command: sudo uuu -b fat_write LCM4-bootscript mmc 2:1 LCM4-bootscript   Now we have our bootscript in U-Boot in MMC 2:1.   Finally, we can run the bootscript in U-Boot: u-boot=> load mmc 2:1 ${loadaddr} LCM4-bootscript 158 bytes read in 2 ms (77.1 KiB/s) u-boot=> source ${loadaddr} ## Executing script at 40400000 6656 bytes read in 5 ms (1.3 MiB/s) ## No elf image at address 0x007e0000 ## Starting auxiliary core stack = 0x20020000, pc = 0x1FFE02CD...   And the Cortex M4 booted successfully:    I hope this can helps to you.   Best regards.   Salas.  
View full article
Symptoms   On i.MX8MP, when inputting a 80% duty, 0.4V-1.8V, 3KHz square wave, we observed that the system may hang. We also tested i.MX8MN and i.MX8MM and observed the same phenomenon. In i.MX8MN RM, there's a note in GPC chapter:     We believe that the issue described in this note exists not only in the iMX8MN, but also in the iMX8MP and iMX8MM. Meanwhile, there is not only a problem with power down in this issue, but also a problem with wait mode. Diagnosis   In debugging, we find that avoiding accessing LPCR_A53_AD register in imx_set_cluster_powerdown can fix the issue. So we think that due to frequently power up/down of cores, cores have chances failed to power up. When the IRQ behavior become more complex, because the IRQ is an async event, it will come in any time. if the wait mode is enabled, in some conner case, the GPC internal LPM mode state machine will run into problem, then lead to system failure. Solution   1. A workaround patch that bypass the wait mode setting during the cpuidle.. See the patch attached. 2. Will add the Note about "SCU power down should not be enabled in wait mode" to i.MX8MP and i.MX8MM RM. 3. Will try to identify this issue into errta document, ticket TKT0632147.
View full article
This is a simple document for recording some known-how and tips for building up the Windows 10 IoT development environment for i.MX platform. It can only be used as a complement for official document in BSP package (Guide/Release Note/etc.). Applicable for: Windows 10 IoT, i.MX BSP v1.4.1 (date to Nov/2023) Please refer to the PDF attached.
View full article
Information about the transition from the NXP Demo Experience to GoPoint for i.MX Application Processors.
View full article
How to use UART4 on iMX8M from Linux User Space   The UART4 on iMX8MM-EVK and iMX8MN-EVK are thinking of debugging the M core which is not usable on Linux user space by default on pre-compiled images.   To use the UART4 on Linux user space you have to do the next modifications on the device tree and atf to assign that peripheral to Linux User Space     https://github.com/nxp-imx/imx-atf/blob/lf_v2.6/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c     iMX8MN-EVK   imx8mn_bl31_setup.c   https://github.com/nxp-imx/imx-atf/blob/lf_v2.6/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c   /* Master domain assignment */ RDC_MDAn(RDC_MDA_M7, DID1), /* peripherals domain permission */ - RDC_PDAPn(RDC_PDAP_UART4, D1R | D1W), + RDC_PDAPn(RDC_PDAP_UART4, D0R | D0W), RDC_PDAPn(RDC_PDAP_UART2, D0R | D0W), RDC_PDAPn(RDC_PDAP_RDC, D0R | D0W | D1R),       Device tree configurations for iMX8MN-EVK   iMX8MN-EVK.dtsi   https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi   &uart3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart3>; assigned-clocks = <&clk IMX8MN_CLK_UART3>; assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_80M>; uart-has-rtscts; status = "okay"; }; + &uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + assigned-clocks = <&clk IMX8MN_CLK_UART4>; + assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_80M>; + status = "okay"; + }; ********************** pinctrl_uart3: uart3grp { fsl,pins = < MX8MN_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x140 MX8MN_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x140 MX8MN_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x140 MX8MN_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x140 >; }; + pinctrl_uart4: uart4grp { + fsl,pins = < + MX8MN_IOMUXC_UART4_RXD_UART4_DCE_RX 0x140 + MX8MN_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 + >; + };   iMX8MM-EVK   https://github.com/nxp-imx/imx-atf/blob/lf_v2.6/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c   imx8mm_bl31_setup.c   /* Master domain assignment */ RDC_MDAn(RDC_MDA_M7, DID1), /* peripherals domain permission */ - RDC_PDAPn(RDC_PDAP_UART4, D1R | D1W), + RDC_PDAPn(RDC_PDAP_UART4, D0R | D0W), RDC_PDAPn(RDC_PDAP_UART2, D0R | D0W), RDC_PDAPn(RDC_PDAP_RDC, D0R | D0W | D1R),   Device tree configurations for iMX8MM-EVK   iMX8MM-EVK.dtsi   https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi   &uart3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart3>; assigned-clocks = <&clk IMX8MM_CLK_UART3>; assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>; uart-has-rtscts; status = "okay"; }; + &uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + assigned-clocks = <&clk IMX8MM_CLK_UART4>; + assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>; + status = "okay"; + }; ********************** pinctrl_uart3: uart3grp { fsl,pins = < MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x140 MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x140 MX8MM_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x140 MX8MM_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x140 >; }; + pinctrl_uart4: uart4grp { + fsl,pins = < + MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x140 + MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 + >; + };   iMX8MP-EVK   https://github.com/nxp-imx/imx-atf/blob/lf_v2.6/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c   imx8mp_bl31_setup.c   RDC_MDAn(RDC_MDA_M7, DID1), RDC_MDAn(RDC_MDA_LCDIF, DID2), RDC_MDAn(RDC_MDA_LCDIF2, DID2), RDC_MDAn(RDC_MDA_HDMI_TX, DID2), /* peripherals domain permission */ + RDC_PDAPn(RDC_PDAP_UART4, D0R | D0W), RDC_PDAPn(RDC_PDAP_UART2, D0R | D0W), RDC_PDAPn(RDC_PDAP_WDOG1, D0R | D0W), RDC_PDAPn(RDC_PDAP_RDC, D0R | D0W | D1R),   Device tree configurations for iMX8MP-EVK   iMX8MP-EVK.dts   https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/arch/arm64/boot/dts/freescale/imx8mp-evk.dts   &uart3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart3>; assigned-clocks = <&clk IMX8MP_CLK_UART3>; assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>; fsl,uart-has-rtscts; status = "okay"; }; + &uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + assigned-clocks = <&clk IMX8MP_CLK_UART4>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>; + status = "okay"; + }; ************************************ pinctrl_uart3: uart3grp { fsl,pins = < MX8MP_IOMUXC_ECSPI1_SCLK__UART3_DCE_RX 0x140 MX8MP_IOMUXC_ECSPI1_MOSI__UART3_DCE_TX 0x140 MX8MP_IOMUXC_ECSPI1_SS0__UART3_DCE_RTS 0x140 MX8MP_IOMUXC_ECSPI1_MISO__UART3_DCE_CTS 0x140 >; }; + pinctrl_uart4: uart4grp { + fsl,pins = < + MX8MP_IOMUXC_UART4_RXD__UART4_DCE_RX 0x140 + MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x140 + >; + };     After compiling the image with the changes previously shown, we obtained this result:      
View full article
BSP: L6.1.36 Some customer need use adb under usb ffs. The adb in Yocto can greatly improves development efficiency. This is a demo for enabling adb on Yocto.   Yocto local.conf IMAGE_INSTALL:append = "android-tools android-tools-adbd" PREFERRED_PROVIDER_android-tools-conf = "android-tools-conf-configfs"   Test script for launching adbd modprobe g_ffs idVendor=0x1fc9 idProduct=0x0146 iSerialNumber="ZhimingLiu" mkdir -p /dev/usb-ffs/adb mount -t functionfs adb /dev/usb-ffs/adb -o uid=2000,gid=2000 adbd &   Test on Windows: PS C:\Users\Administrator\Desktop\platform-tools> .\adb.exe devices List of devices attached ZhimingLiu device PS C:\Users\Administrator\Desktop\platform-tools> .\adb.exe shell sh-5.2# uname -a Linux imx8mp-lpddr4-evk 6.1.36+g04b05c5527e9 #1 SMP PREEMPT Fri Nov 24 04:46:22 UTC 2023 aarch64 GNU/Linux sh-5.2# ls config ffs t.sh test2.sh sh-5.2# cd / sh-5.2# ls bin dev home lost+found mnt proc run srv tmp usr boot etc lib media opt root sbin sys unit_tests var sh-5.2#
View full article
Platform: Demo images, i.MX8MPlus EVK   Some customer need test ffs gadget function on i.MX8MPlus EVK. Here is demo for ffs test, please connect EVK and Ubuntu PC before test.   Test script: #!/bin/sh # Setup the device (configfs) modprobe libcomposite mkdir -p config mount none config -t configfs cd config/usb_gadget/ mkdir g1 cd g1 echo 0x1fc9 >idVendor echo 0x0146 >idProduct mkdir strings/0x409 echo 12345 >strings/0x409/serialnumber echo "Signal 11" >strings/0x409/manufacturer echo "Test" >strings/0x409/product mkdir configs/c.1 mkdir configs/c.1/strings/0x409 echo "Config1" >configs/c.1/strings/0x409/configuration # Setup functionfs mkdir functions/ffs.usb0 ln -s functions/ffs.usb0 configs/c.1 cd ../../../ mkdir -p ffs mount usb0 ffs -t functionfs cd ffs ffs-test 64 & # from the Linux kernel, with mods! sleep 3 cd .. # Enable the USB device echo 38100000.usb > config/usb_gadget/g1/UDC   EVK log root@imx8mpevk:~# ./test2.sh [ 17.859597] file system registered ffs-test: dbg: ep0: writing descriptors (in v2 format) ffs-test: dbg: ep0: writing strings ffs-test: dbg: ep1: starting ffs-test: dbg: ep2: starting ffs-test: dbg: ep1: starts ffs-test: dbg: ep0: starts ffs-test: dbg: ep2: starts Event BIND Event ENABLE Ubuntu PC log: lzm@lzm-GL552VW:~$ lsusb -D /dev/bus/usb/001/008 Device: ID 1fc9:0146 NXP Semiconductors Test Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.10 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x1fc9 NXP Semiconductors idProduct 0x0146 bcdDevice 6.01 iManufacturer 1 Signal 11 iProduct 2 Test iSerial 3 12345 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0020 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 4 Config1 bmAttributes 0x80 (Bus Powered) MaxPower 2mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 5 Source/Sink Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 1 Binary Object Store Descriptor: bLength 5 bDescriptorType 15 wTotalLength 0x0016 bNumDeviceCaps 2 USB 2.0 Extension Device Capability: bLength 7 bDescriptorType 16 bDevCapabilityType 2 bmAttributes 0x0000010e BESL Link Power Management (LPM) Supported BESL value 256 us SuperSpeed USB Device Capability: bLength 10 bDescriptorType 16 bDevCapabilityType 3 bmAttributes 0x00 wSpeedsSupported 0x000f Device can operate at Low Speed (1Mbps) Device can operate at Full Speed (12Mbps) Device can operate at High Speed (480Mbps) Device can operate at SuperSpeed (5Gbps) bFunctionalitySupport 1 Lowest fully-functional device speed is Full Speed (12Mbps) bU1DevExitLat 0 micro seconds bU2DevExitLat 0 micro seconds Device Status: 0x0001 Self Powered  
View full article
Traditional non-matter devices cannot directly join the matter network. But Matter Bridge solves the problem. Matter bridge can join a Matter network as a Matter device and nonmatter devices need to be mapped to Matter network as a dynamic endpoint. In this way, other Matter devices can communicate with non-matter devices through dynamic endpoints. The Guide is a Matter Zigbee Bridge implement based on i.MX93 + K32W0.     Feature List • Matter over Ethernet • Matter over Wi-Fi • Register and Remove Zigbee Deivces • Connect Zigbee devices into Matter ecosystem seamlessly • Zigbee Devices o OnOff cluster o Temperature Sensor Cluster • Matter Actions o Start Zigbee Network o Zigbee Network Permit Join o Factory Reset • No limitation if migrating to other i.MX MPU like i.MX6ULL, i.MX8MP • OTBR and Zigbee bridge can be integrated into one single device
View full article
Usually, device tree source files are not a signal pure dts file. It could include dtsi, dts or C code heads .h files. Need C compiler finish the pre-compile to a pure dts file first. It is integrated inside the like Linux build system(Makefile, etc.). This document shows the original way to compile device tree. This document will show compile device tree under windows.    
View full article
test ov5640 with 480p, raw10 via ISP on imx8mp
View full article
  Platform & BSP :i.MX8MPlus, L6.1.36   The attachments enable the i.MX8MPlus pci function in uboot. lspci in Linux root@imx8mpevk:~# lspci -nn 00:00.0 PCI bridge [0604]: Synopsys, Inc. DWC_usb3 / PCIe bridge [16c3:abcd] (rev 01) 01:00.0 Ethernet controller [0200]: Marvell Technology Group Ltd. Device [1b4b:2b42] (rev 11) pci test results in uboot:  u-boot=> pci BusDevFun VendorId DeviceId Device Class Sub-Class _____________________________________________________________ 00.00.00 0x16c3 0xabcd Bridge device 0x04 u-boot=> pci bar 00.00.00 ID Base Size Width Type ---------------------------------------------------------- 0 0x0000000018000000 0x0000000000100000 32 MEM u-boot=> pci regions 00 Buses 00-01 # Bus start Phys start Size Flags 0 0x0000000000000000 0x000000001ff80000 0x0000000000010000 io 1 0x0000000018000000 0x0000000018000000 0x0000000007f00000 mem 2 0x0000000040000000 0x0000000040000000 0x0000000016000000 mem sysmem 3 0x0000000058000000 0x0000000058000000 0x00000000a8000000 mem sysmem 4 0x0000000100000000 0x0000000100000000 0x00000000c0000000 mem sysmem u-boot=> pci header 00.00.00 vendor ID = 0x16c3 device ID = 0xabcd command register ID = 0x0007 status register = 0x0010 revision ID = 0x01 class code = 0x06 (Bridge device) sub class code = 0x04 programming interface = 0x00 cache line = 0x08 latency time = 0x00 header type = 0x01 BIST = 0x00 base address 0 = 0x18000000 base address 1 = 0x00000000 primary bus number = 0x00 secondary bus number = 0x01 subordinate bus number = 0x01 secondary latency timer = 0x00 IO base = 0x10 IO limit = 0x00 secondary status = 0x0000 memory base = 0x1820 memory limit = 0x1810 prefetch memory base = 0xfff0 prefetch memory limit = 0x0000 prefetch memory base upper = 0x00000000 prefetch memory limit upper = 0x00000000 IO base upper 16 bits = 0x0000 IO limit upper 16 bits = 0x0000 expansion ROM base address = 0x18100000 interrupt line = 0xff interrupt pin = 0x01 bridge control = 0x0000
View full article
The configuration of DDR is very important. NXP provides a tool for configuring DDR for users of i.MX series products. Here are the details steps for it. Hope can do help for someone. 1\ The DDR part startup and initialization sequence of MX8MM:   The MX 8M series DDR tools include: DDR Register Programming Aid --->Configurate custom DDR initialization MSCALE DDR Tool(DDR Stress Test Tool) --->Test DDR initialization And DDR interface ---> Generate custom DDR initialization code for the u-boot SPL DDR RPA(RPA) is an Excel spreadsheet tool used to develop DDR initialization for specific DDR configurations (DDR device type, density, etc.) of users. RPA generates DDR initialization (in a separate Excel worksheet tab). Detailed explanations and introductions will be provided here. DDR stress testing tool is a software tool based Windows that initializes PHY and generates DDRC configuration Uboot source code to verify whether DDR initialization can be used for u-boot and OS startup. DDR stress testing script, this format is specifically used for DDR stress detection. First, copy the content from this worksheet tab, and then paste it into a text file, naming the document with the ". ds" file extension. Select this file when performing DDR stress testing. 2\i.MX8M series DDR tool work flow           Above is the DDR Tool flow for the i.MX8MM: DDR RPA Tool: Configure DDR parameters to generate DDR Stress Test script ". ds". DDR Sress Test Tool: Test DDR initialization and DDR interface, generate DDR initialization code for the u-boot SPL DDR driver. For the newest DDR RPA version as below:   https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/i-MX8MMini-m845S-DDR-Register-Programming-Aid-RPA/ta-p/1172443 In the above link, you can download the corresponding DDR configuration tools for i.MX8MM using different DDRs.   3\How to use this script to configure DDR parameters (1)Obtain the required DRAM data sheet from the DRAM supplier firstly. The DDR parameter configuration content will be completed in the "Register Configuration" worksheet tab.   (2)"Register Configuration",Update the device information table to include DRAM information and system usage. DDR RPA tool:  Register Configuration---->Device Information table   It should be filled out based on the datasheet and relevant hardware circuit design of the selected DDR chip. Specific users can refer to the manual for selecting DDR chips and their own hardware design. Take the i.MX 8M Mini LPDDR4 EVK board as example, it selects the Micron MT53D512M32D2DS-053 WT:D, we can go the Micron website to download the DDR’s datasheet and we can see bellow:   Density per channel (Gb)= Device density (Per Channel Per CS)=8Gb Number of ROW Addresses=R[15:0]=16 Number of Channels=2 (2 Channels i.MX8MM DDR is 32bit) Number of COLUMN Addresses=C[9:0]=10 Total DRAM density(Gb) Automatic calculation:Density per channel (Gb) * Number of Channels * Number of Chip Selects used  =8Gb * 2 * 1=16Gb=2GB Bus Width=M32=32bit: i.MX8MM DDR support 32bit Cycle Freq (MHz)=1500MHZ: The DDR controller clock of the i.MX8MM is set to 1500MHZ. The information filled in is shown in the table below:   (3)Browse through various shaded cells in the spreadsheet to update using data from the DRAM table (pay special attention to the "Legend" table to determine the meaning of different shaded cells; in many cases, these cells may not need to be updated). On the parameter filling page, we can also see the following table, with different colors indicating the need to modify and maintain the original parameters and the affected parameter information. On the register configuration tab, basically only the orange part of the color represents the bit segments that usually need to be updated, and the rest do not need to be modified or configured.   (4)Go to the BoardDataBusConfig tab, fill in the i.MX8MM data bus mapping to the memory device correctly. DDR RPA tool: BoardDataBusConfig ---->Configurate data bus bit   Users should pay special attention to ensuring that this worksheet is configured correctly, otherwise the LPDDR4 system may not function properly. The memory controller of i.MX8MM allows for BYTE internal swapping. For layout convenience, BYTE internal swapping is usually performed, so the BoardDataBusConfig column needs to be configured according to the actual schematic design. We can see the tab in the BoardDataBusConfig, user fill the i.MX8MM data bit connection to associated LPDDR4, the filling in of data bits here should be consistent with the order of our hardware design wiring, which means that if there are swapped data bits, the corresponding relationship must be filled in. Take the LPDDR4 connection to the i.MX8MM as example, the highest 8 bits on the channel B of the LPDDR4   connect to the side of DRAM_DQ00~DRAM_DQ07 of CPU, and the lowest 8 bits on the channel B of the LPDDR4 DRAM_DQ08~DRAM_DQ15 of CPU side,the lowest 8 bits on the channel A of the LPDDR4 connect to the DRAM_DQ16~DRAM_DQ23 of CPU side,the highest 8 bits on the channel A of the LPDDR4 connect to the DRAM_DQ24~DRAM_DQ31 of the CPU side. The i.MX8MM memory controller allows for BYTE internal swapping. For layout convenience, BYTE internal swapping is usually performed, and this needs to be filled in according to the actual wiring in the data bus.       (5)Generate the “.ds” file DDR RPA tool: DDR stress test file ----> “.ds”   Copy the content of the DDR stress test file into a text file and name it a. ds file. For subsequent DDR stress testing purposes.   4\Do the DDR Stress test and Generate the DDR Code The following is the workflow of the DDR tool for the MX8MM series:   Preparation Board: i.MX 8M Mini LPDDR4 EVK Software download: mscale_ddr_tool_v3.31_setup.exe(Install it) PC:Window10 PC file .ds file Hardware requirements for the board: (Please note that these interfaces are necessary when using our stress testing tools) Serial download mode USB OTG port Debug UART port 4.1 Hardware connection   SW1101set 1010xxxxxx go to Serial Download mode, connect the USB-OTG and UART to PC, USB OTG is used for serial download of binary files: UART is used to communicate with users. Note: It is recommended to connect the USB OTG directly to the host PC, rather than through the USB Hub. When power on the board,we can see HID-compliant vendor-defined device and USB Input Device:   UART port are COM3 and COM4:   4.2 Open MSCALEDDR_Tool. exe in administrator mode for DDR parameter calibration and pressure testing:   Select serial port Select Search in Debug UART and you can read that the other two serial ports COM3 and COM4 have been tried. Click on the Connect button. It should be noted that we have two serial ports, one for the A core and the other for the M core. Here, COM4 must be selected to load the script normally. COM4 is used for the A core. Select Target Select the MX8M-mini,speed of CPU chosse1200MHZ, DDR LPDDR4 size 2GB. Select .ds file, Load DDR Script: Copy the generate mx8mm_micron_lpddr4_2gb_2d_1500m_200m_50m_32bit_1cs_RPAv22.ds to the path of the DDR TOOL, then press the Download button. After the download is successful, there will be a print message indicating the successful download and the startup information of the board. We can see the CPU parameters and DDR configuration.   Pres Calibration: This step mainly involves executing the DDR initialization and calibration process. If there is a failure, it is necessary to analyze the DDR problem based on the printed information. If there is no problem, the following interface will appear.   (5) If there are no problems after calibration, perform a pressure test. Only perform this operation when the calibration is passed. Run the test on all frequency set points. If the DDR pressure test passes, you can see that the test has passed successfully. If there is an error, you should search for the problem with the DDR based on the error message.   (6) Generate u-boot timing After the stress test is successfully completed, clicking the Gen Code button will generate a file lpddr4_timing. c, and then the lpddr4_timing. C file can be copied to the u boot directory.     5\ Modifying and configuring DDR frequencies that are not supported by default         The above test is for the frequency point 1500MHZ that is supported by default in our tool. RPA provides default DRAM PLL settings (DRAM frequency) based on the default settings supported in u-boot. If the customer is not using the default supported frequency, in addition to updating the new frequency in RPA, the new DRAM PLL settings should also be manually updated in the u boot SPL. (1) Firstly, in the RPA script, "Clock Cycle Freq (MHz)" is set to the frequency we need (2) Then search for 'memory set 0x30360054' in the RPA DDR stress test file worksheet tab, with a default setting of 1500MHZ.   We can see the DRAM PLL register and bit settings:   For special frequencies, we have a calculation formula here: DDR_freq = [(24MHz x pll_main_div)/(pll_pre_div x 2^pll_post_div)] x 2 1500 = [(24 x 250) / (8 x 2^1)] x 2 Bellow are some special examples of the required configurations for various frequencies:     Finishing configuration, create a. ds test DDR script in the RPA script to specify the frequency of this configuration. (3)After creating a DDR script for the DDR stress testing tool, run the calibration and perform the DDR pressure test. Generating the lpddr4_timing.c, modify the required DDR rate parameters Manually. (4)Modify the DRAM PLL,DRAM_freq = DRAM_PLL x 2 in SPL,u-boot SPL DDR driver can will not automatically change DRAM PLL based on generated code. Therefore, users will need to manually modify the dram_pll_init  for the required DDR PLL parameter.
View full article
On this tutorial we will review the implementation of Flutter on the i.MX8MP using the Linux Desktop Image. Please find more information about Flutter using the following link: Flutter: Option to create GUIs for Embedded System... - NXP Community Requirements: Evaluation Kit for the i.MX 8M Plus Applications Processor. (i.MX 8M Plus Evaluation Kit | NXP Semiconductors) NXP Desktop Image for i.MX 8M Plus (GitHub - nxp-imx/meta-nxp-desktop at lf-6.1.1-1.0.0-langdale) Note: This tutorial is based on the NXP Desktop Image Ubuntu 22.04 with Yocto version 6.1.1 – Langdale. Steps: 1. First, run commands to update packages. $ sudo apt update $ sudo apt upgrade 2. Install Flutter for Linux using the following command. $ sudo snap install flutter --classic 3. Run the command to verify the correct installation. $ flutter doctor With this command you will find information about the installation. The important part for our purpose is the parameter "Linux toolchain - develop for Linux desktop". 4. Run the command “flutter create .” to create a flutter project, this framework will create different folders and files used to develop the application.  $ cd Documents $ mkdir flutter_hello $ cd flutter_hello $ flutter create .​ 5. Finally, you can run the “hello world” application using: $ flutter run Verify the program behavior incrementing the number displayed on the window.  
View full article