• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос Генератор звука STM32F3-Discovery, ESP8266 и I2S

RRRLock

New member
Доброго времени суток!
Есть задача сделать генератор звуковых сигналов с помощью платы STM32F3-Discovery, затем по интерфейсу I2S передавать аудио-сигнал в ESP8266, по радио-каналу с использованием протокола UDP пересылать сигнал в компьютер и воспроизводить звук. Формат данных 24 бита, частота дискретизации 48 кГц. STM32F3 - мастер-передатчик, ESP - слэйв-приемник.
Пишу прошивку в Eclipse с использованием UDK. В папке с примерами есть проект I2S-Demo. Попробовал подправить проект под свои нужды, но столкнулся со следующими проблемами:

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

2. Данные с STM-ки приходят не полностью. Часть сообщения теряется, такое ощущение, что входной канал I2S в ESP8266 запрограммирован под другую тактовую частоту и частоту дискретизации. Так же есть мысль, что нет синхронизации по CLK, поскольку затактировал I2S в STM от PLL без кварца. Так же частота дискретизации получилась не 48 000 Гц, а 48 676 Гц. Может быть в этом дело?

Подскажите пожалуйста в чем может быть проблема?
 
Последнее редактирование:

RRRLock

New member
Занимался другим проектом и получил подвижки в этом. Запустил в непрерывном режиме передачу данных с использованием DMA с STM32F3-Discovery на модуль ESP8266 (ESP-07).
STM32F3 - master transmitter, ESP8266 - slave receiver. Формат передаваемых данных 24 бита, MSB-first, частота сэмплирования 48 кГц, размер одного передаваемого буфера 128 отсчетов. Каждая ячейка буфера передатчика заполнена тестовым числом 0x0300bb55. Результаты в виде 10 отчетов приемного буфера вывожу на терминал. Получается вот такая вот картина. Нечетные ячейки буфера приемника заполняются "почти" таким же числом, которое я отправлял, а вот четные ячейки почему-то заполнены удвоенным числом.

Ищу ошибку в инициализации I2S на ESP8266. Может у кого-то ещё какие мысли есть, почему происходит умножение на 2 и как это исправить?
Делители для тактирования I2S в вышесказанном режиме настроил так:
Код:
CLEAR_PERI_REG_MASK(I2SCONF, I2S_TRANS_SLAVE_MOD|
                        (I2S_BITS_MOD<<I2S_BITS_MOD_S)|
                        (I2S_BCK_DIV_NUM <<I2S_BCK_DIV_NUM_S)|
                        (I2S_CLKM_DIV_NUM<<I2S_CLKM_DIV_NUM_S));

    SET_PERI_REG_MASK(I2SCONF, I2S_RIGHT_FIRST|I2S_MSB_RIGHT|I2S_RECE_SLAVE_MOD|
                        I2S_RECE_MSB_SHIFT|I2S_TRANS_MSB_SHIFT|
                        ((13&I2S_BCK_DIV_NUM )<<I2S_BCK_DIV_NUM_S)|
                        ((4&I2S_CLKM_DIV_NUM)<<I2S_CLKM_DIV_NUM_S)|
                        (15<<I2S_BITS_MOD_S));
 

Вложения

Garmin

Member
Подобную проблему оцифровки звука я решил по другому. I2S принимается в STM32, а затем по SPI протоколу передаётся в ESP8266. Причём обмен ведётся в обе стороны. ESP8266 работает как SPI slave, шина данных мультиплексирована. Пакеты по 64 байта, так как у SPI такой объём буфера. Ничего не теряется. Сейчас тружусь над передачей по WiFi. UDP меня не удовлетворил (есть потери), занимаюсь TCP, но с кучей кривых примеров и с разными реализациями передачи есть проблемы в понимании сути процесса.
 

RRRLock

New member
Подобную проблему оцифровки звука я решил по другому. I2S принимается в STM32, а затем по SPI протоколу передаётся в ESP8266. Причём обмен ведётся в обе стороны. ESP8266 работает как SPI slave, шина данных мультиплексирована. Пакеты по 64 байта, так как у SPI такой объём буфера. Ничего не теряется. Сейчас тружусь над передачей по WiFi. UDP меня не удовлетворил (есть потери), занимаюсь TCP, но с кучей кривых примеров и с разными реализациями передачи есть проблемы в понимании сути процесса.
У меня тоже была идея воспользоваться SPI, но столкнулся с рядом препятствий:

1. У HSPI сигнал CS заведен на GPIO15, который должен быть подтянут через резистор к земле. Можно выбрать 3 других вывода под CS.
Какой выбрали вы? У меня модуль ESP-07, проект делаю в Eclipse с помощью UDK, для программирования и отладки использую плату USB-TTL, GPIO0 заведен на DTR, GPIO1 занят под TX0, а GPIO11 находится под экраном. Можно конечно снять экран и подпаяться аккуратненько или взять ESP-12E, который у меня тоже имеется, на котором выведен GPIO11.

2. Какой API использовать для проекта с FreeRTOS? Попутно хочу спросить, есть ли способ обойтись без FreeRTOS для непрерывной обработки данных?
 

Garmin

Member
Я сразу использовал ESP-12. Подключение:
* Обмен данными по SPI1 в slave режиме
* GPIO12 - данные MISO и MOSI
* GPIO13 - REQ GPIO OUT флаг запроса от ESP8266 на передачу данных
* GPIO14 - CLK
* GPIO15 - CS
* GPIO4 - CS GPIO IN для разрешения конфликтов
Резистор нужен только во время старта, а в это время IO порты STM32 находятся в высокоимпедансном состоянии. Так что ничего не мешает модулю стартовать.
Пишу также под UDK, но со своим файлом описания периферии. Он выложен в соседней теме.
Принцип обработки данных никак не связан с FreeRTOS. Я писал и так, и так. Сейчас пишу без него.
 

RRRLock

New member
Принцип обработки данных никак не связан с FreeRTOS. Я писал и так, и так. Сейчас пишу без него.
Как вы работаете с непрерывным приемом данных по SPI? Используете бесконечный цикл? Как тогда разбираетесь с watchdog?

В SDK programming guid написано:
Using non-OS SDK which is single-threaded, the CPU should not take long to execute tasks:
‣ If a task occupies the CPU too long, ESP8266 can't feed the dog, it will cause a watchdog
reset;
‣ If interrupt is disabled, CPU can only be occupied in us range and the time should not be
more than 10 us; if interrupt is not disabled, it is suggested that CPU should not be
occupied more than 500 ms.
Не стал с этим разбираться и перешел на проект с FreeRTOS. Теперь вот зерно сомнения во мне после ваших слов))
 

Garmin

Member
Как вы работаете с непрерывным приемом данных по SPI? Используете бесконечный цикл? Как тогда разбираетесь с watchdog?
Не стал с этим разбираться и перешел на проект с FreeRTOS. Теперь вот зерно сомнения во мне после ваших слов))
Именно глупые примеры с опросом и задержками в циклах сбивают всех с толку.
Мне посоветовали работь по событиям. Поставил прерывания и коллбэки на события в main_init () и у меня нет цикла основной программы. Процессор занимается своими делами.
Правда, пришлось подрихтовать свою парадигму программирования, и отслеживать развитие событий в разных частях программы.
 

RRRLock

New member
Именно глупые примеры с опросом и задержками в циклах сбивают всех с толку.
Мне посоветовали работь по событиям. Поставил прерывания и коллбэки на события в main_init () и у меня нет цикла основной программы. Процессор занимается своими делами.
Правда, пришлось подрихтовать свою парадигму программирования, и отслеживать развитие событий в разных частях программы.
Спасибо за полезную информацию.
Нашел ваш проект на GitHub GitHub - Intelligent-Productions/UDP_SPI_project: Description registers ESP8266 in ST style. Буду сидеть разбираться.

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