zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.87k stars 6.62k forks source link

sam_v71_xult -> I2C_1 hang during scanning i2c devices #33910

Closed santa-kr closed 3 years ago

santa-kr commented 3 years ago

I am beginner to Zephyr rtos. I have one SAM V71 Xplained Ultra board and testing sample program on it. Also, I have a new board using SAMV71N21 chip we made. I modified sam_v71_quant-common.dtsi to use I2C_1 bus on new board.

After booting os, I tried scan i2c devices on I2C bus. I got the log like below. the result of I2C_0 scan is OK but I2C_1 scan is halted during scanning. When I looked the i2c signal via oscilloscope, clock and data of I2C_0 is OK. But I2C_1 signal is abnormal, clock is always low and data line is always high. I don't know the correct reason.

let me know how to debug I2C_1 bus.

thans. SI J. KIM

[logging text] [00:00:00.000,000] i2c_sam_twihs: Device I2C_1 initialized [00:00:00.000,000] i2c_sam_twihs: Device I2C_0 initialized

uart:~$ i2c scan I2C_0 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- 0 devices found on I2C_0

uart:~$ i2c scan I2C_1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: .................... Hanged ...............

[sam_v71_quant-common.dtsi] /*

/ { aliases { i2c-0 = &twihs0; i2c-1 = &twihs1; led0 = &yellow_led0; led1 = &yellow_led1; led2 = &yellow_led2; };

chosen {
    zephyr,console = &uart0;
    zephyr,shell-uart = &uart0;
    zephyr,sram = &sram0;
    zephyr,flash = &flash0;
    zephyr,code-partition = &slot0_partition;
};

leds {
    compatible = "gpio-leds";
    yellow_led0: led_0 {
        gpios = <&piod 14 GPIO_ACTIVE_LOW>;
        label = "User LED 0";
    };
    yellow_led1: led_1 {
        gpios = <&piod 15 GPIO_ACTIVE_LOW>;
        label = "User LED 1";
    };
    yellow_led2: led_2 {
        gpios = <&pioa 15 GPIO_ACTIVE_LOW>;
        label = "User LED 2";
    };
};

    ext1_header: quant-pro-connector1 {
            compatible = "atmel-quant-pro-header";
            #gpio-cells = <2>;
            gpio-map-mask = <0xffffffff 0xffffffc0>;
            gpio-map-pass-thru = <0 0x3f>;          /*           Shared */
            gpio-map =      <0  0 &pioa 18 0>,      /* AFE0 AD7         */
                            <1  0 &pioa 19 0>,      /* AFE0 AD8         */
                            <2  0 &piob  0 0>,      /* PHY_RST          */
                            <3  0 &piob  1 0>,      /* PHY_LINK         */
                            <4  0 &pioa 17 0>,      /* PWMC1_H3         */
                            <5  0 &piod 10 0>,      /* ID_SET_8         */
                            <6  0 &piod 11 0>,      /* ID_SET_4         */
                            <7  0 &piod 12 0>,      /* ID_SET_2         */
                            <8  0 &piod 13 0>,      /* ID_SET_0         */
                            <9  0 &piod 16 0>,      /* VBUS_DET_H       */
                            <10 0 &piod 17 0>,      /* EN_H_VBUS        */
                            <11 0 &pioa 20 0>,      /* WKUP10           */
                            <12 0 &pioa 16 0>,      /* PHY_INT          */
                            <13 0 &piod 18 0>,      /* URXD4       EXT2 */
                            <14 0 &piod 19 0>,      /* UTXD4       EXT2 */
                            <15 0 &pioa  9 0>,      /* URXD0            */
                            <16 0 &pioa 10 0>;      /* UTXD0            */
                                                    /* GND              */
                                                    /* +3.3V            */
    };

    ext2_header: quant-pro-connector2 {
            compatible = "atmel-quant-pro-header";
            #gpio-cells = <2>;
            gpio-map-mask = <0xffffffff 0xffffffc0>;
            gpio-map-pass-thru = <0 0x3f>;          /*           Shared */
            gpio-map =      <0  0 &pioa 22 0>,      /* CAN_EN           */
                            <1  0 &pioa 21 0>,      /* AFE0 AD1         */
                            <2  0 &pioa  2 0>,      /* QCA_INT          */
                            <3  0 &pioa  5 0>,      /* RTC_RST          */
                            <4  0 &pioa  0 0>,      /* PWMC0_H0         */
                            <5  0 &pioa  1 0>,      /* PWMC0_L0         */
                            <6  0 &pioa 23 0>,      /* EN_TX485         */
                            <7  0 &piob  0 0>,      /* PHY_RESET        */
                            <8  0 &pioa  3 0>,      /* TWD0        EXT1 */
                            <9  0 &pioa  4 0>,      /* TWCK0       EXT1 */
                            <10 0 &piob  4 0>,      /* TWD1        EXT1 */
                            <11 0 &piob  5 0>,      /* TWCK1       EXT1 */
                            <12 0 &piod 25 0>,      /* URXD2            */
                            <13 0 &piod 26 0>,      /* UTXD2            */
                            <14 0 &piod 27 0>,      /* SPI0(NPCS3)      */
                            <15 0 &piod 21 0>,      /* SPI0(MOSI)  EXT1 */
                            <16 0 &piod 20 0>,      /* SPI0(MISO)  EXT1 */
                            <17 0 &piod 22 0>,      /* SPI0(SCK)   EXT1 */
                            <18 0 &piod 28 0>,      /* URXD3       EXT2 */
                            <19 0 &piod 30 0>;      /* UTXD3       EXT2 */
                                                    /* GND              */
                                                    /* +3.3V            */
    };

};

