Easyelectronics.ru

Электроника для всех
Текущее время: 23 сен 2019, 23:28

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 11 ] 
Автор Сообщение
 Заголовок сообщения: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 22 июл 2019, 23:39 
Только пришел

Зарегистрирован: 30 окт 2018, 22:52
Сообщения: 9
Что нужно: периодические платные консультации с оплатой за час и возможностью вместе отсматривать прототип устройства (если это понадобится). Поэтому территориально - СпБ.

Кто нужен: человек, который четко ткнет в проблемы, потому что уже знает, что делать и не раз делал подобное. Есть затык, надо пройти стадию этого затыка - ключевое в том, что пройти надо самому. Учусь, интересно, все дела.

Подобное означает работу с real-time передачей звука на 2.4 ГГц с использованием своего протокола, задержками порядка 5-10ms, скорее всего это CCшники от TI в связке с I2S.

Что за прототип:

Хочу повторить вот эту железку, передача/прием звука на 2.4ГГц, 24 бита, 48Кгц, моно-канал. На ней связка A7190 (Amicom RF transceiver, 4mbps, до 512 байт на пакет, куча всяких плюшек), STM32, кодек. В моем случае конфигурация такая:

- STM32F103RCT6
- PCM5102 DAC на воспроизведение
- PCM1802 на снятие звука
- По одному A7190 на прием/передачу
- SSD1306 на I2C чисто для мониторинга.

Прототип собран на основе готовых модулей. Ссылки на модули выше, модули собраны в бутердрод на stmке.

Что работает:

Да все работает, только нестабильно. Передатчик/приемник нормально передает/принимает на скорости в среднем 2.3mbps, чего с лихвой хватает на моноканал 24бита/46785Гц. DMA, размер пакета данных в 512байт, без CRC, без пересылки, потери в 30 пакетов в секунду в среднем, что кажется некритичным. Стабильность передачи проверена, тупо своим небольшим протоколом, проверяющим последовательность данных.

Звук пересылается / принимается. I2S тоже на DMA, прямой стриминг с ADC на DAC отрабатывает корректно и без проблем. Работа со звуком в коллбэках HAL, отображение информации на экране / пересылка данных раскиданы по таскам FreeRTOS. Использую HAL (да, о ужас, но проблем я с ним в итоге не получил).

В чем проблема:

Неформально проблема в том, что через 10-15 секунд передачи начинает появляться черт пойми откуда взявщаяся циклическая помеха - нарастающий шум, ухудшение звука, которая уходит секунд через 20 с возвратом к нормальному чистому звуку. Далее ситуация повторяется. Проблема не в питании - питание проверено на 300 раз и от его корректности помеха не исчезает. Проблема не в канале - пробовал разные, но смена никак не влияет на ситуацию.

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

Здесь становится понятно, что я изобретаю колесо и проблема должна решаться каким-то стандартным способом, но я не понимаю, как здесь сделать синхронизацию железобетонно средствами HAL/FreeRTOS. Разработкой занимаюсь на выходных, год вылетел на то, чтобы дойти до именно такой конфигурации и разобраться с I2S/DMA/FreeRTOS и испробовать все, что мог - дальше нужна помощь и надо сократить засчет нее время.

Доступ к коду организую.


Последний раз редактировалось yeswolf 23 июл 2019, 20:34, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 23 июл 2019, 00:23 
Старожил

Зарегистрирован: 08 июн 2015, 16:26
Сообщения: 353
Ох, ща бует мясо.

Первое: для обработки звука в риалтайме - выкинуть нафиг FreeRTOS и HAL. С такими аппетитами - только обработка в прерывании проканает. Работа со звуком, да еще с потоками 2.3 Mbps - это не для FreeRTOS. А все остальное уже можно и в таски запихнуть, с меньшим приоритетом.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 23 июл 2019, 07:44 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 3624
А мы раньше сами по книжкам учились...
А ваша помеха связана с кольцевыми буферами. Вы должны использовать двойную буферизацию. Заполняется первая половина буфера - передается вторая половина. Заполняется вторая половина - передается первая половина. И так же на приемнике, при загрузке в ЦАП. Причем, вы должны настроить скорости таким образом, чтобы ничего не налезало друг на друга. Помеха связана со сбиванием цикличности.
Ну а RTOS еще и усугубляет дело своими издержками. В последнее время стало распространяться ошибочное представление о RTOS, как о системе "реального" времени. На деле она работает с квантованием и на маломощных МК забирает на себя чуть ли не половину ресурсов. Особенно, если неправильно организована работа с очередями - то есть передача всего буфера через очередь - в этом случае дважды теряется время на копирование буфера.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 23 июл 2019, 08:58 
Заглядывает иногда

