您尚未登录。

#2 Re: 全志 SOC » V3s板子 LRADC KEY按键显示的键值错误,并且显示毫无规律,求教啊! » 2023-02-10 18:06:48

对比本目录下sun4i-lradc-key.c 与 linux-5.10/drivers/input/keyboard/sun4i-lradc-keys.c 文件
增加调试代码,查看按键实际检测到的adc值
修改sun4i-lradc-key.c文件,增加debug部分代码,根据实际检测出来的adc值 设置linux kernel 设备树的参考电压

大概检测逻辑是:实际检测出来的电压与参考电压哪个更接近 就设置为哪个键值

for (i = 0; i < lradc->chan0_map_count; i++) 
{
    diff = abs(lradc->chan0_map[i].voltage - voltage);
    if (diff < closest) {
        closest = diff;
        keycode = lradc->chan0_map[i].keycode;
        #ifdef DEBUG_INPUT_KEY
        dev_info(lradc_dev, "Debug: chan0_map %d V \n", lradc->chan0_map[i].voltage);
        #endif
    }
}

前两天看了一下,我得分压电阻变了,改了一下参考电压 ,打开以下文件的 #define DEBUG_INPUT_KEY  在按键输出的时候会有调试信息

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Allwinner sun4i low res adc attached tablet keys driver
 *
 * Copyright (C) 2014 Hans de Goede <hdegoede@redhat.com>
 */

/*
 * Allwinnner sunxi SoCs have a lradc which is specifically designed to have
 * various (tablet) keys (ie home, back, search, etc). attached to it using
 * a resistor network. This driver is for the keys on such boards.
 *
 * There are 2 channels, currently this driver only supports channel 0 since
 * there are no boards known to use channel 1.
 */

#include <linux/err.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>

#define LRADC_CTRL		0x00
#define LRADC_INTC		0x04
#define LRADC_INTS		0x08
#define LRADC_DATA0		0x0c
#define LRADC_DATA1		0x10

/* LRADC_CTRL bits */
#define FIRST_CONVERT_DLY(x)	((x) << 24) /* 8 bits */
#define CHAN_SELECT(x)		((x) << 22) /* 2 bits */
#define CONTINUE_TIME_SEL(x)	((x) << 16) /* 4 bits */
#define KEY_MODE_SEL(x)		((x) << 12) /* 2 bits */
#define LEVELA_B_CNT(x)		((x) << 8)  /* 4 bits */
#define HOLD_KEY_EN(x)		((x) << 7)
#define HOLD_EN(x)		((x) << 6)
#define LEVELB_VOL(x)		((x) << 4)  /* 2 bits */
#define SAMPLE_RATE(x)		((x) << 2)  /* 2 bits */
#define ENABLE(x)		((x) << 0)

/* LRADC_INTC and LRADC_INTS bits */
#define CHAN1_KEYUP_IRQ		BIT(12)
#define CHAN1_ALRDY_HOLD_IRQ	BIT(11)
#define CHAN1_HOLD_IRQ		BIT(10)
#define	CHAN1_KEYDOWN_IRQ	BIT(9)
#define CHAN1_DATA_IRQ		BIT(8)
#define CHAN0_KEYUP_IRQ		BIT(4)
#define CHAN0_ALRDY_HOLD_IRQ	BIT(3)
#define CHAN0_HOLD_IRQ		BIT(2)
#define	CHAN0_KEYDOWN_IRQ	BIT(1)
#define CHAN0_DATA_IRQ		BIT(0)

//#define DEBUG_INPUT_KEY
/* struct lradc_variant - Describe sun4i-a10-lradc-keys hardware variant
 * @divisor_numerator:		The numerator of lradc Vref internally divisor
 * @divisor_denominator:	The denominator of lradc Vref internally divisor
 */
struct lradc_variant {
	u8 divisor_numerator;
	u8 divisor_denominator;
};

static const struct lradc_variant lradc_variant_a10 = {
	.divisor_numerator = 2,
	.divisor_denominator = 3
};

static const struct lradc_variant r_lradc_variant_a83t = {
	.divisor_numerator = 3,
	.divisor_denominator = 4
};

struct sun4i_lradc_keymap {
	u32 voltage;
	u32 keycode;
};

