|
Передача данных из SPI в SPI, Подскажите как лучше |
|
|
|
Mar 31 2015, 06:12
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 1-02-12
Из: Екатеринбург
Пользователь №: 70 003

|
Всем доброго времени суток! Подскажите, как лучше организовать систему. Система в целом выглядит так: Есть софт процессор NiosII - он выполняет основные задачи: отвечает на запросы пользователя, принимает какие-то данные, обрабатывает их, выдает ответы и прочее. Также есть два SPI: SPI1 - он принимает данные из вне как только вся система запустилась и SPI2 в который мне нужно эти данные (определенное количество) выплюнуть (этот SPI от Ethernet платки). Получается, что мне нужно постоянно гнать данные из SPI1 в SPI2. Причем, иногда мне нужно в этот поток данных добавлять еще байт своих данных. Как это можно организовать с минимальным участием проца? Чтобы он успевал делать свою основную работу и меньше отвлекался на эту передачу? Может есть какая-то переферия для таких задач? Подскажите куда посмотреть? Частота работа Niosa 100MГц, а данные на SPI1 приходят с частотой 24Мгц. Пока у меня рисуется стандартный вариант: по прерыванию на прием по SPI1 я через DMA записываю поступившие данные в память, как только пришло необходимое кол-во байт, выставляю флаг. И в основном цикле программы по этому флагу отправляю эти данные в SPI2.
|
|
|
|
|
Mar 31 2015, 06:37
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 21-11-12
Из: Россия г. Санкт-Петербург
Пользователь №: 74 498

|
Цитата(prussta @ Mar 31 2015, 09:12)  Всем доброго времени суток! Подскажите, как лучше организовать систему. Система в целом выглядит так: Есть софт процессор NiosII - он выполняет основные задачи: отвечает на запросы пользователя, принимает какие-то данные, обрабатывает их, выдает ответы и прочее. Также есть два SPI: SPI1 - он принимает данные из вне как только вся система запустилась и SPI2 в который мне нужно эти данные (определенное количество) выплюнуть (этот SPI от Ethernet платки). Получается, что мне нужно постоянно гнать данные из SPI1 в SPI2. Причем, иногда мне нужно в этот поток данных добавлять еще байт своих данных. Как это можно организовать с минимальным участием проца? Чтобы он успевал делать свою основную работу и меньше отвлекался на эту передачу? Может есть какая-то переферия для таких задач? Подскажите куда посмотреть? Частота работа Niosa 100MГц, а данные на SPI1 приходят с частотой 24Мгц. Пока у меня рисуется стандартный вариант: по прерыванию на прием по SPI1 я через DMA записываю поступившие данные в память, как только пришло необходимое кол-во байт, выставляю флаг. И в основном цикле программы по этому флагу отправляю эти данные в SPI2. Мне кажется тут проще иметь столько буферных хранилишь для данных, сколько типов данных. Т.о. в момент готовности передать в SPI2 нужно взять в соответствии с протоколом данные из разных буферных хранилищь и передать. В качестве хранилишщь удобно использовать FIFO. Если функционально расписать по блокам: 1)блоки FIFO; 2) простенький блочек, который соберет в кучу данные с разных FIFO в соответствии с протоколом; 3) SPI передатчик. FIFO может заполняться с различной частотой, а вычитываться из всех FIFO будет с одной частотой равной частоте передачи данный SPI2. В итоге процессор сможет в режиме прямого доступа в память все сливать в своё FIFO, другие типы памятей тоже заполнятся как им будет удобно, а все вычитываться будет строго со скоростью SPI2. ИМХО
--------------------
Победа - это когда N раз упал и N+1 раз встал.
|
|
|
|
|
Mar 31 2015, 07:11
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 1-02-12
Из: Екатеринбург
Пользователь №: 70 003