Зарегистрирован: 17 сен 2018, 07:24
Сообщения: 44
Скорее всего проблема в том, что у двух модулей stm32 немного отличается частота кварца (который 8mhz).
I2S на передачу может быть 48.01Кгц, а на приём 49.99Кгц, тут получится переполнение приёмного буфера. Или наоборот, тогда получится недостаточное заполнение буфера. В случае использования circular dma режима это как раз будет проявляться в периодическом появлении звукового глюка, который будет нарастать и спадать.

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

Пример:
Приёмный буфер с A7190: 1000 + 1000 + 1000 байт
Буфер на воспроизведение по i2s 1000 + 1000 байт (кольцевой на 2000 байт)
Битовая маска заполнения данными приёмных буферов с a7190: 111

1. i2s dma halfcplt, копируем данные из буфера a7190 в первую половину i2s dma tx буфера. Маска заполнения 110
2. i2s dma cplt, копируем данные из буфера a7190 во вторую половину i2s dma tx буфера. Маска заполения 100
3. i2s dma halfcplt, копируем данные из буфера a7190 в первую половину i2s dma tx буфера. Маска заполнения 000
4. i2s dma cplt, копируем данные из буфера a7190 во вторую половину i2s dma tx буфера. Маска заполения 000 - возникновение проблемы, нету ни одного до конца заполненного массива.

Можно попробовать всегда "растягивать" данные так, чтобы в приёмном буфере с A7190 было как минимум два заполненных блока.
Т.е. на втором шаге, т.к. маска заполнения стала 100, мы принудительно растягиваем данные в третьем массиве (маска заполнения 101), а новые данные теперь принимаем во второй массив (середина маски).
Растягивание можно делать линейной интерполяцией или даже без интерполяции, просто по индексам. Например 900 байт превратить в 1000 байт.

Если скорость передатчика выше, то нельзя допускать ситуации, когда маска заполнения 111.
Буфер на приём возможно имеет смысл сделать побольше. Куски необязательно 1000 байт, тут нужно подумать как лучше нарезать. Ниже приведу пример с тремя наборами буферов:

1) Приёмный буфер 1500 + 1500 байт (размер с запасом на случай если идёт передатчик быстрее, чем приёмник).

2) Промежуточный буфер
1000 + 1000 + 1000 (маска заполнения 111)

3) I2S DMA буфер на воспроизведение:
1000 + 1000

1. Итак, включили питание, включили i2s, начинается заполнение буфера на 1500 байт
2. срабатывает i2s halfcplt. Не важно на сколько заполнился первый набор 1500 байт, запись принятых данных сразу переключается на второй набор из 1500 байт
3. копируем данные из первого набора 1500 байт в промежуточный буфер. Если из 1500 байт заполнено 900 байт, то растягиваем до 1000. Если заполнено 1200, то сжимаем до 1000 байт и записываем в промежуточный буфер.
4. срабатвает i2s cplt. Не важно на сколько заполнился второй набор в 1500 байт, запись принятых данных сразу переключается на первый набор из 1500 байт
5. копируем данные из второго набора 1500 байт в промежуточный буфер. Если из 1500 байт заполнено 900 байт, то растягиваем до 1000. Если заполнено 1200, то сжимаем до 1000 байт и записываем в промежуточный буфер

Т.е. получается синхронизация по i2s cplt/halfcplt, которая жестко подготавливает себе промежуточный буфер. Маска заполнения промежуточного буфера при каждом i2s cplt/halfcplt будет меняться следующим образом
halfcplt: 111 -> 110 -> 111
cplt: 111 -> 101 -> 111
halfcplt 111 -> 011 -> 111
cplt: 111 -> 110 -> 111
и т.д., т.е. как только мы взяли кусок 1000 байт (2) и скопировали его круговой буфер i2s dma (3), мы сразу же заполняем его новыми 1000 байт данными из приёмного буфера (1):

(1) Приёмный буфер 1500 + 1500 байт (размер с запасом на случай если идёт передатчик быстрее, чем приёмник).

(2) Промежуточный буфер
1000 + 1000 + 1000 (маска заполнения 111)

(3) I2S DMA буфер на воспроизведение:
1000 + 1000

Максимальная разница скорее всего будет максимум 2-3 сэмпла. Т.е. для простоты можно выбрасывать лишние 2 сэмпла (1002 сэмпла превратим в 1000), или копировать недостающие до 1000 (998 превратить в 1000, скопировав 998й в 999 и 1000-ный). На слух это скорее всего можно будет услышать как еле-заметное редкое потрескивание. Убрать потрескивание можно линейной интерполяцией, аналогично тому, как это делается для изоборажений.

update: забыл написать, что в пункте 2 и 4 по i2s halfcplt и cplt копируем данные из промежуточного буфера в i2s dma буфер.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 23 июл 2019, 19:42 
Только пришел

