Jump to content
    

SPI драйвер для ADS7046

Здравствуйте! Стокнулся с проблемой написания драйвера под данную АЦП через SPIDEV. Опыта программирования под линукс не имею, до этого всегда на микроконтроллерах работал. Проблема заключается в том , что АЦП требует после каждого опроса переводить бит линию CS в высокое состояние , а затем снова переводить в ноль. Работа через SPIDEV же не позволяет управлять линией CS, можно только выставить задержку этой линии в микросекундах. Железо уже готово, я бы между хостом и АЦП микроконтроллер воткнул, гораздо удобнее бы было и частоту семплирования выставлять и прочее. 

Можете посоветовать откуда можно позаимствовать похожий SPI драйвер (постараюсь переделать под свои нужды )  и чтобы частота дискретизации настраивалась,

Share this post


Link to post
Share on other sites

struct spi_ioc_transfer {
	__u64		tx_buf;
	__u64		rx_buf;
	__u32		len;
	__u32		speed_hz;
	__u16		delay_usecs;
	__u8		bits_per_word;
	__u8		cs_change;
	__u32		pad;
};

len делаете 1

bits_per_word 8

cs_change 0

И на каждую передачу будет подниматься CS

 

Share this post


Link to post
Share on other sites

1. Посоветовать можно. Но у хоста должна быть минимум указана архитектура......

2. И ADC наверное не ad7046 а ads7046... 

Share this post


Link to post
Share on other sites

Извините, в торопях тему писал. Да ADS7046 , а железо используется ARM9 F1C200s

Share this post


Link to post
Share on other sites

Вам надо еще определиться с тем, что у вас за SPI контроллер стоит. Найти в дереве устройств описание.
Что за Линукс у вас? 

Линукс уже стоит на устройстве?
Какие файлы в /boot/ директории?

Примеры можно найти в коде ядра:
https://elixir.bootlin.com/linux/latest/source/drivers/spi

Инструкции там же:
https://elixir.bootlin.com/linux/latest/source/Documentation/spi

Вам с нуля все будет непонятно. Спрашивайте.

Глобально выглядит так:
Каждому устройству соответствует его описание в дереве устройств. Режимы работы, адреса регистров и т.д.. Если одинаковых устройств несколько, то каждому индивидуальное описание и регистры точно будут другими в этих описаниях одного и тогоже типа устройства.

Еще есть драйвер, который для работы с этим устройством.

Вам надо и драйвер и описание в дерево добавить.

В описании и драйвере есть признак, по которому для каждого описания ищется драйвер.
Если нашелся драйвер, то устройство может быть использовано.

В директории /sys/ можно посмотреть. Там каждому драйверу и каждому описанию посвящена директория.

Вот дерево для вашего процессора:
https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/dts/allwinner/suniv-f1c200s-lctech-pi.dts
или
https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/dts/allwinner/suniv-f1c200s-popstick-v1.1.dts

 Найдите этот файл в вашем коде ядра. Там та же директория.
 

Одно SPI устройство уже описано. 


&spi0 {
	pinctrl-names = "default";
	pinctrl-0 = <&spi0_pc_pins>;
	status = "okay";

	flash@0 {
		compatible = "spi-nand";
		reg = <0>;
		spi-max-frequency = <40000000>;
	};
};

Где compatible = "spi-nand"; есть признак ("spi-nand" -- признак), который должен совпасть с драйвером. У вас будет другой признак. Можете поискать среди драйверов. Вдруг найдете подходящий, тогда из него признак возьмете и впишите в свое дерево. Можно любой признак вписать. Напишите имя микросхемы, например.
Главное чтобы в обоих местах имя в точности совпадало.

Там еще ножки описаны:

			spi0_pc_pins: spi0-pc-pins {
				pins = "PC0", "PC1", "PC2", "PC3";
				function = "spi0";
			};


Вот похожий драйвер:
https://github.com/torvalds/linux/blob/master/drivers/iio/adc/ad7476.c
Он с правильного источника. То, что я давал выше -- производный источник (https://elixir.bootlin.com).

В структуре

static struct spi_driver ad7476_driver = {
	.driver = {
		.name	= "ad7476",
	},
	.probe		= ad7476_probe,
	.id_table	= ad7476_id,
};

.name    = "ad7476"
"ad7476" -- признак, по которому будет найдено описание в дереве устройств для этого драйвера.
 
Когда добавите код драйвера в соответствующее место в директории ядра, надо будет добавить описание вашего драйвера в Kconfig и Makefile. Посмотрите как сделано здесь:
https://github.com/torvalds/linux/tree/master/drivers/iio/adc

Потом в окне, созданном командой make menuconfig добавьте этот драйвер. Там будет строка, что вы добавили в Kconfig
Теперь при компиляции ядра ваш драйвер будет присутствовать.

При запуске Линукса на вашем устройстве, в директории /sys/ будет добавлена соответствующая директория.

 

Share this post


Link to post
Share on other sites

Спасибо большое! Как добавить и обозначить SPI через дерево устройств я разобрался еще в пятницу. Сейчас буду разбирать драйвер. 

Share this post


Link to post
Share on other sites

Имейте в виду, что линуксовая подсистема iio - это страшный кошмар. Мегасемплов на ARM9 не получится.

Share this post


Link to post
Share on other sites

On 4/1/2024 at 11:21 AM, aaarrr said:

Имейте в виду, что линуксовая подсистема iio - это страшный кошмар. Мегасемплов на ARM9 не получится.

Спасибо! Получается чтобы достичь 2.4 МГц дискретизации нужно все-таки промежуточное звено ставить в виде микроконтроллера какого нибудь ? 

Share this post


Link to post
Share on other sites

11 minutes ago, Mysteo said:

Получается чтобы достичь 2.4 МГц дискретизации нужно все-таки промежуточное звено ставить в виде микроконтроллера какого нибудь ?

Да, или программируемой логики.

Share this post


Link to post
Share on other sites

8 часов назад, aaarrr сказал:

Да, или программируемой логики.

Или бареметал)))))

Share this post


Link to post
Share on other sites

17 minutes ago, mantech said:

Или бареметал))))

...или бареметал. Но и он может не вывезти - все же SPI на таких процессорах не под АЦП задумывался.

Share this post


Link to post
Share on other sites

24 минуты назад, aaarrr сказал:

Но и он может не вывезти - все же SPI на таких процессорах не под АЦП задумывался.

Нее, тут все норм, например в Т113

image.thumb.png.7697a5dc16e532b2a1ff312c108e43a1.png

По ДШ получается макс 400мегабит, ТС нужно почти на порядок меньше.

Edited by mantech

Share this post


Link to post
Share on other sites

3 minutes ago, mantech said:

макс 400мегабит

А триггер от таймера, как в обычных МК?

Share this post


Link to post
Share on other sites

3 минуты назад, aaarrr сказал:

А триггер от таймера, как в обычных МК?

А вот тут х.з. не проверял))

Share this post


Link to post
Share on other sites

Ну, вот. Потребуется извратный семплрейт или запуск по внешнему событию, и никакой бареметал тоже не спасет...

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...