Перейти к содержанию
    

Как работать с ADC?

Создал корку

entity adc is
	port (
		adc_pll_clock_clk          : in  std_logic                     := '0';             --    adc_pll_clock.clk
		adc_pll_locked_export      : in  std_logic                     := '0';             --   adc_pll_locked.export
		clock_clk                  : in  std_logic                     := '0';             --            clock.clk
		reset_sink_reset_n         : in  std_logic                     := '0';             --       reset_sink.reset_n
		sample_store_csr_address   : in  std_logic_vector(6 downto 0)  := (others => '0'); -- sample_store_csr.address
		sample_store_csr_read      : in  std_logic                     := '0';             --                 .read
		sample_store_csr_write     : in  std_logic                     := '0';             --                 .write
		sample_store_csr_writedata : in  std_logic_vector(31 downto 0) := (others => '0'); --                 .writedata
		sample_store_csr_readdata  : out std_logic_vector(31 downto 0);                    --                 .readdata
		sample_store_irq_irq       : out std_logic;                                        -- sample_store_irq.irq
		sequencer_csr_address      : in  std_logic                     := '0';             --    sequencer_csr.address
		sequencer_csr_read         : in  std_logic                     := '0';             --                 .read
		sequencer_csr_write        : in  std_logic                     := '0';             --                 .write
		sequencer_csr_writedata    : in  std_logic_vector(31 downto 0) := (others => '0'); --                 .writedata
		sequencer_csr_readdata     : out std_logic_vector(31 downto 0)                     --                 .readdata
	);
end entity adc;

а что цеплять на порты и как работать не пойму. документация как обычно написанна для тех кто в теме. для своих разработчиков пишут,не для пользователей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Делайте с секвенсером, на avalon-mm. Там один регистр CSR потом прописать чтобы запустить ADC, а потом считывать из регистров нужных входов готовое значение. Если все делать в qsys с ниосом - наружу вообще ничего не надо вытаскивать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, alexPec said:

Делайте с секвенсером, на avalon-mm. Там один регистр CSR потом прописать чтобы запустить ADC, а потом считывать из регистров нужных входов готовое значение. Если все делать в qsys с ниосом - наружу вообще ничего не надо вытаскивать.

в том то и дело что я не знаю какие настройки прописывать в сиквенсер. этот ''entity adc'' для работы на low level, непосредственно обращаться в кор, надо знать адреса и значения.

я пошел другим путем - создал через QSYS

adc.png.2dd4058ff77b45ec84b9eabfc4e876f9.png

и получил модуль более приятный для глаз.

component adc_qsys is
		port (
			clk_clk                : in  std_logic                     := 'X';             -- clk
			command_valid          : in  std_logic                     := 'X';             -- valid
			command_channel        : in  std_logic_vector(4 downto 0)  := (others => 'X'); -- channel
			command_startofpacket  : in  std_logic                     := 'X';             -- startofpacket
			command_endofpacket    : in  std_logic                     := 'X';             -- endofpacket
			command_ready          : out std_logic;                                        -- ready
			reset_reset_n          : in  std_logic                     := 'X';             -- reset_n
			response_valid         : out std_logic;                                        -- valid
			response_channel       : out std_logic_vector(4 downto 0);                     -- channel
			response_data          : out std_logic_vector(11 downto 0);                    -- data
			response_startofpacket : out std_logic;                                        -- startofpacket
			response_endofpacket   : out std_logic                                         -- endofpacket
		);
	end component adc_qsys;

но как пользоваться остается загадкой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просто в кусисе поставьте компонент ADC, выберите тип с секвенсером и avalon-mm шиной. Получается примерно так:

image.thumb.png.e884dc43f945c3a13c8f3986a01bb9c6.png

А дальше через ниос, через регистры запускаете и вытаскиваете данные

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, alexPec said:

Просто в кусисе поставьте компонент ADC, выберите тип с секвенсером и avalon-mm шиной. Получается примерно так:

 

А дальше через ниос, через регистры запускаете и вытаскиваете данные

у меня нет ниоса, голый камень.

я так понимаю

1 - выставляем канал          command_channel <= "00000";

2 - запускаем конвертацию  command_valid <= '1';

3 - ждем конца конвертации response_valid = '1';

4 - считываем данные из     response_data

так что ли?

или сигналы сиквенсера надо обязательно куда то подключить?

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, там можно и без секвенсера АЦП сделать, но страшно много выводов получится.

К сожалению тут уже не подскажу. Придется курить хэндбук, я выкурил только часть с авалон-интерфейсом :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, alexPec said:

Нет, там можно и без секвенсера АЦП сделать, но страшно много выводов получится.

