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

Что не так с CSI?

Здравствуйте.

В общем ситуация следующая.

Сделал кадровый буфер, данные собираются, штампуются данными гироскопа и передаются на комп.

что качается камеры:

1. ядро MIPI RX Advance - получает сырой поток с камеры.

2. ядро MIPI DSI/CSI-2 Receiver - получает сырой поток с предыщего ядра и обрабатывает пакеты данных.

3. ядро MIPI Byte-to-Pixel Converter - получает пакеты с предыдущего ядра и выделяет из них данные пикселей.

 

Так вот Вроде бы все работает как и должно. С последнего ядра есть сигналы O_LineValid и O_FrameValid. 

Собрал тестовый образец таким образом что сигнал O_LineValid вывожу на светодиод. Выходная частота пикселей 28мгц.

Вот так сделал связи:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use IEEE.numeric_std.all;  
 

entity camera_csi_processor is  
port (   
	RESET: in std_logic := '0';   
    DATA_P: in std_logic := '0';
    DATA_N: in std_logic := '0';
    DATA_2_P: in std_logic := '0'; 
    DATA_2_N: in std_logic := '0'; 
    CLK_P: in std_logic := '0'; 
    CLK_N: in std_logic := '0';
	
	MipiEn: in std_logic := '0';
	
	I_Pix_Clk: in std_logic := '0';
    O_FrameValid : out std_logic := '0';
    O_LineValid : out std_logic := '0';
	O_PixData: out std_logic_vector(15 downto 0) := (others => '0')
); 
end camera_csi_processor;



architecture logic of camera_csi_processor is 

constant I_REF_DataType:  std_logic_vector(5 downto 0) := "101010";  -- "RAW-8, 6'h2A"
 
signal O_ShortPack_EN: std_logic := '0';
signal O_LongPack_EN: std_logic := '0';
signal O_DataTypeMatch_EN: std_logic := '0';
signal O_ECC_OK: std_logic := '0';
signal O_ECC: std_logic_vector(7 downto 0) := (others => '0');	
signal O_ChanelID: std_logic_vector(1 downto 0) := (others => '0');	
signal DataType: std_logic_vector(5 downto 0) := (others => '0');	
signal PayloadDataCnt: std_logic_vector(15 downto 0) := (others => '0');
signal PAYLOAD: std_logic_vector(15 downto 0) := (others => '0');
signal PAYLOAD_DV: std_logic_vector(1 downto 0) := (others => '0');

signal Mipi_Ready: std_logic := '0';
signal Mipi_Data_Read_Clk: std_logic := '0';
signal Mipi_Data_Out1: std_logic_vector(7 downto 0) := (others => '0');	
signal Mipi_Data_Out0: std_logic_vector(7 downto 0) := (others => '0');	


component mipi_rx
	port (
		reset_n: in std_logic;
		HS_CLK_P: in std_logic;
		HS_CLK_N: in std_logic;
		clk_byte_out: out std_logic;
		HS_DATA1_P: in std_logic;
		HS_DATA1_N: in std_logic;
		data_out1: out std_logic_vector(7 downto 0);
		HS_DATA0_P: in std_logic;
		HS_DATA0_N: in std_logic;
		data_out0: out std_logic_vector(7 downto 0);
		hs_en: in std_logic;
		clk_term_en: in std_logic;
		data_term_en: in std_logic;
		ready: out std_logic
	);
end component;
 

component MIPI_DSI_CSI2_RX_Top
	port (
		I_RSTN: in std_logic;
		I_BYTE_CLK: in std_logic;
		I_REF_DT: in std_logic_vector(5 downto 0);
		I_READY: in std_logic;
		I_DATA0: in std_logic_vector(7 downto 0);
		I_DATA1: in std_logic_vector(7 downto 0);
		O_SP_EN: out std_logic;
		O_LP_EN: out std_logic;
		O_LP_AV_EN: out std_logic;
		O_ECC_OK: out std_logic;
		O_ECC: out std_logic_vector(7 downto 0);
		O_WC: out std_logic_vector(15 downto 0);
		O_VC: out std_logic_vector(1 downto 0);
		O_DT: out std_logic_vector(5 downto 0);
		O_PAYLOAD: out std_logic_vector(15 downto 0);
		O_PAYLOAD_DV: out std_logic_vector(1 downto 0)
	);
end component;

component MIPI_Byte_to_Pixel_Converter_Top
	port (
		I_RSTN: in std_logic;
		I_BYTE_CLK: in std_logic;
		I_PIXEL_CLK: in std_logic;
		I_SP_EN: in std_logic;
		I_LP_AV_EN: in std_logic;
		I_DT: in std_logic_vector(5 downto 0);
		I_WC: in std_logic_vector(15 downto 0);
		I_PAYLOAD_DV: in std_logic_vector(1 downto 0);
		I_PAYLOAD: in std_logic_vector(15 downto 0);
		O_FV: out std_logic;
		O_LV: out std_logic;
		O_PIXEL: out std_logic_vector(15 downto 0)
	);
end component;
 
  
begin 

MyMIPI: mipi_rx
 	port map (
 		reset_n => RESET,
 
 		HS_CLK_P => CLK_P,
 		HS_CLK_N => CLK_N,
 
 		HS_DATA1_P => DATA_2_P ,
 		HS_DATA1_N => DATA_2_N ,
 		
 		HS_DATA0_P => DATA_P,
 		HS_DATA0_N => DATA_N,
 		
 		ready => Mipi_Ready,
 		clk_byte_out => Mipi_Data_Read_Clk,
 		data_out1 => Mipi_Data_Out1,
 		data_out0 => Mipi_Data_Out0,
 		
 		hs_en => MipiEn,
 		clk_term_en => '1',
 		data_term_en => '1'	
 	);  
	  
  cam1_reader: MIPI_DSI_CSI2_RX_Top
	port map (
		I_RSTN => RESET,				
		I_REF_DT => I_REF_DataType,
		
		I_BYTE_CLK => Mipi_Data_Read_Clk,
		I_READY => Mipi_Ready,
		I_DATA0 => Mipi_Data_Out0,
		I_DATA1 => Mipi_Data_Out1,
		
		O_SP_EN => O_ShortPack_EN,
		O_LP_EN => O_LongPack_EN,
		O_LP_AV_EN => O_DataTypeMatch_EN,
		O_ECC_OK => O_ECC_OK,
		O_ECC => O_ECC,		
		O_VC => O_ChanelID, 
		
		O_DT => DataType,
		O_WC => PayloadDataCnt,
		O_PAYLOAD => PAYLOAD,
		O_PAYLOAD_DV => PAYLOAD_DV
	);

ca1_pix_conv: MIPI_Byte_to_Pixel_Converter_Top
	port map (
		I_RSTN => RESET,
		I_BYTE_CLK => Mipi_Data_Read_Clk,
		
		I_SP_EN => O_ShortPack_EN,
		I_LP_AV_EN => O_LongPack_EN,
		
		I_DT => DataType,
		I_WC => PayloadDataCnt,		
		I_PAYLOAD_DV => PAYLOAD_DV,
		I_PAYLOAD => PAYLOAD,
		
		I_PIXEL_CLK => I_Pix_Clk,
		O_FV => O_FrameValid,
		O_LV => O_LineValid,
		O_PIXEL => O_PixData
	);
  
 
  

end architecture;

 

После настройки камеры и включения этот светодиод начинает мигать с разной периодичностью. Я так понимаю это означает что с камеры идет полноценный поток, он корректно дешифруется и обрабатываются пакеты и по итогу система даже достает пиксели из пакетов.

Далее я укладываю их в оперативу и затем считываю на комп.

 

Оператива проверена следующим образом:

Создан процесс со счетчиком на частоте 28мгц. и он просто на каждом такте увеличивает значение и подает его на вход оперативы. 

На компе при считывании я вижу правильные данные от 1 до 255 . 

 

Но если я завожу сигнал O_PixData с конвертера то на компе какая то хрень происходит. Данные в основном идут 0xff.

Пробовал визуализировать и вот что получается:

image.thumb.png.e43fec0c848feee75645afced192c845.png

 

Что это за хрень то? и главное почему так?