struct sun4i_lradc_data {
	struct device *dev;
	struct input_dev *input;
	void __iomem *base;
	struct regulator *vref_supply;
	struct sun4i_lradc_keymap *chan0_map;
	const struct lradc_variant *variant;
	u32 chan0_map_count;
	u32 chan0_keycode;
	u32 vref;
};
// hack: just for testing
static struct device *lradc_dev;
static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id)
{
	struct sun4i_lradc_data *lradc = dev_id;
	u32 i, ints, val, voltage, diff, keycode = 0, closest = 0xffffffff;

	ints  = readl(lradc->base + LRADC_INTS);

	/*
	 * lradc supports only one keypress at a time, release does not give
	 * any info as to which key was released, so we cache the keycode.
	 */

	if (ints & CHAN0_KEYUP_IRQ) {
		input_report_key(lradc->input, lradc->chan0_keycode, 0);
		lradc->chan0_keycode = 0;
	}

	if ((ints & CHAN0_KEYDOWN_IRQ) && lradc->chan0_keycode == 0) {
		val = readl(lradc->base + LRADC_DATA0) & 0x3f;
		voltage = val * lradc->vref / 63;
		// debug hack : display voltage in dmesg
		
		for (i = 0; i < lradc->chan0_map_count; i++) {
			diff = abs(lradc->chan0_map[i].voltage - voltage);
			if (diff < closest) {
				closest = diff;
				keycode = lradc->chan0_map[i].keycode;
				#ifdef DEBUG_INPUT_KEY
				dev_info(lradc_dev, "Debug: chan0_map %d V \n", lradc->chan0_map[i].voltage);
				#endif
			}
			
		}
		#ifdef DEBUG_INPUT_KEY
		printk("Debug: volatile: %u V, adc: %d,ref volatage: %d button pressed\n", voltage,val, lradc->vref);
		#endif
		//dev_info(lradc_dev, "Debug: volatile: %u V, adc: %d,ref volatage: %d button pressed\n", voltage,val, lradc->vref);
		lradc->chan0_keycode = keycode;
		input_report_key(lradc->input, lradc->chan0_keycode, 1);
	}

	input_sync(lradc->input);

	writel(ints, lradc->base + LRADC_INTS);

	return IRQ_HANDLED;
}

static int sun4i_lradc_open(struct input_dev *dev)
{
	struct sun4i_lradc_data *lradc = input_get_drvdata(dev);
	int error;

	error = regulator_enable(lradc->vref_supply);
	if (error)
		return error;

	lradc->vref = regulator_get_voltage(lradc->vref_supply) *
		      lradc->variant->divisor_numerator /
		      lradc->variant->divisor_denominator;
	/*
	 * Set sample time to 4 ms / 250 Hz. Wait 2 * 4 ms for key to
	 * stabilize on press, wait (1 + 1) * 4 ms for key release
	 */
	writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
		SAMPLE_RATE(0) | ENABLE(1), lradc->base + LRADC_CTRL);

	writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC);

	return 0;
}

static void sun4i_lradc_close(struct input_dev *dev)
{
	struct sun4i_lradc_data *lradc = input_get_drvdata(dev);

	/* Disable lradc, leave other settings unchanged */
	writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
		SAMPLE_RATE(2), lradc->base + LRADC_CTRL);
	writel(0, lradc->base + LRADC_INTC);

	regulator_disable(lradc->vref_supply);
}

static int sun4i_lradc_load_dt_keymap(struct device *dev,
				      struct sun4i_lradc_data *lradc)
{
	struct device_node *np, *pp;
	int i;
	int error;

	np = dev->of_node;
	if (!np)
		return -EINVAL;

	lradc->chan0_map_count = of_get_child_count(np);
	if (lradc->chan0_map_count == 0) {
		dev_err(dev, "keymap is missing in device tree\n");
		return -EINVAL;
	}

	lradc->chan0_map = devm_kmalloc_array(dev, lradc->chan0_map_count,
					      sizeof(struct sun4i_lradc_keymap),
					      GFP_KERNEL);
	if (!lradc->chan0_map)
		return -ENOMEM;

	i = 0;
	for_each_child_of_node(np, pp) {
		struct sun4i_lradc_keymap *map = &lradc->chan0_map[i];
		u32 channel;

		error = of_property_read_u32(pp, "channel", &channel);
		if (error || channel != 0) {
			dev_err(dev, "%pOFn: Inval channel prop\n", pp);
			of_node_put(pp);
			return -EINVAL;
		}

		error = of_property_read_u32(pp, "voltage", &map->voltage);
		if (error) {
			dev_err(dev, "%pOFn: Inval voltage prop\n", pp);
			of_node_put(pp);
			return -EINVAL;
		}

		error = of_property_read_u32(pp, "linux,code", &map->keycode);
		if (error) {
			dev_err(dev, "%pOFn: Inval linux,code prop\n", pp);
			of_node_put(pp);
			return -EINVAL;
		}

		i++;
	}