|
Цитата 2) простенький блочек, который соберет в кучу данные с разных FIFO в соответствии с протоколом; я правильно понимаю, что этот блочек это просто небольшая функция, которую будет выполнять тот же NiosII в основном цикле?
|
|
|
|
|
Mar 31 2015, 07:19
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 21-11-12
Из: Россия г. Санкт-Петербург
Пользователь №: 74 498

|
Цитата(prussta @ Mar 31 2015, 10:11)  я правильно понимаю, что этот блочек это просто небольшая функция, которую будет выполнять тот же NiosII в основном цикле? Можно и процессором, но мне кажется fpga здесь разумней выбрать. Все что я описал я предполагал реализовать на fpga Цитата(prussta @ Mar 31 2015, 10:11)  я правильно понимаю, что этот блочек это просто небольшая функция, которую будет выполнять тот же NiosII в основном цикле? Если не ясно как его реализовать, тогда спрашивайте...поясню
--------------------
Победа - это когда N раз упал и N+1 раз встал.
|
|
|
|
|
Mar 31 2015, 07:26
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 1-02-12
Из: Екатеринбург
Пользователь №: 70 003

|
Цитата(Dmitriyspb @ Mar 31 2015, 13:19)  Можно и процессором, но мне кажется fpga здесь разумней выбрать. Все что я описал я предполагал реализовать на fpga
Если не ясно как его реализовать, тогда спрашивайте...поясню Так я и так реализую на fpga, использую софтпроцессор NiosII для управления всей подключенной переферией - SPI, FIFO, DMA и т.д. Делаю на Cyclone III. Или я не так понимаю? Цитата Если не ясно как его реализовать, тогда спрашивайте...поясню Поясните, пожалуйста
|
|
|
|
|
Mar 31 2015, 07:46
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 21-11-12
Из: Россия г. Санкт-Петербург
Пользователь №: 74 498

|
Цитата(prussta @ Mar 31 2015, 10:26)  Так я и так реализую на fpga, использую софтпроцессор NiosII для управления всей подключенной переферией - SPI, FIFO, DMA и т.д. Делаю на Cyclone III. Или я не так понимаю? Тогда я все верно понял. Цитата(prussta @ Mar 31 2015, 10:26)  Поясните, пожалуйста У вас есть допустим 2 FIFO. 1-ая (FIFO1) заполняется процессором в режиме DMA, а вторая с порта SPI1 (FIFO2). (На этом этапе необходимо разобраться с принципом FIFO и организацией DMA.) Как известно FIFO позволяет согласовывать различные клоковые домена. В вашем случае можно предположить 3 клоковых домена, а именно 1-ый ПРОЦЕССОРНЫЙ, 2-ой SPI1, 3-ий SPI2. Т.е. в FIFO1 с удобной скоростью для процессора, в FIFO2 пишется с скоростью прихода данных от SPI1, а SPI2 загружаются данные с удобной для SPI2 скоростью. ________________________________________________________________________________ __________________________________________________________ Мы разобрались как записать в память. Теперь разберемся как из нее вычитать. Вычитываем из памятей FIFO1, FIFO2 c скоростью SPI2. Но так как мы передаем данные от двух источников (FIFO1, FIFO2) необходимо вычитанные данные миксовать необходимым образом (это из протокола SPI2 видно). Если микс реализовать на verilog, тогда это будет цикл case. ___________________________________________ уточняйте свой вопрос. Что именно не ясно?
--------------------
Победа - это когда N раз упал и N+1 раз встал.
|
|
|
|
|
Mar 31 2015, 09:02
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 21-11-12
Из: Россия г. Санкт-Петербург
Пользователь №: 74 498

|
Цитата(prussta @ Mar 31 2015, 11:54)  Я просто не пишу на аппаратных языках, поэтому и забыла про этот вариант и рассматривала стандартные компоненты, которые уже есть. Схемотехническом редакторе? рисуете схемки?
--------------------
Победа - это когда N раз упал и N+1 раз встал.
|
|
|
|
|
Mar 31 2015, 09:40
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 1-02-12
Из: Екатеринбург
Пользователь №: 70 003