Зарегистрирован: 30 окт 2018, 22:52
Сообщения: 9
sdv_cyborg писал(а):
Ох, ща бует мясо.
Первое: для обработки звука в риалтайме - выкинуть нафиг FreeRTOS и HAL. С такими аппетитами - только обработка в прерывании проканает. Работа со звуком, да еще с потоками 2.3 Mbps - это не для FreeRTOS. А все остальное уже можно и в таски запихнуть, с меньшим приоритетом.


Пойду-ка я отредактирую сообщение, это у меня помутнение рассудка случилось, когда я написал, что "работа со звуком в тасках FreeRTOS". Нету ее там никакой, вру, обманываю - вся обработка (которая суть "выцепить моноканал из стерео") сидит в HalfCplt/Cplt. RTOS конечно же только отсылает/принимает готовый буфер и экран лопатит. И да, делал и без нее, и без экрана, нет никакой разницы, от слова "совсем", проблема та же.

BusMaster писал(а):
А мы раньше сами по книжкам учились...
А ваша помеха связана с кольцевыми буферами. Вы должны использовать двойную буферизацию. Заполняется первая половина буфера - передается вторая половина. Заполняется вторая половина - передается первая половина. И так же на приемнике, при загрузке в ЦАП.


Этот этап я прошел полтора месяца назад. Пробовал, без всяких RTOS, без экрана, было без разницы.

Но вообще пойду-ка я пробовать все опять и с учетом комментария Georgy.Moshkin ниже.

По ходу тему надо бы переносить в "Делаю", вот бы узнать, как.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 23 июл 2019, 20:00 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 3624
Ой, Жора там наворотил кучу кучищную, прями диссертацию напесал. А эта штука делается гораздо проще. Те же два буфера. Радиоканал передает буфер быстрее, чем его расходует ЦАП. И ЦАП перезапускается каждый раз, когда приходит новый буфер с радиоканала. То есть, буфер ЦАПа не работает циклически. Не пришли новые данные с радиоканала к моменту завершения буфера ЦАПом - ЦАП останавливается, не пытаясь читать в цикле тот же самый буфер повторно. И наоборот - данные с радиоканала пришли раньше, чем ЦАП закончил читать буфер - перезапускаем ЦАП с начала пришедшего буфера. Чем короче буферы, тем меньше остановок/пропусков из-за рассинхронизации. И вообще, рассинхронизация тут будет всегда, просто чем одинаковее частоты кварцев, тем больше период между пропусками/выпадениями.

Вот "веселые картинки" для иллюстрации работы, если текстом воспринимается сложно:
таким образом, в качестве синхросигнала выступает событие начала приема от радиоканала. На практике этим событием является прерывание от модуля радиоканала. Ну и чем короче буфер, тем меньше рассинхронизация между АЦП и ЦАП, но сильнее нагрузка на радиоканал (передатчик чаще выходит в эфир). В итоге, нам надо стремиться к возможно большей скорости радиоканала и передаче небольших размеров буфера.
И двух буферов, работающих попеременно, тут достаточно. Надо просто правильно организовать их работу. Об этом я и писал ранее!