	return 0;
}

static int sun4i_lradc_probe(struct platform_device *pdev)
{
	struct sun4i_lradc_data *lradc;
	struct device *dev = &pdev->dev;
	int i;
	int error;
	// hack : just for testing
	lradc_dev = &pdev->dev;
	lradc = devm_kzalloc(dev, sizeof(struct sun4i_lradc_data), GFP_KERNEL);
	if (!lradc)
		return -ENOMEM;

	error = sun4i_lradc_load_dt_keymap(dev, lradc);
	if (error)
		return error;

	lradc->variant = of_device_get_match_data(&pdev->dev);
	if (!lradc->variant) {
		dev_err(&pdev->dev, "Missing sun4i-a10-lradc-keys variant\n");
		return -EINVAL;
	}

	lradc->vref_supply = devm_regulator_get(dev, "vref");
	if (IS_ERR(lradc->vref_supply))
		return PTR_ERR(lradc->vref_supply);

	lradc->dev = dev;
	lradc->input = devm_input_allocate_device(dev);
	if (!lradc->input)
		return -ENOMEM;

	lradc->input->name = pdev->name;
	lradc->input->phys = "sun4i_lradc/input0";
	lradc->input->open = sun4i_lradc_open;
	lradc->input->close = sun4i_lradc_close;
	lradc->input->id.bustype = BUS_HOST;
	lradc->input->id.vendor = 0x0001;
	lradc->input->id.product = 0x0001;
	lradc->input->id.version = 0x0100;

	__set_bit(EV_KEY, lradc->input->evbit);
	for (i = 0; i < lradc->chan0_map_count; i++)
		__set_bit(lradc->chan0_map[i].keycode, lradc->input->keybit);

	input_set_drvdata(lradc->input, lradc);

	lradc->base = devm_ioremap_resource(dev,
			      platform_get_resource(pdev, IORESOURCE_MEM, 0));
	if (IS_ERR(lradc->base))
		return PTR_ERR(lradc->base);

	error = devm_request_irq(dev, platform_get_irq(pdev, 0),
				 sun4i_lradc_irq, 0,
				 "sun4i-a10-lradc-keys", lradc);
	if (error)
		return error;

	error = input_register_device(lradc->input);
	if (error)
		return error;

	return 0;
}

static const struct of_device_id sun4i_lradc_of_match[] = {
	{ .compatible = "allwinner,sun4i-a10-lradc-keys",
		.data = &lradc_variant_a10 },
	{ .compatible = "allwinner,sun8i-a83t-r-lradc",
		.data = &r_lradc_variant_a83t },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match);

static struct platform_driver sun4i_lradc_driver = {
	.driver = {
		.name	= "sun4i-a10-lradc-keys",
		.of_match_table = of_match_ptr(sun4i_lradc_of_match),
	},
	.probe	= sun4i_lradc_probe,
};

module_platform_driver(sun4i_lradc_driver);

MODULE_DESCRIPTION("Allwinner sun4i low res adc attached tablet keys driver");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL");

#3 Re: ESP32/ESP8266 » 打样了4次才搞定了esp32的天线 » 2022-12-21 17:45:58

一般的天线都有指导PCB 怎么画,看看官方的文档,天线周围要避空等。

#4 Re: 全志 SOC » f1c100s/f1c200s最便宜,做一些电子产品用得最多的arm9? » 2022-10-02 22:09:48

都是网友凑起来的,据我了解 官方只释放资料,不管你能不能用起来。
不过,做产品主要看有没有货,自己的产品适不适用,性价比,技术方面总能攻克。

#5 Re: 全志 SOC » 晕哥,帮我看一下,为什么不支持Wlan0? » 2022-08-21 17:09:45

我也遇到了 记录一下:
原因:
原来dock硬件默认开启MMC1,我嫌开启后LED绿灯一直闪烁,因此将MMC1 disable 了,需要重新打开MMC1
另外由于MMC1 使用PG0,1,2 所以在使用MMC1时需要将 LED disable掉

#6 Re: 全志 SOC » 开源V3x制作的MIPI-V3x小电脑 » 2022-08-19 13:29:50

学习一下 对那个GPS显示离线地图的感兴趣。。