|
Цитата(Dmitriyspb @ Mar 31 2015, 15:02)  Схемотехническом редакторе? рисуете схемки? Да, иногда приходится и этим заниматься))
|
|
|
|
|
Apr 3 2015, 11:10
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 1-02-12
Из: Екатеринбург
Пользователь №: 70 003

|
Цитата У вас есть допустим 2 FIFO. 1-ая (FIFO1) заполняется процессором в режиме DMA, а вторая с порта SPI1 (FIFO2). Dmitriyspb, а как вы предлагаете с порта SPI1 заполнять FIFO2? Есть варианты его заполнения без участия процессора? Даже если использовать DMA, то получается, что надо при приходе данных в регистр SPI1 нужно вызывать ф-ию alt_dma_rxchan_prepare(...), чтобы DMA передал эти данные в FIFO2 . Можно ли как-нибудь это обойти? В идеале хотелось бы так настроить передачу, чтобы данные приходя в SPI1 сразу бы записывались в FIFO2, и проц при этом не беспокоить.
|
|
|
|
|
Apr 3 2015, 11:45
|
Частый гость
 
Группа: Свой
Сообщений: 139
Регистрация: 3-04-13
Пользователь №: 76 333

|
Цитата(prussta @ Apr 3 2015, 14:10)  Dmitriyspb, а как вы предлагаете с порта SPI1 заполнять FIFO2? Есть варианты его заполнения без участия процессора? Даже если использовать DMA, то получается, что надо при приходе данных в регистр SPI1 нужно вызывать ф-ию alt_dma_rxchan_prepare(...), чтобы DMA передал эти данные в FIFO2 . Можно ли как-нибудь это обойти? В идеале хотелось бы так настроить передачу, чтобы данные приходя в SPI1 сразу бы записывались в FIFO2, и проц при этом не беспокоить. вы настоящий программист  . не проще сделать отдельный контроллер, реализующий запись SPI1->FIFO2, который снимет с процессора эту задачу? SPI протокол известен, скорость записи в фифо гораздо выше скорости SPI. все сведется к сдвиговому регистру, собирающего слова от SPI, и выставляющим строб записи для фифо как только это слово будет собрано
|
|
|
|
|
Apr 5 2015, 08:40
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 1-02-12
Из: Екатеринбург
Пользователь №: 70 003

|
Да, подобное и нужно)) контроллер этот как реализовать? написать на аппаратном языке?
|
|
|
|
|
Apr 6 2015, 07:49
|
Частый гость
 
Группа: Свой
Сообщений: 139
Регистрация: 3-04-13
Пользователь №: 76 333

|
с фифошкой никогда плотно не работал, но на скорую руку набросал логику фунциклирования - как себе это представляю. в принципе осталось только порты прописать и разобраться с фифо и ее подключить. зы переменные в капсе - ин/аут порты, строчные - внутренние переменные ззы отцы-профессионалы, поправьте меня если что - сам то я начинающий лошарик  CODE process (CLK_SPI) rgs:std_logic_vector(31 downto 0); ct:std_logic_vector(4 downto 0); begin if CLK_SPI'event and CLK_SPI='1' then if CS_SPI='1' then rgs(31 downto 0)<=rgs(30 downto 0)&IN_SPI after 100 ps; else rgs<=rgs after 100 ps; end if; if CS_SPI='1' then ct<=ct+1 after 100 ps; else ct<=ct after 100 ps; end if; end if; end process;
data_ready_spi<= '1' when ct="11111" else '0'; process (CLK_FIFO) data_ready_fifo, data_ready_fifo_d:std_logic; begin if CLK_FIFO'event and CLK_FIFO='1' then data_ready_fifo<=data_ready_spi after 100 ps; data_ready_fifo_d<=data_ready_fifo after 100 ps; if RESET='1' then WREN_FIFO<='0' after 100 ps; elsif data_ready_fifo='1' and data_ready_fifo_d='0' then WREN_FIFO<='1' after 100 ps; else WREN_FIFO<=WREN_FIFO after 100 ps; end if; DATA_FIFO<=rgs after 100 ps; end if; end process;
тут же первый косячок - надо следить за тем чтобы данные всегда были по 32 бита - иначе собьется насчет в счетчике, из-за того что он привязан к синхре SPI, а она появляется уже после того как выставится CS_SPI. в общем стоит вопрос обнуления счетчика
Сообщение отредактировал GAYVER - Apr 6 2015, 07:50
Эскизы прикрепленных изображений
|
|
|
|
|
Apr 6 2015, 08:24
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 21-11-12
Из: Россия г. Санкт-Петербург
Пользователь №: 74 498

