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

Как правильно синхронизировать SGDMA?

Здравствуйте, коллеги!

Вот такая связка:

 

АЦП-----ОБРАБОТКА-----FIFO-----SGDMA----NIOSII

 

Вопрос не по реализации, с ней все нормально, а по алгоритму. Дело в том, что здесь АЦП производит 256 измерений последовательно от 256 разных каналов и т.д. по кругу. Важен порядковый номер каждого байта, принятого в буфер ДМА.

 

Если по каким-то причинам пропускаетcя байт от АЦП, буфер теряет синхронность, нулевой байт уже не соответствует нулевому каналу и возникает “кольцевой” сдвиг. Причем этот сдвиг остается и при следующем трансфере.

 

Как с этим бороться? Нужно придумать механизм самосинхронизации.

 

Дополнительно нумеровать байты очень не хочется (например, можно добавить один бит и выставлять его только для нулевого канала). Сбрасывать фифо не получается, т.к. оно заполняется непрерывно; в прерывании, возникающем по окончании ДМА трансфера этого делать нельзя, потому что фифа уже начала заполняться новыми данными.

 

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

 

Спасибо!

NJ

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


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

Здравствуйте, коллеги!

Вот такая связка:

 

АЦП-----ОБРАБОТКА-----FIFO-----SGDMA----NIOSII

 

Вопрос не по реализации, с ней все нормально, а по алгоритму. Дело в том, что здесь АЦП производит 256 измерений последовательно от 256 разных каналов и т.д. по кругу. Важен порядковый номер каждого байта, принятого в буфер ДМА.

 

Если по каким-то причинам пропускаетcя байт от АЦП, буфер теряет синхронность, нулевой байт уже не соответствует нулевому каналу и возникает “кольцевой” сдвиг. Причем этот сдвиг остается и при следующем трансфере.

 

Как с этим бороться? Нужно придумать механизм самосинхронизации.

 

Дополнительно нумеровать байты очень не хочется (например, можно добавить один бит и выставлять его только для нулевого канала). Сбрасывать фифо не получается, т.к. оно заполняется непрерывно; в прерывании, возникающем по окончании ДМА трансфера этого делать нельзя, потому что фифа уже начала заполняться новыми данными.

 

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

 

Спасибо!

NJ

 

 

АЦП пишет в промежуточный буфер, далее проверяем количество записей. Если количество соответствует, переписываем их в кольцевой буфер. Придется добавить еще один буфер и еще один ДМА.

И еще вопрос, по каким причинам АЦП может не выдать байт?

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

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


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

Если по каким-то причинам пропускаетcя байт от АЦП, буфер теряет синхронность, нулевой байт уже не соответствует нулевому каналу и возникает “кольцевой” сдвиг. Причем этот сдвиг остается и при следующем трансфере.

 

Как с этим бороться? Нужно придумать механизм самосинхронизации.

Можно использовать разбивку на пакеты(добавить, соответственно, пару сигналов к Avalon-stream). SGDMA вроде как умеет принимать по одному пакету на дескриптор, если в дескрипторе указана нулевая длина(потенциальная дыра в безопасности доступа к памяти, хм).

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


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

АЦП пишет в промежуточный буфер, далее проверяем количество записей. Если количество соответствует, переписываем их в кольцевой буфер. Придется добавить еще один буфер и еще один ДМА.

О времена.... банальный 2D буфер (5 минут работы) решит все проблемы, без кучи всякой обвески

 

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


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

О времена.... банальный 2D буфер (5 минут работы) решит все проблемы, без кучи всякой обвески

..а что такое - 2D буфер ?

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


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

О времена.... банальный 2D буфер (5 минут работы) решит все проблемы, без кучи всякой обвески

Еще раз спасибо за идею. Я использовал Onchip Memory в режиме Dual-port access. Второй порт выведен из ниоса, в него пишутся данные и по окончанию цикла генерируется прерывание.

 

Все получилось в разы компактнее и проще, чем с ДМА. Конечно, такое пройдет только с Ниосом, куда возможно встроить блок.

 

NJ

 

И еще вопрос, по каким причинам АЦП может не выдать байт?

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

 

АЦП не может не выдать. Может случиться, что его не заберет ДМА и ФИФО не опустошится. Тогда лишние байты в ФИФО останутся навсегда, если не принять никаких мер. (Или заберет не все байты, т.к. ДМА каждый цикл надо перезапускать из софта. Сделать режим Ping-Pong без управления ДМА из прерывания у меня не получилось)

 

NJ

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


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

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

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

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

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

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

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

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

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

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