Настройки камеры я взял с файла который китайцы предоставили.

          arx.WriteRegister(d3xxDevice, 0x0304, 2);  // : 2 = 24
          arx.WriteRegister(d3xxDevice, 0x0306, 32); // x 32 = 768 = vt_pix_clk
          arx.WriteRegister(d3xxDevice, 0x0302, 1);  // 1
          arx.WriteRegister(d3xxDevice, 0x0300, 9);  // vt_pix_clk / 4 = 192 Мгц = OP_SYS_CLK
          arx.WriteRegister(d3xxDevice, 0x030A, 1);  // 1
          arx.WriteRegister(d3xxDevice, 0x0308, 9);  // vt_pix_clk / 8 = 24 Мгц = op_pix_clk


          arx.WriteRegister(d3xxDevice, 0x31B0, 0x0047); // FRAME_PREAMBLE
          arx.WriteRegister(d3xxDevice, 0x31B2, 0x0026); // LINE_PREAMBLE
          arx.WriteRegister(d3xxDevice, 0x31B4, 0x328C); // MIPI_TIMING_0
          arx.WriteRegister(d3xxDevice, 0x31B6, 0x32E8); // MIPI_TIMING_1
          arx.WriteRegister(d3xxDevice, 0x31B8, 0x1C12); // MIPI_TIMING_2
          arx.WriteRegister(d3xxDevice, 0x31BA, 0x1452); // MIPI_TIMING_3
          arx.WriteRegister(d3xxDevice, 0x31BC, 0x8488); // MIPI_TIMING_4


          arx.WriteRegister(d3xxDevice, 0x31E0, 0x00F1); // PIX_DEF_ID
          arx.WriteRegister(d3xxDevice, 0x31E6, 0xA35F); // PIX_DEF_ID_2 
          arx.WriteRegister(d3xxDevice, 0x3120, 0x0001); // GAIN_DITHER_CONTROL
          arx.WriteRegister(d3xxDevice, 0x301E, 0x002A); // DATA_PEDESTAL_

          arx.WriteRegister(d3xxDevice, 0x0344, 0x0004); // X_ADDR_START
          arx.WriteRegister(d3xxDevice, 0x0346, 0x0004); // Y_ADDR_START
          arx.WriteRegister(d3xxDevice, 0x0348, 0x0233); // X_ADDR_END        559
          arx.WriteRegister(d3xxDevice, 0x034A, 0x0233); // Y_ADDR_END        559
          arx.WriteRegister(d3xxDevice, 0x034C, 0x0230); // X_OUTPUT_SIZE     560
          arx.WriteRegister(d3xxDevice, 0x034E, 0x0230); // Y_OUTPUT_SIZE     560
          arx.WriteRegister(d3xxDevice, 0x3040, 0x0041); // READ_MODE
          arx.WriteRegister(d3xxDevice, 0x30A4, 0x0001); // Y_EVEN_INC_
          arx.WriteRegister(d3xxDevice, 0x0342, 0x02F8); // LINE_LENGTH_PCK   760
          arx.WriteRegister(d3xxDevice, 0x0340, 0x0248); // FRAME_LENGTH_LINES    584
          arx.WriteRegister(d3xxDevice, 0x3012, 0x0107); // COARSE_INTEGRATION_TIME_


          // RAW format 8bit
          arw = arx.ReadRegister(d3xxDevice, 0x0112);
          arx.WriteRegister(d3xxDevice, 0x0112, 0x0808); // RAW 8bit 

          // // 2lane format
          // arw = arx.ReadRegister(d3xxDevice, 0x31AE); // формат 2-lane
          // arx.WriteRegister(d3xxDevice, 0x31AE, 0x0202);
          //
          // режим тестового вывода BAR monochrome
          arw = arx.ReadRegister(d3xxDevice, 0x3070);
          arx.WriteRegister(d3xxDevice, 0x3070, 3); // BAR monochrome

Единственное тут есть параметры:

REG= 0x31B0, 0x0047 // FRAME_PREAMBLE
REG= 0x31B2, 0x0026 // LINE_PREAMBLE

Но я в настройках корки нигде не увидел задание этих параметров. Как их использовать то?

 

Даже специально включил BAR monochrome чтобы данные шли понятные. 

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

ARX3A0_MIPI_2LANE_560X560.ini

Даже не знаю куда думать. (( 

Может у кого есть какие нибудь идеи что происходит?? 

 

 

 

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

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


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

Quote

После настройки камеры и включения этот светодиод начинает мигать с разной периодичностью. Я так понимаю это означает что с камеры идет полноценный поток, он корректно дешифруется и обрабатываются пакеты и по итогу система даже достает пиксели из пакетов.

Нет. 

3 модуля последовательно. С непонятной работоспособность. Что могло пойти не так ...

 

Отлаживать поэтапно. Как минимум - писать тестбенч и смотреть реакцию модулей.

А лучше - поэтапная отдадка. С выводом данных на логический анализатор. Встроенный или внешний. 

Подключаем 1 ядро. Смотрим что на выходе. Как формируется кадр. И что там вообще формируется.

Далее подключаем 2 ядро  - смотри выход. Адекватные данные?

Ни и 3 ядро аналогично. 

 

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


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

Возьмите сохраните какую то область изображения в  блочной памяти или не несколько строк (посмотрите есть ли реакция на свет - писксели меняют значения)

потом данные передайте на комп например через юарт например

или посмотрите на них в внутрисхемном отладчике 

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

потом тоже самое после вычитки с ddr памяти

 

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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