&cpu0 { clock-frequency = <300000000>; };

&afec0 { status = "okay"; };

&afec1 { status = "okay"; };

&twihs0 { status = "okay"; };

&twihs1 { status = "okay"; };

&spi0 { status = "okay";

pinctrl-0 = <&pd20b_spi0_miso
         &pd21b_spi0_mosi
         &pd22b_spi0_spck
         &pd27b_spi0_npcs3>;

cs-gpios = <&piod 27 GPIO_ACTIVE_LOW>;

};

&uart0 { status = "okay"; pinctrl-0 = <&pa9a_uart0_urxd0 &pa10a_uart0_utxd0>; current-speed = <115200>; };

&uart3 { status = "okay"; pinctrl-0 = <&pd28a_uart3_urxd3 &pd30a_uart3_utxd3>; current-speed = <115200>; };

&usart1 { status = "okay"; current-speed = <115200>; };

&wdt { status = "okay"; };

&usbhs { status = "okay"; };

&gmac { status = "okay"; };

&pwm0 { status = "okay"; };

&pioa { status = "okay"; };

&piob { status = "okay"; };

&piod { status = "okay"; };

&flash0 { partitions { compatible = "fixed-partitions";

address-cells = <1>;

    #size-cells = <1>;

    /*
     * The first half of sector 0 (64 kbytes)
     * is reserved for the bootloader
     */
    boot_partition: partition@0 {
        label = "mcuboot";
        reg = <0x0 0x00010000>;
        read-only;
    };

    /* From sector 1 to sector 7 (included): slot0 (896 kbytes) */
    slot0_partition: partition@20000 {
        label = "image-0";
        reg = <0x0020000 0x000e0000>;
    };

    /* From sector 8 to sector 14 (included): slot1 (896 kbytes) */
    slot1_partition: partition@100000 {
        label = "image-1";
        reg = <0x00100000 0x000e0000>;
    };

    /* Sector 15: scratch (128 kbytes) */
    scratch_partition: partition@1e0000 {
        label = "image-scratch";
        reg = <0x001e0000 0x00020000>;
    };
};

};

ext1_spi: &spi0 { };

ext1_i2c: &twihs0 { };

ext2_i2c: &twihs1 { };

ext0_serial: &uart0 { };

ext2_serial: &uart3 { };

ext2_spi: &spi0 { };

nandojve commented 3 years ago

At sam_v71_xult board the usart1 is used as console. The txd1 pin is shared with twd1 and you can't have both twihs1 and usart1 at same time. I think that is the issue.

You can test using a USB<->serial with any UART port. Try disable USART_SAM driver and enable UART_SAM. Look at same70-pinctrl for pin definitions. It will be easy to check possible conflicts.

Don't forget to enable the UART port like below. The pinctrl-0 is mandatory for any UART driver.

&uart3 {
    status = "okay";

    pinctrl-0 = <&pd28a_uart3_urxd3 &pd30a_uart3_utxd3>;
    current-speed = <115200>;
};
github-actions[bot] commented 3 years ago

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

santa-kr commented 3 years ago

I have still problem.. I don't use usart1 port as debug as if you can see the above device tree. We have changed it to uart0.

