shurne
Posts: 4
Joined: Thu Feb 02, 2017 7:21 pm

Issues with CM, 2x Cameras, and a PiTFT [Solved]

Tue Feb 07, 2017 11:39 pm

I'm working on a product that currently makes use of the CM1 module. The device has a custom module host board (custom IO board) with various peripherals attached. In particular, the device makes use of 2 Pi No-IR Cameras and a PiTFT 3.5" Resistive touchscreen display from Adafruit.

The device performs some fairly significant image processing, and so with the recent release of the CM3 module, we're pretty excited to upgrade the device. So far, the upgrade has been going well and most of our peripherals and software components work fine, but we've run into a pretty significant snag with the touchscreen interface, so I'm hoping someone here might have some ideas.

The issue in a nutshell:
Without a dt-blob.bin in /boot, the touchscreen seems to work completely fine, without any failures.
With the dt-blob.bin file in place (required for the camera interfaces), the touchscreen exhibits some very odd behavior:

To get the touchscreen to work with a dt-blob.bin file in place (to support the camera interfaces), I have to perform a sequence of steps with the dt-blob file:
  1. Modify the .dts file such that the pins connected to the PiTFT device are set to have a function of "spi0" (which I believe is an invalid function?)
  2. Compile the dts file, updating the dt-blob.bin file in /boot.
  3. Reboot
    - At this point, the camera interface appears to be broken (vcgencmd get_camera outputs Supported: 2 Connected: 0), but the touchscreen interface starts to work (tested using evtest)
  4. Revert the modifications such that the file uses all valid pin functions, such as setting the pins for the PiTFT to have a function of "spi"
  5. Compile the dts file, updating the dt-blob.bin file in /boot.
  6. Reboot
    - At this point, both camera interfaces are detected and work fine, and the touchscreen also seems to work fine, as tested with evtest.
Finally, once I get the touchscreen working, it continues to work across reboot cycles unless I power off the device and completely remove power. I then have to repeat the above steps before the touchscreen will start talking again.

I originally suspected a possible hardware compatibility issue, but as a test, I loaded a CM1 module with the latest software (that we were bringing up on the CM3 module), and see the exact same behavior. Additionally, the current/previous software we have in place on the CM1 appears to work fine. So, that suggests to me that this is likely some sort of software issue, probably with a kernel driver or other low-level software component.

Some additional information I can provide:
  • The previous software image that works on the CM1 device uses a build of Raspbian Jessie Lite from Adafruit with a kernel version of 4.1.14+. This image from Adafruit includes the various kernel modules and device tree overlays required to support the PiTFT devices.
  • The current software image we are trying to bring up on the CM3 device (and also tested on the CM1), is the official Raspbian Jessie Lite image from 2017-01-11 with a kernel version of 4.4.45-v7+. It looks like the various kernel modules and device tree overlays are now included in this official build.
  • The touchscreen makes use of the stmpe-ts touchscreen driver.
  • The PiTFT device requires the pitft35-resistive device tree overlay.
  • The PiTFT display itself works just fine. It's only the touchscreen device that exhibits issues.
  • Even in the latest kernel, it does look like Adafruit has some slight modifications to the stmpe-ts driver (see https://github.com/adafruit/adafruit-ra ... stmpe-ts.c). Thinking this might be what I need to solve the problem, I have already tried rebuilding the kernel with these modifications and loading that onto the device. However, that has not solved the problem, and I see the exact same behavior even with these modifications included.
  • We do have a slightly adjusted configuration for the 2 cameras. Instead of having the CAM0 LED and CAM0 SHUTDOWN signals on GPIO pins 2 and 3, we have them on pins 5 and 6 and our dt-blob.dts file reflects this.
  • To rule out an issue with that particular display, I have tried a 2nd PiTFT display with the same results.
  • The exact behavior I see when the touchscreen does not work is no output is generated by evtest when I tap the touchscreen display.
Anyone have any ideas for what could possibly be the problem here? Anything we should look into as next steps for debugging?
Last edited by shurne on Thu Feb 16, 2017 3:11 pm, edited 1 time in total.

shurne
Posts: 4
Joined: Thu Feb 02, 2017 7:21 pm

Re: Issues with CM, 2x Cameras, and a PiTFT

Wed Feb 15, 2017 11:35 pm

Based on viewtopic.php?p=1114617#p1114617 and the other replies in that thread, it looks like there may be some issues with the CM3 device tree sections? Is it possible that the behavior I'm seeing is caused by these same issues?

It seems like, depending on my device-tree setup (dt-blob file), I either get the cameras to work or I get the touchscreen interface to work, but I can't get both to work at boot from a clean power on.

Edit: Note that I did already try adding the various pin_defines mention in that post, but it doesn't seem to solve the problems I'm seeing.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 9069
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Issues with CM, 2x Cameras, and a PiTFT

Thu Feb 16, 2017 7:33 am

Please post your Dt-blob.bin.dts in code tags or to Dropbox and we can have a look. There may be a pitft in the office - I'll ask.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

shurne
Posts: 4
Joined: Thu Feb 02, 2017 7:21 pm

Re: Issues with CM, 2x Cameras, and a PiTFT

Thu Feb 16, 2017 1:19 pm

Here's my .dts file:

Code: Select all

/dts-v1/;

/ {
  videocore {

    pins_cm {

      pin_config {

        pin@default {
          polarity = "active_high";
          termination = "pull_down";
          startup_state = "inactive";
          function = "input";
        }; // pin

        // BANK 0 - USER GPIO //
        pin@p0  { function = "input";   termination = "pull_up";    }; // GPU WILL USE THIS PIN FOR CAM0 I2C0 SDA
        pin@p1  { function = "input";   termination = "pull_up";    }; // GPU WILL USE THIS PIN FOR CAM0 I2C0 SCL
        pin@p2  { function = "i2c1";    termination = "pull_up";    }; // I2C1 SDA1 - ACCELEROMETER & RTC
        pin@p3  { function = "i2c1";    termination = "pull_up";    }; // I2C1 SCL1 - ACCELEROMETER & RTC
        pin@p4  { function = "input";   termination = "pull_up";    }; // POWER SWITCH INPUT/OUTPUT PIN
        pin@p5  { function = "output";  termination = "no_pulling"; }; // GPU WILL USE THIS PIN FOR CAM0 LED
        pin@p6  { function = "output";  termination = "no_pulling"; }; // GPU WILL USE THIS PIN FOR CAM0 SHUTDOWN
        pin@p7  { function = "spi";     termination = "pull_up";    }; // PI TFT DISPLAY - SPI0 CE1
        pin@p8  { function = "spi";     termination = "pull_up";    }; // PI TFT DISPLAY - SPI0 CE0
        pin@p9  { function = "spi";     termination = "pull_down";  }; // PI TFT DISPLAY - SPI0 MISO
        pin@p10 { function = "spi";     termination = "pull_down";  }; // PI TFT DISPLAY - SPI0 MOSI
        pin@p11 { function = "spi";     termination = "pull_down";  }; // PI TFT DISPLAY - SPI0 SCLK
        pin@p12 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p13 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
///////////////////////////////////////////
// TO ENABLE UART0 UNCOMMENT THESE 2 LINES:
//       pin@p14 { function = "uart0";   termination = "no_pulling"; }; // UART0 TX
//       pin@p15 { function = "uart0";   termination = "pull_up";    }; // UART0 RX
// AND COMMENT OUT/REMOVE THESE 2 LINES:
        pin@p14 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p15 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
///////////////////////////////////////////
        pin@p16 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p17 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p18 { function = "input";   termination = "pull_down";  }; // PI TFT DISPLAY - BACKLIGHT ON/OFF
        pin@p19 { function = "output";  termination = "pull_down";  }; // LED
        pin@p20 { function = "output";  termination = "pull_down";  }; // LED
        pin@p21 { function = "output";  termination = "pull_down";  }; // LED
        pin@p22 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p23 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p24 { function = "input";   termination = "pull_down";  }; // PI TFT DISPLAY
        pin@p25 { function = "input";   termination = "pull_down";  }; // PI TFT DISPLAY
        pin@p26 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p27 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE

        // BANK 1 - USER GPIO//
        pin@p28 { function = "input";   termination = "pull_up";    }; // GPU WILL USE THIS PIN FOR CAM1 I2C0 SDA
        pin@p29 { function = "input";   termination = "pull_up";    }; // GPU WILL USE THIS PIN FOR CAM1 I2C0 SCL
        pin@p30 { function = "output";  termination = "no_pulling"; }; // GPU WILL USE THIS PIN FOR CAM1 LED
        pin@p31 { function = "output";  termination = "no_pulling"; }; // GPU WILL USE THIS PIN FOR CAM1 SHUTDOWN
        pin@p32 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p33 { function = "input";   termination = "pull_down";  }; // CHARGER INTL
        pin@p34 { function = "output";  termination = "pull_down";  startup_state = "active"; }; // USB1_H, default to external port
        pin@p35 { function = "input";   termination = "pull_up";    }; // LOW BATTERY ALARM
        pin@p36 { function = "input";   termination = "pull_down";  }; // MOTION INT1
        pin@p37 { function = "input";   termination = "pull_down";  }; // MOTION INT2
        pin@p38 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p39 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p40 { function = "pwm";     termination = "pull_down";  }; // BUZZER - PWM0
        pin@p41 { function = "pwm";     termination = "pull_down";  }; // BUZZER - PWM1
        pin@p42 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p43 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p44 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE WAS INPUT NO PULL
        pin@p45 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE WAS INPUT NO PULL

        // BANK 2 - DON'T TOUCH UNLESS YOU KNOW WHAT YOU'RE DOING //
        pin@p46 { function = "input";   termination = "no_pulling"; drive_strength_mA = <8>; polarity = "active_high"; }; // HPD_N
        pin@p47 { function = "output";  termination = "no_pulling"; drive_strength_mA = <8>; polarity = "active_low"; startup_state = "active"; }; // STATUS LED / EMMC_DISABLE_N CONTROL
        pin@p48 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD CLK
        pin@p49 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD CMD
        pin@p50 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD D0
        pin@p51 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD D1
        pin@p52 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD D2
        pin@p53 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD D3

      }; // pin_config

      pin_defines {
          pin_define@HDMI_CONTROL_ATTACHED { type = "internal"; number = <46>; }; // HPD_N on GPIO46

          pin_define@NUM_CAMERAS { type = "internal"; number = <2>; };

          pin_define@CAMERA_0_LED { type = "internal"; number = <5>; };
          pin_define@CAMERA_0_SHUTDOWN { type = "internal"; number = <6>; };
          pin_define@CAMERA_0_UNICAM_PORT { type = "internal"; number = <1>; };
          pin_define@CAMERA_0_I2C_PORT { type = "internal"; number = <0>; };
          pin_define@CAMERA_0_SDA_PIN { type = "internal"; number = <0>; };
          pin_define@CAMERA_0_SCL_PIN { type = "internal"; number = <1>; };

          pin_define@CAMERA_1_LED { type = "internal"; number = <30>; };
          pin_define@CAMERA_1_SHUTDOWN { type = "internal"; number = <31>; };
          pin_define@CAMERA_1_UNICAM_PORT { type = "internal"; number = <0>; };
          pin_define@CAMERA_1_I2C_PORT { type = "internal"; number = <0>; };
          pin_define@CAMERA_1_SDA_PIN { type = "internal"; number = <28>; };
          pin_define@CAMERA_1_SCL_PIN { type = "internal"; number = <29>; };

      }; // pin_defines

    }; // pins_cm


    pins_cm3 {

      pin_config {

        pin@default {
          polarity = "active_high";
          termination = "pull_down";
          startup_state = "inactive";
          function = "input";
        }; // pin

        // BANK 0 - USER GPIO //
        pin@p0  { function = "input";   termination = "pull_up";    }; // GPU WILL USE THIS PIN FOR CAMERA 0 I2C0 SDA
        pin@p1  { function = "input";   termination = "pull_up";    }; // GPU WILL USE THIS PIN FOR CAMERA 0 I2C0 SCL
        pin@p2  { function = "i2c1";    termination = "pull_up";    }; // I2C1 SDA1 - ACCELEROMETER & RTC
        pin@p3  { function = "i2c1";    termination = "pull_up";    }; // I2C1 SCL1 - ACCELEROMETER & RTC
        pin@p4  { function = "input";   termination = "pull_up";    }; // POWER SWITCH INPUT/OUTPUT PIN
        pin@p5  { function = "output";  termination = "no_pulling"; }; // GPU WILL USE THIS PIN FOR CAM0 LED
        pin@p6  { function = "output";  termination = "no_pulling"; }; // GPU WILL USE THIS PIN FOR CAM0 SHUTDOWN
        pin@p7  { function = "spi";     termination = "pull_up";    }; // PI TFT DISPLAY - SPI0 CE1
        pin@p8  { function = "spi";     termination = "pull_up";    }; // PI TFT DISPLAY - SPI0 CE0
        pin@p9  { function = "spi";     termination = "pull_down";  }; // PI TFT DISPLAY - SPI0 MISO
        pin@p10 { function = "spi";     termination = "pull_down";  }; // PI TFT DISPLAY - SPI0 MOSI
        pin@p11 { function = "spi";     termination = "pull_down";  }; // PI TFT DISPLAY - SPI0 SCLK
        pin@p12 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p13 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
///////////////////////////////////////////
// TO ENABLE UART0 UNCOMMENT THESE 2 LINES:
//       pin@p14 { function = "uart0";   termination = "no_pulling"; }; // UART0 TX
//       pin@p15 { function = "uart0";   termination = "pull_up";    }; // UART0 RX
// AND COMMENT OUT/REMOVE THESE 2 LINES:
        pin@p14 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p15 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
///////////////////////////////////////////
        pin@p16 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p17 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p18 { function = "input";   termination = "pull_down";  }; // PI TFT DISPLAY - BACKLIGHT ON/OFF
        pin@p19 { function = "output";  termination = "pull_down";  }; // LED
        pin@p20 { function = "output";  termination = "pull_down";  }; // LED
        pin@p21 { function = "output";  termination = "pull_down";  }; // LED
        pin@p22 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p23 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p24 { function = "input";   termination = "pull_down";  }; // PI TFT DISPLAY
        pin@p25 { function = "input";   termination = "pull_down";  }; // PI TFT DISPLAY
        pin@p26 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p27 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE

        // BANK 1 - USER GPIO//
        pin@p28 { function = "input";   termination = "pull_up";    }; // GPU WILL USE THIS PIN FOR CAMERA 1 I2C0 SDA
        pin@p29 { function = "input";   termination = "pull_up";    }; // GPU WILL USE THIS PIN FOR CAMERA 1 I2C0 SCL
        pin@p30 { function = "output";  termination = "no_pulling"; }; // GPU WILL USE THIS PIN FOR CAMERA 1 LED
        pin@p31 { function = "output";  termination = "no_pulling"; }; // GPU WILL USE THIS PIN FOR CAMERA 1 SHUTDOWN
        pin@p32 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p33 { function = "input";   termination = "pull_down";  }; // CHARGER INTL
        pin@p34 { function = "output";  termination = "pull_down";  startup_state = "active"; }; // USB1_H, default to external port
        pin@p35 { function = "input";   termination = "pull_up";    }; // LOW BATTERY ALARM
        pin@p36 { function = "input";   termination = "pull_down";  }; // MOTION INT1
        pin@p37 { function = "input";   termination = "pull_down";  }; // MOTION INT2
        pin@p38 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p39 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p40 { function = "pwm";     termination = "pull_down";  }; // BUZZER - PWM0
        pin@p41 { function = "pwm";     termination = "pull_down";  }; // BUZZER - PWM1
        pin@p42 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p43 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE
        pin@p44 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE WAS INPUT NO PULL
        pin@p45 { function = "input";   termination = "pull_down";  }; // DEFAULT STATE WAS INPUT NO PULL

        // BANK 2 - DON'T TOUCH UNLESS YOU KNOW WHAT YOU'RE DOING //
        pin@p46 { function = "input";   termination = "no_pulling"; drive_strength_mA = <8>; polarity = "active_high"; }; // HPD_N
        pin@p47 { function = "output";  termination = "no_pulling"; drive_strength_mA = <8>; polarity = "active_low"; startup_state = "active"; }; // STATUS LED / EMMC_DISABLE_N CONTROL
        pin@p48 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD CLK
        pin@p49 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD CMD
        pin@p50 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD D0
        pin@p51 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD D1
        pin@p52 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD D2
        pin@p53 { function = "sdcard";  termination = "pull_up";    drive_strength_mA = <8>; }; // SD D3

      }; // pin_config

      pin_defines {
          pin_define@NUM_CAMERAS { type = "internal"; number = <2>; };

          pin_define@CAMERA_0_LED { type = "internal"; number = <5>; };
          pin_define@CAMERA_0_SHUTDOWN { type = "internal"; number = <6>; };
          pin_define@CAMERA_0_UNICAM_PORT { type = "internal"; number = <1>; };
          pin_define@CAMERA_0_I2C_PORT { type = "internal"; number = <0>; };
          pin_define@CAMERA_0_SDA_PIN { type = "internal"; number = <0>; };
          pin_define@CAMERA_0_SCL_PIN { type = "internal"; number = <1>; };

          pin_define@CAMERA_1_LED { type = "internal"; number = <30>; };
          pin_define@CAMERA_1_SHUTDOWN { type = "internal"; number = <31>; };
          pin_define@CAMERA_1_UNICAM_PORT { type = "internal"; number = <0>; };
          pin_define@CAMERA_1_I2C_PORT { type = "internal"; number = <0>; };
          pin_define@CAMERA_1_SDA_PIN { type = "internal"; number = <28>; };
          pin_define@CAMERA_1_SCL_PIN { type = "internal"; number = <29>; };
      }; // pin_defines


    }; // pins_cm3

  };

};
If there's anything else you need, such as some dmesg output, other application output, etc, please let me know and I'll post that ASAP. Thanks!!

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 9069
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Issues with CM, 2x Cameras, and a PiTFT

Thu Feb 16, 2017 1:39 pm

I've just finished updating the blobs. New versions at https://github.com/6by9/documentation/t ... putemodule, and there's a pull request open to get the main docs repo updated.
With the bits that were missing I was seeing kernel lockups/crashes on boot. Those all seem to be fixed now.

AIUI SPI should just be configured by the dtoverlay line in config.txt - you shouldn't need to alter dt-blob.bin directly.
Using dt-blob.bin has the potential for you to map multiple pins to the same function, and that causes grief. I'd suggest leaving them as inputs in dt-blob.bin, and then check with raspi-gpio that they have been mapped correctly after all the overlays are loaded.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

shurne
Posts: 4
Joined: Thu Feb 02, 2017 7:21 pm

Re: Issues with CM, 2x Cameras, and a PiTFT

Thu Feb 16, 2017 2:46 pm

Success!!

With your recent dt-blob-dualcam.dts and some slight modifications (moving CAM0 LED and SHUTDOWN pins), both cameras and the touchscreen interface work consistently!

Thanks for the help!

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 9069
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Issues with CM, 2x Cameras, and a PiTFT

Thu Feb 16, 2017 2:54 pm

Good news.

I didn't bother working through the detail of what was going to go wrong with each of those blobs, but missing "EMMC_ENABLE was going to mean no activity LED, and missing SMPS_[SDA|SCL] meant no talking to the SMPS. Both of those seemed useful things to have in there, and the SMPS lines are also used for talking to the GPIO expander, so that was going to be lacking configuration too.
The SMPS and GPIO expander didn't apply to the CM1, so it was probably just a copy/paste done without thinking through all the details :(
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

Return to “Compute Module”