|
Цитата(prussta @ Apr 5 2015, 11:40)  Да, подобное и нужно)) контроллер этот как реализовать? написать на аппаратном языке? Для Вас это задача сложная потому, что вы не совсем разобрались с такими ресурсами как: 1. Система на кристалле (что такое и для чего она была рождена на свет) 2. FPGA - принцип реализации КЦУ и ПЦУ на базе ПЛИС. Не суть важно как вы будете реализовывать контроллер записи/чтения. Можно в схемотехническом редакторе нарисовать или же описать работу устройства используя языки программирования HDL. ________________________________________________________________________________ _____ И САМОЕ ГЛАВНОЕ!!!!!!!!! Срочно нарисуйте структуру, того устройства который разрабатывайте. Укажите задачи которые решает процессор, а какие решает fpga. Иначе Ваш монстр погибнет в зачатом состоянии. Разберитесь с принципом работы Вашего будущего устройства на функциональном уровне. И желательно бы знать особенности программирования на ПЛИС. Потому как (К БОЛЬШОМУ СОЖАЛЕНИЮ ВСЕГО СООБЩЕСТВА ПРОГРАММИСТОВ) программировать FPGA и программировать процессор вещи достаточно сильно разные. ________________________________________________________________________________ __ Вернемся к вашим вопросам. Spi приёмники и передатчики, fifo также удобно реализовать на плис. А задача организации процесса записи в память или передатчик - это достаточно простая задача требующая конкретных вопросов. _______________________________________________________________________________ Поэтому рекомендую реализовать FIFO, SPI_TX, SPI_RX по отдельности на базе FPGA. А блок (контроллер) обеспечивающий запись и чтение для сопряжения процессора, FIFO, SPI_TX, SPI_RX реализовывать имея конкретные сигналы и вопросы.
--------------------
Победа - это когда N раз упал и N+1 раз встал.
|
|
|
|
|
Apr 6 2015, 11:28
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 1-02-12
Из: Екатеринбург
Пользователь №: 70 003

|
Цитата(Dmitriyspb @ Apr 6 2015, 14:24)  Для Вас это задача сложная потому, что вы не совсем разобрались с такими ресурсами как: ...... Dmitriyspb, да Вы правы, что-то разрабатывать на ПЛИС приходится впервые, поэтому много темных мест)) и спаисбо за советы! Цитата(Dmitriyspb @ Apr 6 2015, 14:24)  программировать FPGA и программировать процессор вещи достаточно сильно разные. да, знаю, я только обзорно знакома с аппаратными языками, поэтому и возникают "новичковые" вопросы) программировать fpga сама не буду(если что). А здесь же хотелось получить альтернативные идеи по общей организации системы, потому что мои идеи не удались. Я так понимаю, что без блока на fpga, организующего прием данных с SPI1 не обойтись, потому что если данные идут постоянно, то программа все время "висит" в обработчике прерывания по приему SPI1 и даже не выходит в основной цикл. ( Это я попробовала при помощи Niosа принимать) Хотя не совсем мне понятно почему так, ведь данные идут с частотой 30 Мгц, а процессор работает на 157МГц. Почему он не успевает выходить в основной цикл? В прерывании только считываю пришедшие данные. Неужели так много занимает это времени....хмм...
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|