I have another problem when I am using i2c data transfer. When reading 256 bytes of EEPROM data with i2c, data is not normally received in i2c Read Buffer.

Data 0x7F is stored in the last position of EEPROM. So I expect 0x7F when I read last position. But I could not receive the same data. I got 0x00.. Why?

[The below is my code for testing EEPROM read & write]

define EEPROM_AT24MAC402_SIZE 256 // Bytes, 2K (256 * 8 = 2048 bits)

uint8_t eeprom_buffer[EEPROM_AT24MAC402_SIZE];

void eeprom_AT24MAC402_read() { int ret;
memset(eeprom_buffer, 0x00,EEPROM_AT24MAC402_SIZE);

// Read EEPROM
ret = i2c_read(i2c_dev, &eeprom_buffer, EEPROM_AT24MAC402_SIZE, EEPROM_I2C_ADDR);            

if (ret!=0) {
    printk("[%s]i2c_read EPROR=%d\n", __func__, ret);
    return;
}
else {
    //printk("[%s]i2c_read OK=%d\n", __func__, ret);
}   
printk("[%s] EEPROM Data[255] = 0x%x\n", __func__, eeprom_buffer[256]);

}

printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x00

So I retried several times of data reading process. I got the below results.

for( int i = 0; i< 50; i++)
    printk("[%s] EEPROM Data[255] = 0x%x\n", __func__, eeprom_buffer[256]);

printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x00 printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x00 printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x00 printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x00 printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x00 printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x00 printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x00 printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x7f printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x7f printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x7f printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x7f printk("[%s] EEPROM Data[255] = 0x%x\n", func, eeprom_buffer[256]) => 0x7f

I got the delayed result. Why?

Please let me know how to solve this kind of problem. Thanks.

SI J. KIM

delayed_result

nandojve commented 3 years ago

Maybe, I expressed myself wrong:

&usart1 {
status = "disable";
};

Let me know if problem continue.

mnkp commented 3 years ago

As @nandojve has mentioned you shouldn't enable resources that you're not using. If USART1 is enabled in DTS the driver instance will be initialized during system boot and USART1 pins connected to the module. In your case however, luckily, twihs1 driver instance is initialized after usart1 (assuming you didn't change the default initialization priorities) so the pins get connected to twihs1.

I believe the problem lays elsewhere, though is indeed caused by pin ownership issue. The signal TWCK1, clock line of TWIHS1 instance, is connected to pin PB5 which is part of the ARM Cortex debug interface. Fortunately, it's TRACESWO signal and if you're not using SWO it can be safely disabled. You can try the following patch

diff --git a/soc/arm/atmel_sam/samv71/soc_config.c b/soc/arm/atmel_sam/samv71/soc_config.c
index 72cafdc4aa..7a91ff7f59 100644
--- a/soc/arm/atmel_sam/samv71/soc_config.c
+++ b/soc/arm/atmel_sam/samv71/soc_config.c
@@ -53,6 +53,9 @@ static int atmel_samv71_config(const struct device *dev)
        while (!((PMC->PMC_SR) & PMC_SR_PCKRDY3)) {
                ;
        }
+#else
+       /* Disable TDO/TRACESWO function on PB5 pin */
+       MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO5;
 #endif

        return 0;
mnkp commented 3 years ago

I have another problem when I am using i2c data transfer.

As for the second issue

printk("[%s] EEPROM Data[255] = 0x%x\n", __func__, eeprom_buffer[256]);

In the above code you're accessing out of bound array index. The array has 256 elements but you are accessing the 257-th element.

santa-kr commented 3 years ago

Thanks for your fast reply.

1) First issue : I2C-1 Operation I tried patch process as you mentioned to disable the function of SWO like below, MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO5;

This is OK.
I can access the remote device via i2c-1 interface.

Thanks.

2) Second issue : when using i2c, data is not normally received. I am sorry for disturbing your valuable time. I wrote mistyped message at the previous comment. The array index is mistaken.

 eeprom_buffer[256] => eeprom_buffer[255]

 I am still receiving the delayed result.
 To access normal data I expect at the same position I did read operation during several times.
 Please refer the attached picture.

delay_i2c

 After taking this kind of result, I think delay time will is required during i2c operation.
 So, after inserting wait function I retried.
 I got the following result.

wait_i2c

 When I took much more delay time, I got the expected data from eeprom device.

 I can't understand why this kind of result is generated.
 Please  give me take good solution.

Thanks.
SI J. KIM