К сожалению тут уже не подскажу. Придется курить хэндбук, я выкурил только часть с авалон-интерфейсом :)

спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

21 час назад, jenya7 сказал:

у меня нет ниоса, голый камень.

Ну так добавьте его. Это гораздо проще, и результат получите быстрее, чем если сами начнете автомат для управления придумывать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/12/2019 at 3:08 PM, StewartLittle said:

Ну так добавьте его. Это гораздо проще, и результат получите быстрее, чем если сами начнете автомат для управления придумывать.

брать FPGA и вставлять в него микроконтроллер? никогда не понимал этих извращений. FPGA тем и хорош что может делать то что не может микроконтроллер.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

39 minutes ago, jenya7 said:

брать FPGA и вставлять в него микроконтроллер? никогда не понимал этих извращений. FPGA тем и хорош что может делать то что не может микроконтроллер.

FPGA тем и хорош, что на нем можно делать параллельную обработку интерфейсов и ЦОС под управлением софтварного проца

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, quato_a said:

FPGA тем и хорош, что на нем можно делать параллельную обработку интерфейсов и ЦОС под управлением софтварного проца

проц отжирает половину ресурсов, которых в FPGA кот наплакал. если бы FPGA стоил хотя бы в 2 раза дороже чем проц и был сопоставим по ресурсам с процом, тогда да. а так он стоит в 10 раз дороже и ресурсов в 10 раз меньше.

у меня внешний контроллер подключен к FPGA по SPI. как по мне это лучшее решение.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 hours ago, jenya7 said:

проц отжирает половину ресурсов, которых в FPGA кот наплакал. если бы FPGA стоил хотя бы в 2 раза дороже чем проц и был сопоставим по ресурсам с процом, тогда да. а так он стоит в 10 раз дороже и ресурсов в 10 раз меньше.

у меня внешний контроллер подключен к FPGA по SPI. как по мне это лучшее решение.

если только у вас плис, очень маленькая) минимальный ниос, ЕМНИП 600 плиток, средний 1200, максимальный 1600. Правда есть любители писать КА на 100 и больше состояний, а потом усиленно их отлаживать.

ТС, есть еще Авалон стейт секвенсер. Он весит очень мало, может быть он вас устроит по возможностям?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, des00 said:

если только у вас плис, очень маленькая) минимальный ниос, ЕМНИП 600 плиток, средний 1200, максимальный 1600. Правда есть любители писать КА на 100 и больше состояний, а потом усиленно их отлаживать.

ТС, есть еще Авалон стейт секвенсер. Он весит очень мало, может быть он вас устроит по возможностям?

у меня 10M50DAF484C7G и загрузка 70%.

не могу понять что там с чем соединять. нет нормальной документации. я так понимаю через QSYS по Avalon-mm шине можно все соединить включая SPI. но разобраться в этом - убиться можно.

 

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как я выбираю функциональность пина? Он может иметь разную функциональность -  IO_1A/ADC1IN2/DIFFIO_RX_L1P.

Если я в QSYS выбрал ADC 1/2 и каналы с которыми работать (CH1-CH8) пины отконфигурируются кором? в пин планере эти пины не надо конфигурировать? там в I/O Standard и опции такой нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в Qsys создал модуль

component adc_qsys is
	port (
		adc_1_command_valid          : in  std_logic                     := '0';             --  adc_1_command.valid
		adc_1_command_channel        : in  std_logic_vector(4 downto 0)  := (others => '0'); --               .channel
		adc_1_command_startofpacket  : in  std_logic                     := '0';             --               .startofpacket
		adc_1_command_endofpacket    : in  std_logic                     := '0';             --               .endofpacket
		adc_1_command_ready          : out std_logic;                                        --               .ready
		adc_1_response_valid         : out std_logic;                                        -- adc_1_response.valid
		adc_1_response_channel       : out std_logic_vector(4 downto 0);                     --               .channel
		adc_1_response_data          : out std_logic_vector(11 downto 0);                    --               .data
		adc_1_response_startofpacket : out std_logic;                                        --               .startofpacket
		adc_1_response_endofpacket   : out std_logic;                                        --               .endofpacket
		adc_2_command_valid          : in  std_logic                     := '0';             --  adc_2_command.valid
		adc_2_command_channel        : in  std_logic_vector(4 downto 0)  := (others => '0'); --               .channel
		adc_2_command_startofpacket  : in  std_logic                     := '0';             --               .startofpacket
		adc_2_command_endofpacket    : in  std_logic                     := '0';             --               .endofpacket
		adc_2_command_ready          : out std_logic;                                        --               .ready
		adc_2_response_valid         : out std_logic;                                        -- adc_2_response.valid
		adc_2_response_channel       : out std_logic_vector(4 downto 0);                     --               .channel
		adc_2_response_data          : out std_logic_vector(11 downto 0);                    --               .data
		adc_2_response_startofpacket : out std_logic;                                        --               .startofpacket
		adc_2_response_endofpacket   : out std_logic;                                        --               .endofpacket
		clk_clk                      : in  std_logic                     := '0';             --            clk.clk
		reset_reset_n                : in  std_logic                     := '0'              --          reset.reset_n
	);