Вложения:
000.png
000.png [ 20.18 Кб | Просмотров: 462 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 24 июл 2019, 08:35 
Заглядывает иногда

Зарегистрирован: 17 сен 2018, 07:24
Сообщения: 44
видимо сейчас так и сделано, но не реализована остановка (i2s), поэтому задержка накапливается и появляется глюк. Тут нужно смотреть как будет выглядеть этот перезапуск stm-ского i2s на его clk выходе, какова реакция pcm5102, а так вариант BusMaster-а самый простой и использует минимум памяти. Если с этим подходом будут проблемы, возможно это связано с "Clock Error Detect" http://www.ti.com/lit/ds/symlink/pcm5100.pdf (стр.24), хотя там запас по байтам достаточно большой.

Другая потенциальная проблема может быть из-за 512-байтового буфера и auto-ack auto-resend (в A7190). Не знаю как работают такие штуки, но скорее всего время между двумя пакетами по отправке и по приёму может быть разным. Эта проблема может скрываться в готовом изделии, которое при наличии определённой помехи начнёт раз через раз делать эти auto-resend-ы, и при простом подходе мы получим какую-нибудь трескотню. Будет весьма досадно, если A7190 успешно пропихнёт пакеты в условиях помех, но из-за синхронизации i2s по получению пакетов от A7190 получится прерывистый звук.

Так что тут есть о чём подумать, например использовать память stm32-приёмника по максимуму, не полагаться на время прихода пакета от A7190, пусть встроенный i2s stm32 диктует скорость. Для повышения надёжности я бы сжал данные перед отправкой целочисленным haar-ом, это сохранит всякие мелкие приятные слуху детали от 48кГц, и даст запас по времени буферизации.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 24 июл 2019, 10:52 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 3624
При передаче потоковый реал-таймовых данных всегда выключается повторная пересылка. Потерянные пакеты повторно не передаются. Нет смысла усложнять работу, ведь заранее неизвестно, на сколько времени пропадает связь. В комп.сетях так реализован протокол UDP, в котором, в отличие от TCP, не проверяется доставка пакетов. Поэтому, если к моменту исчерпания текущего буфера ЦАП не пришли новые данные, то работа ЦАП останавливается, а выходы ЦАП мьютируются, чтобы не было на них никакого сигнала. На слух это выглядит как прерывание звука - мы все это слышали в мобильном телефоне, когда связь нестабильна и звук "заикается".

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 24 июл 2019, 16:07 
Только пришел

Зарегистрирован: 30 окт 2018, 22:52
Сообщения: 9
Georgy.Moshkin писал(а):
видимо сейчас так и сделано, но не реализована остановка (i2s), поэтому задержка накапливается и появляется глюк.


В плане радиоканала - нет двойного буффера. Буффер одинарный на один пакет, сразу после получения копируется в буффер отправки, остановки на это время тоже нет. Потому что... Потому что попытки тормозить ЦАП привели к полному трэшу при circular. А отправка в normal mode не работает потому, что... потому что если я все верно понимаю, ее только по таймеру долбать в соответствии с частотой I2S, иначе ЦАП не реагирует, плюс все равно придется ему вмолачивать пустые буффера, чтобы не простаивал.

Georgy.Moshkin писал(а):
auto-ack auto-resend


Выключены, проверял. При них скорость передачи просаживается в разы, без шансов абсолютно.

BusMaster писал(а):
Ну и да, звук в PCM формате через радиоканал напрямую не передается. Его кодируют сжатием без потерь. Самый простой алгоритм - RLE, но для звука он непригоден, ибо в звуковых данных нет повторяющихся подряд значений. Поэтому, для потокоовго аудио повсеместно используют LZW-подобные алгоритмы.
Принцип работы остается практически прежний - приняли пакет с эфира, декодировали его, оправили в ЦАП.


Вот с одной стороны понимаю, с другой - нет. 24 бита (которые на деле 32 в STM32), да один канал, да 46875 сэмплов в секунду - это 1.5mbps. У меня таки пролезает сейчас 2.3mbps. Смысл его сжимать, если он даже так лезет? Или оно все-таки не должно быть критичным для этого случая?

BusMaster писал(а):
Поэтому, если к моменту исчерпания текущего буфера ЦАП не пришли новые данные, то работа ЦАП останавливается, а выходы ЦАП мьютируются, чтобы не было на них никакого сигнала.


Дебильный вопрос, но - я же верно понимаю, что в принципе - в принципе - я могу по отсутствию сигнала в первом приближении даже не вырубать ЦАП, а тупо занулять буффер и переставать его заполнять? Имеется в виду - потом-то понятно, что надо его вырубать в этом случае, но тут пока, как я понимаю, критично остановить DMA - отпроцессить перекидывание буффера - запустить DMA опять, верно?

И да, все равно ушел все переделывать, потому что уже вижу, что плохо все.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 24 июл 2019, 21:04 
Заглядывает иногда

Зарегистрирован: 17 сен 2018, 07:24
Сообщения: 44
Я думаю метод BusMaster-а следует применять без кругового буфера, DMA посылка определенной длины. По приходу пакета останавливать dma посылку.

Если уже надоело в этом разбираться, можно попробовать i2s на прерываниях. Для простоты завести два массива, пока один массив проигрывается,, второй ждёт поступления данных , по приходу пакетов обнулять счётчик проигранных сэмплов. Если новый массив ещё не пришел, зацикливать последнее значение из текущего массива. Я думаю справится контроллер, если нет других задач.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Нужен специалист консультировать - связка STM32/I2S/RF, СпБ
СообщениеДобавлено: 26 июл 2019, 17:44 
Только пришел

Зарегистрирован: 30 окт 2018, 22:52
Сообщения: 9
Оставлю для других, подобных мне, кто сильно торопится, вместо того, чтобы сесть и подумать.
Проблема уходит почти полностью, если организовать нормально двойную буфферизацию хотя бы в простейшем виде и слать ровно столько, сколько нужно в секунду для DAC. Как минимум, после разруливания двойного буффера воспроизведения/"записи" звука по HalfCplt/Cplt "в точку" и такого же пинг-понга на передаче/приеме остались только щелчки по мелочи.

Но уже ясно, что это решаемо. DMA circular в итоге не отключал, пока получилось сделать и на круговом буффере.

Буду дальше схлопываться до минимального проекта и отлаживаться, переводя на прерывания, либо одиночную посылку DMA.

Всем спасибо, но предложение все равно остается в силе :).


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 11 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB