I`m using the Atmel KMS/DRM LCD driver to make it work a custom LCD (ST5651CB + ST5021CB) that I have at home from another project that I wanted to use. So, in order to speed up the development strategy I have divided the problem into several parts which are detailed below.
I have started by integrating the TSC2007 touchscreen driver with successful results, as voltage fluctuations are detected on the screen when it is touched, according to the normal operation after the inclusion of the relevant node in the corresponding i2c bus.
Subsequently, the node for the backlight has been included, making use of the pwm-backlight kernel driver. Also in this case it is fully functional, being able to activate or deactivate it on demand, as well as change the brightness levels (which have been previously defined with the values that oscillate in the interval [0,255]).
Once this has been done, the timing analysis of the panel in SYNC mode has been undertaken using the ST5651CB specification in which this is detailed, to populate the node that makes use of the simple-panel driver of the kernel (to which the backlight previously discussed has been assigned).
(root node)
....
/* Screen brightness */
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&hlcdc_pwm 0 50000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
status = "okay";
};
/* ST5651CB + ST5021CB TFT LCD */
panel: panel {
compatible = "simple-panel";
backlight = <&backlight>;
width-mm = <155>; /* Active area (W) 154.21 */
height-mm = <86>; /* Active area (H) 85.92 */
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
/* SYNC mode */
panel-timing {
clock-frequency = <65000000>; /* Panel clock (Hz) */
hactive = <1024>; /* Active frame width (px) */
vactive = <768>; /* Active frame height (px) */
hfront-porch = <160>; /* Horizontal front porch timing (px) */
hsync-len = <160>; /* HSD blanking (px) */
hback-porch = <160>; /* Horizontal back porch timing (px) */
vfront-porch = <15>; /* Vertical front porch timing (lines) */
vsync-len = <23>; /* VSD blanking (lines) */
vback-porch = <15>; /* Vertical back porch timing (lines) */
pixelclk-active = <0>; /* Data driving on falling edge */
hsync-active = <0>; /* Horizontal sync pulse (low) */
vsync-active = <0>; /* Vertical sync pulse (low) */
de-active = <0>; /* Data enable (low) */
};
port#0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
panel_input: endpoint#0 {
reg = <0>;
remote-endpoint = <&hlcdc_panel_output>;
};
};
};
...
Also in the kernel argument line (using U-Boot bootargs) I`m specifying the mode by supplying video=Unknown-1:1024x768-16
Finally, and I have conglomerated each of these parts to achieve the final goal, populating the hlcdc node in the device tree and having the LCD functional.
(apb node)
...
hlcdc: hlcdc#f0000000 {
u-boot,dm-pre-reloc;
status = "okay";
hlcdc-display-controller {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb666 &pinctrl_lcd_reset>;
port#0 {
#address-cells = <1>;
#size-cells = <0>;
hlcdc_panel_output: endpoint#0 {
reg = <0>;
remote-endpoint = <&panel_input>;
};
};
};
hlcdc_pwm: hlcdc-pwm {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcd_pwm>;
#pwm-cells = <3>;
};
};
...
The problem is that this strategy does not seem to work because, as mentioned above, because I only have the backlight and the touchscreen functional, but nothing is displayed on the screen.
The question is basically if this guide to integrate a custom LCD in linux is correct or if it has been wrong somewhere.
Related
I'm trying to create a screen taking app that can get a raw bitmap of a desktop window from the GPU. I did it via GDI and it works properly, but using both DirectX and DXGI Duplication api, I have black screen or an error.
void dump_buffer() {
IDirect3D9* d3d = nullptr;
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
out("1");
ZeroMemory(&d3dpp, sizeof(d3dpp));//COCK?
D3DDISPLAYMODE d3ddm;
if(FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
err("IDirect3D9");
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = FALSE;
IDirect3DDevice9* d3ddev = nullptr;
out("2");
d3d->CreateDevice(
D3DADAPTER_DEFAULT, // Используем видеокарту, установленную в Windows по умолчанию (= в качестве основной).
D3DDEVTYPE_HAL, // Используем аппаратный рендеринг (Hardware Abstraction Layer).
GetDesktopWindow(), // Дескриптор) окна
D3DCREATE_SOFTWARE_VERTEXPROCESSING, // Не использовать "фишки" T&L для лучшей совместимости с бОльшим числом видеоадаптеров.
&d3dpp, // Указатель на заранее заполненную структуру параметров отображения (D3DPRESENT_PARAMETERS).
&d3ddev // Указатель на создаваемый объект устройства Direct3D.
);
if (d3ddev == nullptr)
err("IDirect3DDevice9");
out("3");
IDirect3DSurface9 *pRenderTarget = nullptr;
IDirect3DSurface9 *pDestTarget = nullptr;
// sanity checks.
// get the render target surface.
HRESULT hr = d3ddev->GetRenderTarget(0, &pRenderTarget);
if (FAILED(hr)){
err("GetRenderTarget");
}
// get the current adapter display mode.
// hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode);
out("4");
D3DDISPLAYMODE mode;
hr = d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode);
if (FAILED(hr)){
err("GetAdapterDisplayMode");
}
// create a destination surface.
out(mode.Width);
out(mode.Height);
out(mode.Format);
hr = d3ddev->CreateOffscreenPlainSurface(mode.Width,
mode.Height,
mode.Format,
D3DPOOL_SYSTEMMEM,
&pDestTarget,
nullptr);
if (FAILED(hr)){
err(("CreateOffscreenPlainSurface"));
}
out("5");
//copy the render target to the destination surface.
hr = d3ddev->GetRenderTargetData(pRenderTarget, pDestTarget);
if (FAILED(hr)){
err(DXGetErrorDescription9A(hr));
err(("GetRenderTargetData"));
}
//save its contents to a bitmap file.
out("6");
hr = D3DXSaveSurfaceToFile(file,
D3DXIFF_BMP,
pDestTarget,
nullptr,
nullptr);
out("7");
// clean up.
pRenderTarget->Release();
pDestTarget->Release();
}
p.s: Do I understand correctly that when using GetDesktopWindow() am I capturing a desktop containing an image of the entire screen?
Some help in solving this problem is needed
I am trying to rebuild the kernel for ADF4372 driver : below
https://github.com/analogdevicesinc/linux/tree/rpi-5.10.y
Now it don't work well.
Kernel version:
Linux raspberrypi 5.10.631235984-v7 #4 SMP Sat Jul 16 17:41:54 JST 2022 armv7l GNU/Linux << My rebuild extension 1235984
Kernel log:
dmesg | grep spi : error messages
[ 9.641473] spi-bcm2835 3f204000.spi: registered master spi0
[ 9.661432] spi spi0.0: setup: forcing CS_HIGH (use_gpio_descriptors)
[ 9.661476] spi spi0.0: setup mode 0, cs_high, 8 bits/w, 1000000 Hz max --> 0
[ 9.662253] adf4371 spi0.0: Using the default clk names
[ 9.672797] spi-bcm2835 3f204000.spi: registered child spi0.0
[ 9.672889] spi-bcm2835 3f204000.spi: chipselect 0 already in use
[ 9.672926] spi_master spi0: spi_device register error /soc/spi#7e204000/spidev#0
[ 9.672957] spi_master spi0: Failed to create SPI device for /soc/spi#7e204000/spidev#0
[ 9.673013] spi spi0.1: setup: forcing CS_HIGH (use_gpio_descriptors)
[ 9.673042] spi spi0.1: setup mode 0, cs_high, 8 bits/w, 125000000 Hz max --> 0
[ 9.673445] spi-bcm2835 3f204000.spi: registered child spi0.1
File rpi-adf4371-overlay.dts:
/dts-v1/;
/plugin/;
/ {
fragment#0 {
target-path = "/";
__overlay__ {
clocks {
adf4372_clkin: clock#0 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <10000000>; // 10MHz
};
};
};
};
fragment#1 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
adf4372#0 {
compatible = "adi,adf4372";
reg = <0>;
spi-max-frequency = <1000000>;
clocks = <&adf4372_clkin>;
clock-names = "clkin";
};
};
};
};
I have GPIO-expnader tca6424 on my board. Pin 17 supplies another chips. I need to power off this chips in the "suspend-to-RAM" mode. I described it in dts file:
hu_u1740: tca6424_hu_u1740#22 {
compatible = "ti,tca6424";
reg = <0x22>;
gpio-controller;
#gpio-cells = <2>;
regulator#17 {
regulator-min-microvolt = <33000000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-name = "pw_bt";
enable-active-high;
regulator-state-mem {
regulator-off-in-suspend;
};
};
};
I tried pin 17 as regulator but it doesn't work. If is there ready way or i should write own driver?
I have platform with MT7620 in MIPS arch. On Platform is instaled OpenWRT. I also use Image Builder to create firmware. Now I whant to enable UART interface in my platform. I think that I must add inode to DT in mt7620.dts file but I do not know what must be the correct syntax. My propozition is below. I also need that UART worked as ttyS0 and console I whant to assigned to ttyS1
So, in file mt7620.dts I whant to add this
chosen {
bootargs = "console=ttyS1,15200";
};
uart#500 {
compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a";
reg = <0x500 0x100>;
interrupt-parent = <&intc>;
interrupts = <5>;
reg-shift = <2>;
pinctrl-names = "default";
pinctrl-0 = <&uartf_pins>;
status = "ok";
};
Please tell me whether above syntax is correct ?
Main library (dtsi) its following inode UART
uart#500 {
compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a";
reg = <0x500 0x100>;
resets = <&rstctrl 12>;
reset-names = "uart";
interrupt-parent = <&intc>;
interrupts = <5>;
reg-shift = <2>;
status = "disabled";
};
EITD
The answer is simply. It should be add inode to *.dts
uart#500
{
status = "okay"
}
That is all, because all parameters have been define in *.dtsi file.
Below is my Handel-C code where it can display a ball on the monitor through the FPGA VGA. But when I try to display a ball and a box in the monitor, it just display the first one, if I disable the ball, then I can display a box.
The ball and the box have similar behaviour, only differences are the size and the initial location.
Do anyone have idea what happen there?
#include <stdlib.hch>
#include "tpad.hch"
#include "ball.hch"
set family = AlteraCycloneIII; /* Really a Cyclone IV */
set part = "EP4CE115F29C7";
interface bus_in (unsigned 1 pin) clock_pin () with {data = {"Y2"}};
interface altpll (unsigned 5 clk with {clockport = 1})
pll (unsigned 2 inclk = 0 # clock_pin.pin)
with {
busformat = "B[N:0]",
properties = {
{"bandwidth_type", "AUTO"},
{"clk0_divide_by", "5"},
{"clk0_duty_cycle", "50"},
{"clk0_multiply_by", "4"},
{"clk0_phase_shift", "0"},
{"compensate_clock", "CLK0"},
{"inclk0_input_frequency", "20000"},
{"intended_device_family", "Cyclone IV E"},
{"lpm_hint", "CBX_MODULE_PREFIX=pll"},
{"lpm_type", "altpll"},
{"operation_mode", "NORMAL"},
{"pll_type", "AUTO"},
{"port_clk0", "PORT_USED"},
{"width_clock", "5"}},
bind = 1};
set clock = internal pll.clk[0];
void main( void ) {
lcd_data lcd;
par {
lcd_data lcd;
Ball ball, box;
initialise_ball( ball ); // Initialise ball structure before starting
initialise_box (box);
par {
lcd_driver( lcd ); // Run display driver in parallel
while (lcd.v_ena) // While vertical enable is true
do par{
display_ball( lcd, ball ); // display ball
display_box (lcd, box);
// update_ball( ball ); // update ball position
// while (!lcd.v_ena) delay; // While vertical enable is false
} while (1);
}
}
}