end component adc_qsys;

подключил к сигналам

signal adc1_com_valid          : std_logic; 
signal adc1_com_channel        : std_logic_vector(4 downto 0); 
signal adc1_com_startofpacket  : std_logic;                    
signal adc1_com_endofpacket    : std_logic;                    
signal adc1_com_ready          : std_logic;                            
signal adc1_reset_n            : std_logic;                   
signal adc1_resp_valid         : std_logic;                                    
signal adc1_resp_channel       : std_logic_vector(4 downto 0);                     
signal adc1_resp_data          : std_logic_vector(11 downto 0);                    
signal adc1_resp_startofpacket : std_logic;                                        
signal adc1_resp_endofpacket   : std_logic; 
signal adc1_sample_time        : std_logic_vector(31 downto 0) := (others => '0'); 

signal adc1_1_data          : std_logic_vector(11 downto 0);
signal adc1_2_data          : std_logic_vector(11 downto 0);
signal adc1_3_data          : std_logic_vector(11 downto 0);
signal adc1_4_data          : std_logic_vector(11 downto 0);
signal adc1_5_data          : std_logic_vector(11 downto 0);
signal adc1_6_data          : std_logic_vector(11 downto 0);
signal adc1_7_data          : std_logic_vector(11 downto 0);
signal adc1_8_data          : std_logic_vector(11 downto 0);

signal adc2_com_valid          : std_logic; 
signal adc2_com_channel        : std_logic_vector(4 downto 0); 
signal adc2_com_startofpacket  : std_logic;                    
signal adc2_com_endofpacket    : std_logic;                    
signal adc2_com_ready          : std_logic;                            
signal adc2_reset_n            : std_logic;                   
signal adc2_resp_valid         : std_logic;                                    
signal adc2_resp_channel       : std_logic_vector(4 downto 0);                     
signal adc2_resp_data          : std_logic_vector(11 downto 0);                    
signal adc2_resp_startofpacket : std_logic;                                        
signal adc2_resp_endofpacket   : std_logic; 
signal adc2_sample_time        : std_logic_vector(31 downto 0) := (others => '0');

signal adc2_1_data          : std_logic_vector(11 downto 0);
signal adc2_2_data          : std_logic_vector(11 downto 0);
signal adc2_3_data          : std_logic_vector(11 downto 0);
signal adc2_4_data          : std_logic_vector(11 downto 0);
signal adc2_5_data          : std_logic_vector(11 downto 0);
signal adc2_6_data          : std_logic_vector(11 downto 0);
signal adc2_7_data          : std_logic_vector(11 downto 0);
signal adc2_8_data          : std_logic_vector(11 downto 0);


U_ADC : adc_qsys 
port map 
(
	clk_clk                  => G_CLK,
	reset_reset_n  => '1', 
	
	adc_1_command_valid          => adc1_com_valid, 
	adc_1_command_channel        => adc1_com_channel, 
	adc_1_command_startofpacket  => adc1_com_startofpacket,
	adc_1_command_endofpacket    => adc1_com_endofpacket, 
	adc_1_command_ready          => adc1_com_ready,
	adc_1_response_valid         => adc1_resp_valid,
	adc_1_response_channel       => adc1_resp_channel,
	adc_1_response_data          => adc1_resp_data, 
	adc_1_response_startofpacket => adc1_resp_startofpacket,
	adc_1_response_endofpacket   => adc1_resp_endofpacket,
		
	adc_2_command_valid          => adc2_com_valid, 
	adc_2_command_channel        => adc2_com_channel, 
	adc_2_command_startofpacket  => adc2_com_startofpacket,
	adc_2_command_endofpacket    => adc2_com_endofpacket, 
	adc_2_command_ready          => adc2_com_ready,
	adc_2_response_valid         => adc2_resp_valid,
	adc_2_response_channel       => adc2_resp_channel,
	adc_2_response_data          => adc2_resp_data,
	adc_2_response_startofpacket => adc2_resp_startofpacket,
	adc_2_response_endofpacket   => adc2_resp_endofpacket
);

теперь хочу просканироавть все каналы

signal chan : std_logic_vector(4 downto 0) := "00000";

ADC1_SCAN : process(G_CLK)
begin

    if rising_edge(G_CLK) then
	 
	     case Adc1State is
	 
			  when ST_WAIT_FOR_SAMPLE => 
			  
					adc1_sample_time <= adc1_sample_time + '1';
		
					if (adc1_sample_time = X"0000000000989680") then  --100 ms
						 adc1_sample_time <= (others => '0');
						 Adc1State <= ST_SELECT_CHAN;
					end if;
					
			  when ST_SELECT_CHAN =>
					if (chan = "01000") then
						chan := "00001";
					else
						chan := chan + '1'; 	
					end if;
					Adc1State <= ST_START_CONV;

			  when ST_START_CONV => 
					adc1_com_channel <= chan;
					adc1_com_valid <= '1';
					Adc1State <= ST_WAIT_FOR_DONE;
			
			  when ST_WAIT_FOR_DONE =>
					adc1_com_valid <= '0';
					if (adc1_resp_valid = '1') then
						 Adc1State <= ST_DATA_READY;
					end if;
					
			  when ST_DATA_READY => 
					case chan is
						 when "00001" => adc1_1_data <= adc1_resp_data;
						 when "00010" => adc1_2_data <= adc1_resp_data;
						 when "00011" => adc1_3_data <= adc1_resp_data;
						 when "00100" => adc1_4_data <= adc1_resp_data;
						 when "00101" => adc1_5_data <= adc1_resp_data;
						 when "00110" => adc1_6_data <= adc1_resp_data;
						 when "00111" => adc1_7_data <= adc1_resp_data;
						 when "01000" => adc1_8_data <= adc1_resp_data;
						 when others => Adc1State <= ST_WAIT_FOR_SAMPLE;
					end case;
				  Adc1State <= ST_WAIT_FOR_SAMPLE;	
				  
		      when others => Adc1State <= ST_WAIT_FOR_SAMPLE;	  
				
        end case;				
			
    end if;

end process ADC1_SCAN;

и есть модуль в который я передаю результаты чтоб вывести наружу

U_REG_FILE : REG_FILE 
generic map
(
	SPI_DATA_WIDTH => 8
)
port map
(
    REG_CLK	     => G_CLK,  
	REG_RST       => '0',          

    ADC1_1_DATA  => adc1_1_data,
	ADC1_2_DATA  => adc1_2_data,	
    ADC1_3_DATA  => adc1_3_data,	
    ADC1_4_DATA  => adc1_4_data,	
    ADC1_5_DATA  => adc1_5_data,	
    ADC1_6_DATA  => adc1_6_data,	
    ADC1_7_DATA  => adc1_7_data,	
    ADC1_8_DATA  => adc1_8_data,	
	
    ADC2_1_DATA  => adc2_1_data,	
	ADC2_2_DATA  => adc2_2_data,	
    ADC2_3_DATA  => adc2_3_data,	
    ADC2_4_DATA  => adc2_4_data,	
    ADC2_5_DATA  => adc2_5_data,
	ADC2_6_DATA  => adc2_6_data,	
    ADC2_7_DATA  => adc2_7_data,	
    ADC2_8_DATA  => adc2_8_data		
);

если я в этом модуле ставлю REG_RST  => '0', то все компилируется, а если REG_RST  => '1', то получаю ошибку в Fitter

Error (170084): Can't route signal "adc_qsys:U_ADC|adc_qsys_ADC1_PLL:adc1_pll|adc_qsys_ADC1_PLL_altpll_gr22:sd1|wire_pll7_clk[0]" to atom "adc_qsys:U_ADC|adc_qsys_ADC_1:adc_1|altera_modular_adc_control:control_internal|fiftyfivenm_adcblock_top_wrapper:adc_inst|fiftyfivenm_adcblock_primitive_wrapper:adcblock_instance|primitive_instance"

Error (170084): Can't route signal "adc_qsys:U_ADC|adc_qsys_ADC1_PLL:adc1_pll|adc_qsys_ADC1_PLL_altpll_gr22:sd1|wire_pll7_clk[0]" to atom "adc_qsys:U_ADC|adc_qsys_ADC_1:adc_1|altera_modular_adc_control:control_internal|fiftyfivenm_adcblock_top_wrapper:adc_inst|fiftyfivenm_adcblock_primitive_wrapper:adcblock_instance|primitive_instance"

причем если я закрываю сигналы

when ST_START_CONV => 
    --adc1_com_channel <= chan;
	--adc1_com_valid <= '1';
	Adc1State <= ST_WAIT_FOR_DONE;

то все компилируется и с REG_RST  => '1'

 

не могу понять в чем дело

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...