#8 Re: 全志 SOC » V3S zero 5.2y的内核 Kernel panic - not syncing: Attempted to kill init! » 2022-08-13 14:55:05

ldl212 说:

我用这个版本 编译4.13y的都没问题启动都正常。

后来更换编译器版本也不行,我重新下载了主线 5.10的版本 就可以了

#10 Re: 全志 SOC » V3S zero 5.2y的内核 Kernel panic - not syncing: Attempted to kill init! » 2022-08-13 12:13:47

多谢坛主回复,我现在用的就是 16.04 lts版本。
我刚发现我得gcc版本 是 gcc version 5.4.0 20160609  我怀疑是这方面的原因,我更换一下编译器试试

#11 全志 SOC » V3S zero 5.2y的内核 Kernel panic - not syncing: Attempted to kill init! » 2022-08-13 11:40:30

ldl212
回复: 6

请教一下大家,licheepi-zero 5.2y的内核 ,编译后出现这样的问题
我是从 tftp下载的 内核,设备树文件,启动起来就这样了
git 了好几遍,重新编译配置了好几遍,依然还是这样
日志如下

[    0.169924] printk: console [ttyS0] disabled
[    0.190228] 1c28000.serial: ttyS0 at MMIO 0x1c28000 (irq = 35, base_baud = 1500000) is a U6_16550A
[    0.748144] printk: console [ttyS0] enabled
[    0.777464] libphy: Fixed MDIO Bus: probed
[    0.782179] dwmac-sun8i 1c30000.ethernet: PTP uses main clock
[    0.787980] dwmac-sun8i 1c30000.ethernet: No regulator found
[    0.794271] dwmac-sun8i 1c30000.ethernet: Current syscon value is not the default 148000 (expect 38000)
[    0.803758] dwmac-sun8i 1c30000.ethernet: No HW DMA feature register supported
[    0.810998] dwmac-sun8i 1c30000.ethernet: RX Checksum Offload Engine supported
[    0.818213] dwmac-sun8i 1c30000.ethernet: COE Type 2
[    0.823188] dwmac-sun8i 1c30000.ethernet: TX Checksum insertion supported
[    0.829979] dwmac-sun8i 1c30000.ethernet: Normal descriptors
[    0.835632] dwmac-sun8i 1c30000.ethernet: Chain mode enabled
[    0.849756] libphy: stmmac: probed
[    0.853875] dwmac-sun8i 1c30000.ethernet: Cannot get mdio-mux node
[    0.860276] ------------[ cut here ]------------
[    0.864900] kernel BUG at net/core/dev.c:9241!
[    0.869337] Internal error: Oops - BUG: 0 [#1] SMP ARM
[    0.874468] Modules linked in:
[    0.877528] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.2.0-licheepi-zero+ #1
[    0.884650] Hardware name: Allwinner sun8i Family
[    0.889364] PC is at free_netdev+0xe0/0xe4
[    0.893456] LR is at free_netdev+0x9c/0xe4
[    0.897547] pc : [<c061c26c>]    lr : [<c061c228>]    psr: 80000013
[    0.903794] sp : c3833df0  ip : fffff9a4  fp : 00000000
[    0.909010] r10: c0488cbc  r9 : c3833e04  r8 : c3b89c00
[    0.914227] r7 : c0b04c48  r6 : c3b94038  r5 : c3b94000  r4 : c3b93f88
[    0.920743] r3 : 00000001  r2 : 00000000  r1 : a0000013  r0 : c0b7440c
[    0.927262] Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[    0.934386] Control: 10c5387d  Table: 4000406a  DAC: 00000051
[    0.940123] Process swapper/0 (pid: 1, stack limit = 0x(ptrval))
[    0.946120] Stack: (0xc3833df0 to 0xc3834000)
[    0.950474] 3de0:                                     c3b89c80 0000000c c38ba010 c04881e8
[    0.958642] 3e00: c0b32948 c3b89800 c3a03900 16d696fd c0b84e04 c0b84e00 c38ba010 00000000
[    0.966809] 3e20: c0b84e04 ffffffed c0b32948 00000000 00000000 c0484c10 c38ba010 c0b32948
[    0.974977] 3e40: c0b32948 c0b04c48 00000000 c0a4bb18 00000007 c0484f90 c0b8757c c0864014
[    0.983144] 3e60: a0000013 c38ba010 00000000 c0b32948 c0b04c48 00000000 c0a4bb18 00000007
[    0.991312] 3e80: 00000000 c0485238 00000000 c0b32948 c38ba010 c04852c0 00000000 c0b32948
[    0.999480] 3ea0: c0485240 c04830c0 00000000 c3808f58 c389ce34 16d696fd 00000000 c0b32948
[    1.007647] 3ec0: c3b89780 00000000 c0b307b8 c04840b8 c0946cb8 ffffe000 c0b32948 c0b32948
[    1.015815] 3ee0: c0b04c48 ffffe000 c0a1e60c c0485adc c0b4cf80 c0b04c48 ffffe000 c01026fc
[    1.023983] 3f00: c09c4f7c 000000f1 000000f1 c013ae00 c09c3ca8 00000000 c0a00608 00000000
[    1.032150] 3f20: 00000006 00000006 c090a3d4 c090a448 c090a3fc c0b04c48 c0a3a818 c3f39990
[    1.040318] 3f40: c3f39998 16d696fd 00000000 16d696fd c0b4cf80 c0b4cf80 000000f1 c0a3a834
[    1.048486] 3f60: c0a3a83c 00000007 00000000 c0a00f20 00000006 00000006 00000000 c0a00608
[    1.056653] 3f80: 00000000 00000000 c07497a8 00000000 00000000 00000000 00000000 00000000
[    1.064820] 3fa0: 00000000 c07497b0 00000000 c01010e8 00000000 00000000 00000000 00000000
[    1.072987] 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    1.081154] 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
[    1.089344] [<c061c26c>] (free_netdev) from [<c04881e8>] (release_nodes+0x178/0x1f4)
[    1.097088] [<c04881e8>] (release_nodes) from [<c0484c10>] (really_probe+0xd0/0x2d8)
[    1.104826] [<c0484c10>] (really_probe) from [<c0484f90>] (driver_probe_device+0x60/0x168)
[    1.113082] [<c0484f90>] (driver_probe_device) from [<c0485238>] (device_driver_attach+0x58/0x60)
[    1.121945] [<c0485238>] (device_driver_attach) from [<c04852c0>] (__driver_attach+0x80/0xbc)
[    1.130462] [<c04852c0>] (__driver_attach) from [<c04830c0>] (bus_for_each_dev+0x68/0xb4)
[    1.138631] [<c04830c0>] (bus_for_each_dev) from [<c04840b8>] (bus_add_driver+0x140/0x1e8)
[    1.146886] [<c04840b8>] (bus_add_driver) from [<c0485adc>] (driver_register+0x78/0x110)
[    1.154971] [<c0485adc>] (driver_register) from [<c01026fc>] (do_one_initcall+0x54/0x1b8)
[    1.163146] [<c01026fc>] (do_one_initcall) from [<c0a00f20>] (kernel_init_freeable+0x140/0x1dc)
[    1.171841] [<c0a00f20>] (kernel_init_freeable) from [<c07497b0>] (kernel_init+0x8/0x114)
[    1.180011] [<c07497b0>] (kernel_init) from [<c01010e8>] (ret_from_fork+0x14/0x2c)
[    1.187568] Exception stack(0xc3833fb0 to 0xc3833ff8)
[    1.192612] 3fa0:                                     00000000 00000000 00000000 00000000
[    1.200779] 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    1.208945] 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[    1.215555] Code: e19500b3 e0450000 e8bd4070 eaeeedbb (e7f001f2)
[    1.221652] ---[ end trace a912cb4ace74eb36 ]---
[    1.226391] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[    1.234055] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---

#12 Re: 全志 SOC » V3s linux5.2 U盘自动挂载配置 » 2022-08-12 10:26:34

hahahah 说:

楼主知道v3s如何挂载nfs么

正点原子有教程

#13 Re: 全志 SOC » 调试应用程序时,怎么快速烧写到目标板? » 2022-08-12 10:04:43

我也刚开始完全志,参考原子的教程,搭建NFS 系统,linux内核,rootfs 都在虚拟机内,设备uboot启动起来后 从tftp下载linux内核,然后联网用虚拟机的nfs 共享文件夹的 rootfs,修改了什么驱动,app直接拷贝到 虚拟机的共享目录,然后在设备端就能看到了直接挂载运行。

#17 Re: 全志 SOC » 求大佬帮我看一下自制F1C200S小板子 » 2020-07-20 17:37:56

论坛气氛这么好?  居然帮忙看原理图?  楼主你还想人帮你画PCB,在别的论坛早被人骂了,管你是不是学生

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn