Мадиас
Вторник 01 сентября 2015 г. 22:00
Хорошо, время для публикации моих идей для моего основного проекта здесь.
Вначале только несколько быстрых фактов и обновлений статуса:
Концепция:
4-канальный (полифонический) Waveetable-Synthesizer на основе STM32F103 с отдельными выходами для платы аналоговых фильтров.
Голосовать через 2pcs pt8211 (дешевый) Audio DAC [Основной код работает - пока невозможно, но благодаря Vassilis с SPI -кодом, TODO: реализация DMA]
USB-MIDI и аппаратный MIDI [Настроили отдельную филиал с использованием USB-MIDI вместо USB-серии-тестовый код работал]
Дисплей (ILI9341 с прикосновением + вторичный OLED), кодеры, ручки.... [Тодо, но сначала нет приоритета для пользовательского интерфейса]
Прямой импорт Waldorf Blofeld Multi-Wavetables через MIDI (USB) [Работайте, код написан]
SPI-Flash (Winbond) EEPROM (2-4 МБ) для хранения
Вначале только несколько быстрых фактов и обновлений статуса:
Концепция:
4-канальный (полифонический) Waveetable-Synthesizer на основе STM32F103 с отдельными выходами для платы аналоговых фильтров.
Голосовать через 2pcs pt8211 (дешевый) Audio DAC [Основной код работает - пока невозможно, но благодаря Vassilis с SPI -кодом, TODO: реализация DMA]
USB-MIDI и аппаратный MIDI [Настроили отдельную филиал с использованием USB-MIDI вместо USB-серии-тестовый код работал]
Дисплей (ILI9341 с прикосновением + вторичный OLED), кодеры, ручки.... [Тодо, но сначала нет приоритета для пользовательского интерфейса]
Прямой импорт Waldorf Blofeld Multi-Wavetables через MIDI (USB) [Работайте, код написан]
SPI-Flash (Winbond) EEPROM (2-4 МБ) для хранения
maybe an additional I2C EEPROM (more write/erase cycles)
several LTC1665 octal-8-Bit-DAC's for controlling the filter board and voice volume [code examples written, maybe I use direct PWM instead of this DAC's]
STM32F103 is individual, but I need 64k RAM (for wavetables), so maybe RET6
[b]Filter board[/b] [i]based on Olivier Gillet Anushri 4-Pole filter board[/i]
Stackable 4-pole LP Filter board (each board with 2x Filter + PT8211 DAC - routable) [created with Kicad uploaded to production: dirtypcbs.com]
Used chips: Mostly SSM2164 (aka V2164) and LM13700, rest TL07x, Styroflex caps for filter)
3d-model:
[img]http://666kb.com/i/d1qbw6ccyw991xrfv.jpg[/img]
[i][b]to be continued[/b][/i]
victor_pv
Ср. 02 сентября 2015 г., 4:16
Мадиас написал:Хорошо, время для публикации моих идей для моего основного проекта здесь.
Вначале только несколько быстрых фактов и обновлений статуса:
Концепция:
4-канальный (полифонический) Waveetable-Synthesizer на основе STM32F103 с отдельными выходами для платы аналоговых фильтров.
Голосовать через 2pcs pt8211 (дешевый) Audio DAC [Основной код работает - пока невозможно, но благодаря Vassilis с SPI -кодом, TODO: реализация DMA]
USB-MIDI и аппаратный MIDI [Настроили отдельную филиал с использованием USB-MIDI вместо USB-серии-тестовый код работал]
Дисплей (ILI9341 с прикосновением + вторичный OLED), кодеры, ручки.... [Тодо, но сначала нет приоритета для пользовательского интерфейса]
Прямой импорт Waldorf Blofeld Multi-Wavetables через MIDI (USB) [Работайте, код написан]
SPI (Winbond) EEPROM (2-4 МБ) для хранения
Вначале только несколько быстрых фактов и обновлений статуса:
Концепция:
4-канальный (полифонический) Waveetable-Synthesizer на основе STM32F103 с отдельными выходами для платы аналоговых фильтров.
Голосовать через 2pcs pt8211 (дешевый) Audio DAC [Основной код работает - пока невозможно, но благодаря Vassilis с SPI -кодом, TODO: реализация DMA]
USB-MIDI и аппаратный MIDI [Настроили отдельную филиал с использованием USB-MIDI вместо USB-серии-тестовый код работал]
Дисплей (ILI9341 с прикосновением + вторичный OLED), кодеры, ручки.... [Тодо, но сначала нет приоритета для пользовательского интерфейса]
Прямой импорт Waldorf Blofeld Multi-Wavetables через MIDI (USB) [Работайте, код написан]
SPI (Winbond) EEPROM (2-4 МБ) для хранения
maybe an additional I2C DAC (more write/erase cycles)
several LTC1665 octal-8-Bit-DAC's for controlling the filter board and voice volume [code examples written, maybe I use direct PWM instead of this DAC's]
STM32F103 is individual, but I need 64k RAM (for wavetables), so maybe RET6
[b]Filter board[/b] [i]based on Olivier Gillet Anushri 4-Pole filter board[/i]
Stackable 4-pole LP Filter board (each board with 2x Filter + PT8211 DAC - routable) [created with Kicad uploaded to production: dirtypcbs.com]
Used chips: Mostly SSM2164 (aka V2164) and LM13700, rest TL07x, Styroflex caps for filter)
3d-model:
[img]http://666kb.com/i/d1qbw6ccyw991xrfv.jpg[/img]
[i][b]to be continued[/b][/i][/quote]
May I suggest you use SPI Flash instead of EEPROM? perhaps you meant that, but if not, flash should be faster than eeprom. Regarding the MCU, the RCT6 boards I have all have 512 of flash and 64 of RAM, so at least for development you can use that.
Both the RCT and RET have 2 integrated DACs, so you can use those for control, or extra channel or whatever you wish.
Мадиас
Ср. 02 сентября 2015 г. 5:43 утра
Дорогой Виктор,
Да, я имею в виду SPI Flash (например, Winbond W25Q64FV). Реальная проблема - циклы записи/чтения, взятые из таблиц данных:
W25Q64FV - 8MB Flash SPI чип (100.000 циклов записи)
24LC512 - 64 КБ Flash I2C Чип (1.000.000 циклов записи)
Таким образом, для «хранения данных постоянного в лету» (данные, подобные патчам, общие файлы, без аудиофайлов), 23LC512 должен быть лучшим вариантом. Но, может быть, я слишком осторожный. Аудио играется напрямую из внутренней оперативной памяти, поэтому мне не понадобится настоящая высокая скорость для внешнего хранилища.
Для разработки я использую мою большую ветеринарную доску (Winbond и I2C Flash на борту) для конечного продукта, который я еще не уверен.
DAC может быть полезен (если нет конфликта с PIN -конфликтом с SPI, мне нужны все 3 порта SPI), но только два ПК проблематичны, потому что мне нужно следовать теме (!) ЦАП (или отфильтрованные ШИМ):
4x контролируемый объем напряжения (VCA)
4x контролируемая частота отсечения напряжения (VCF)
1-4x контролируемого напряжения резонанс (---> Может быть, это для ЦАП, мне не нужно устанавливать резонанс для каждого независимого от голоса)
Итак, один октальный DAC + 1Channel On Board DAC.
Да, я имею в виду SPI Flash (например, Winbond W25Q64FV). Реальная проблема - циклы записи/чтения, взятые из таблиц данных:
W25Q64FV - 8MB Flash SPI чип (100.000 циклов записи)
24LC512 - 64 КБ Flash I2C Чип (1.000.000 циклов записи)
Таким образом, для «хранения данных постоянного в лету» (данные, подобные патчам, общие файлы, без аудиофайлов), 23LC512 должен быть лучшим вариантом. Но, может быть, я слишком осторожный. Аудио играется напрямую из внутренней оперативной памяти, поэтому мне не понадобится настоящая высокая скорость для внешнего хранилища.
Для разработки я использую мою большую ветеринарную доску (Winbond и I2C Flash на борту) для конечного продукта, который я еще не уверен.
DAC может быть полезен (если нет конфликта с PIN -конфликтом с SPI, мне нужны все 3 порта SPI), но только два ПК проблематичны, потому что мне нужно следовать теме (!) ЦАП (или отфильтрованные ШИМ):
4x контролируемый объем напряжения (VCA)
4x контролируемая частота отсечения напряжения (VCF)
1-4x контролируемого напряжения резонанс (---> Может быть, это для ЦАП, мне не нужно устанавливать резонанс для каждого независимого от голоса)
Итак, один октальный DAC + 1Channel On Board DAC.
victor_pv
Ср. 02 сентября 2015 г. 13:14
Мадиас написал:Дорогой Виктор,
Да, я имею в виду SPI Flash (например, Winbond W25Q64FV). Реальная проблема - циклы записи/чтения, взятые из таблиц данных:
W25Q64FV - 8MB Flash SPI чип (100.000 циклов записи)
24LC512 - 64 КБ Flash I2C Чип (1.000.000 циклов записи)
Таким образом, для «хранения данных постоянного в лету» (данные, подобные патчам, общие файлы, без аудиофайлов), 23LC512 должен быть лучшим вариантом. Но, может быть, я слишком осторожный. Аудио играется напрямую из внутренней оперативной памяти, поэтому мне не понадобится настоящая высокая скорость для внешнего хранилища.
Для разработки я использую мою большую ветеринарную доску (Winbond и I2C Flash на борту) для конечного продукта, который я еще не уверен.
DAC может быть полезен (если нет конфликта с PIN -конфликтом с SPI, мне нужны все 3 порта SPI), но только два ПК проблематичны, потому что мне нужно следовать теме (!) ЦАП (или отфильтрованные ШИМ):
4x контролируемый объем напряжения (VCA)
4x контролируемая частота отсечения напряжения (VCF)
1-4x контролируемого напряжения резонанс (---> Может быть, это для ЦАП, мне не нужно устанавливать резонанс для каждого независимого от голоса)
Итак, один октальный DAC + 1Channel On Board DAC.
Да, я имею в виду SPI Flash (например, Winbond W25Q64FV). Реальная проблема - циклы записи/чтения, взятые из таблиц данных:
W25Q64FV - 8MB Flash SPI чип (100.000 циклов записи)
24LC512 - 64 КБ Flash I2C Чип (1.000.000 циклов записи)
Таким образом, для «хранения данных постоянного в лету» (данные, подобные патчам, общие файлы, без аудиофайлов), 23LC512 должен быть лучшим вариантом. Но, может быть, я слишком осторожный. Аудио играется напрямую из внутренней оперативной памяти, поэтому мне не понадобится настоящая высокая скорость для внешнего хранилища.
Для разработки я использую мою большую ветеринарную доску (Winbond и I2C Flash на борту) для конечного продукта, который я еще не уверен.
DAC может быть полезен (если нет конфликта с PIN -конфликтом с SPI, мне нужны все 3 порта SPI), но только два ПК проблематичны, потому что мне нужно следовать теме (!) ЦАП (или отфильтрованные ШИМ):
4x контролируемый объем напряжения (VCA)
4x контролируемая частота отсечения напряжения (VCF)
1-4x контролируемого напряжения резонанс (---> Может быть, это для ЦАП, мне не нужно устанавливать резонанс для каждого независимого от голоса)
Итак, один октальный DAC + 1Channel On Board DAC.
Мадиас
Ср. 02 сентября 2015 г., 13:29
Есть также устройства SPI RAM,
Я знаю их, у меня есть как минимум два из них из доставки образца микрочипа дома. (У меня есть много чипсов SPI/I2C Flash/EEPROM/RAM, поэтому я собираюсь поэкспериментировать лучше всего)
И у RC и выше есть FSMC
Я думал о FSMC и добавлении около 1-2 МБ SRAM (NORS), но фактически они мне не нужны (64 КБ более чем достаточно для меня и для волн), возможно, это может быть будущим обновлением: «Реальные» образцы вместо Wavetables.
О ЦАП, возможно, есть несколько восьмиугольников или, по крайней мере, Quad DAC, которые работают со SPI, в режиме SPI не i2s
У меня есть 8-битный восьми цифровую ЦАП LT1665 -> это SPI, но быть бетоном:
Мне нужно 4-битный DAC для Audio Out, поэтому 2PCS Pt8211 идеально подходит для этого условия ---> Частота 48 кГц. Волноты в реальном времени творены с этой частотой Я знаю, что работа i2s будет отличной выгодой.
Остальные ЦАП предназначены для контрольных линий, им не нужна высокая частота (обновление около 40-100 Гц, и только в случае изменения значения) и без более высокой скорости битов (8-битный больше, чем хорошо, потому что я использую конвертеры выставки. В моей схеме аудиофильтрования MIDI «Понять» только 7-битные значения для нормальных сигналов CC (и одна линия с 14-битной -> изгиб тона), поэтому 8-битный))) Я также реализовал в дизайне фильтра A PWM-фильтр, поэтому я также попробую PURE SWM (с более высокой скоростью), но мне понадобится не менее 9 пин-штифтов.
Итак, мои следующие шаги, пока я не получу платы PCB:
Оптимизация кода Audio Out с помощью ЦАП PT8211 (даже с DMA SPI или I2s (но, честно говоря: я не вижу, чтобы I2 работали с моими навыками)
Мне нужно 4-битный DAC для Audio Out, поэтому 2PCS Pt8211 идеально подходит для этого условия ---> Частота 48 кГц. Волноты в реальном времени творены с этой частотой Я знаю, что работа i2s будет отличной выгодой.
Остальные ЦАП предназначены для контрольных линий, им не нужна высокая частота (обновление около 40-100 Гц, и только в случае изменения значения) и без более высокой скорости битов (8-битный больше, чем хорошо, потому что я использую конвертеры выставки. В моей схеме аудиофильтрования MIDI «Понять» только 7-битные значения для нормальных сигналов CC (и одна линия с 14-битной -> изгиб тона), поэтому 8-битный))) Я также реализовал в дизайне фильтра A PWM-фильтр, поэтому я также попробую PURE SWM (с более высокой скоростью), но мне понадобится не менее 9 пин-штифтов.
Итак, мои следующие шаги, пока я не получу платы PCB:
Оптимизация кода Audio Out с помощью ЦАП PT8211 (даже с DMA SPI или I2s (но, честно говоря: я не вижу, чтобы I2 работали с моими навыками)
victor_pv
Чт 10 сентября 2015 12:44
Я ничего не знаю о LFO, но звучит как работа для торговых таймеров аппаратного обеспечения. Им просто нужно переключить булавку на определенной частоте, и эта частота может меняться время от времени, это правильно?
Если это так, вы можете использовать 1 или несколько таймеров, с правильными значениями для перезагрузки, прескалера и OCR, и установить их на свободный запуск, затем измените значения на лету, чтобы изменить их частоту и период.
Я полагаю, что у вас будет 7 таймеров, доступных в RCT или более высоких MCU, каждый из которых с 4 выходами сравнивает выходы.
Если это так, вы можете использовать 1 или несколько таймеров, с правильными значениями для перезагрузки, прескалера и OCR, и установить их на свободный запуск, затем измените значения на лету, чтобы изменить их частоту и период.
Я полагаю, что у вас будет 7 таймеров, доступных в RCT или более высоких MCU, каждый из которых с 4 выходами сравнивает выходы.
Мадиас
Чт 10 сентября 2015 г. 13:25
LFO - это скорее модульная вещь, от конструкции, как «нормальные» осцилляторы:
Изображение синусоидальной таблицы с 256 записями. (Значения от -127 до 127). Вы проходите через эту таблицу с переменной частотой (скажем, 30 Гц). Таким образом, вы установили таймер с частотой 7680 Гц (256*30 Гц). Это было бы довольно плохо, но функциональный LFO. (Чтобы изменить частоту, вы должны изменить таймер)
Использование этого LFO является модульным, некоторые примеры:
Вы можете модулировать шаг основного генератора: частота основного генератора составляет 440 Гц (концертный шаг «а»).
Есть много целей, которые вы можете модулировать: объем, частота отсечения, баланс между осциллятором1 и OSC2, даже интенсивность LFO2 или скорость LFO3.
Таким образом, в моем синтезаторе LFO будет только «быть в программном обеспечении», изменяя шаг OSC, но даст отдельное значение DAC, если бы я модулировал обрезанный фильтр (внешнее аналоговое оборудование)
В прошлом я делал это с одним таймером для всех LFO:
(Пример кода из моего мозга)
Эта функция находится на таймере, установленном на желаемую максимальную частоту * 256
Изображение синусоидальной таблицы с 256 записями. (Значения от -127 до 127). Вы проходите через эту таблицу с переменной частотой (скажем, 30 Гц). Таким образом, вы установили таймер с частотой 7680 Гц (256*30 Гц). Это было бы довольно плохо, но функциональный LFO. (Чтобы изменить частоту, вы должны изменить таймер)
Использование этого LFO является модульным, некоторые примеры:
Вы можете модулировать шаг основного генератора: частота основного генератора составляет 440 Гц (концертный шаг «а»).
Есть много целей, которые вы можете модулировать: объем, частота отсечения, баланс между осциллятором1 и OSC2, даже интенсивность LFO2 или скорость LFO3.
Таким образом, в моем синтезаторе LFO будет только «быть в программном обеспечении», изменяя шаг OSC, но даст отдельное значение DAC, если бы я модулировал обрезанный фильтр (внешнее аналоговое оборудование)
В прошлом я делал это с одним таймером для всех LFO:
(Пример кода из моего мозга)
Эта функция находится на таймере, установленном на желаемую максимальную частоту * 256
byte div_delay[MAX_VOICES*3];
byte lfo_table_counter[MAX_VOICES*3];
byte lfo_freq[MAX_VOICES*3];
int8_t lfo_value[MAX_VOICES*3];
// lfo_table[] different tables with 256 entries (like sine, sqr, saw up....)
lfo_freq[0]=20;
lfo_freq[1]=100; // and so on...
void LFO()
{
for (byte currentvoice=0;currentvoice<=MAX_VOICES*3;currentvoice++) // need 3 LFO's for each voice
{
div_delay[currentvoice]++;
if (div_delay[currentvoice]>=freq[currentvoice])
lfo_table_counter[currentvoice]++;
lfo_value[currentvoice]=lfo_table[currentvoice];
}
}
Мадиас
Чт 10 сентября 2015 г. 15:39
Хорошо, попробовал RTOS в моем примере i2S, со смешанным успехом:
Корочно, усечен:
Перед настройкой:
Корочно, усечен:
Перед настройкой:
SemaphoreHandle_t event_signal;
victor_pv
Чт 10 сентября 2015 г., 20:07
Не могли бы вы ссылаться на полный эскиз?
РЕДАКТИРОВАТЬ:
Попробуйте установить время ожидания семафора как portmax_delay, а не NULL
Кроме того, почему вы принимаете семафор после его создания?
Это так, что процедура DMA сначала отправляет партию 0? в противном случае, вам не нужно принимать это, пусть задача заполнения буфера возьмет это.
РЕДАКТИРОВАТЬ:
Попробуйте установить время ожидания семафора как portmax_delay, а не NULL
Кроме того, почему вы принимаете семафор после его создания?
Это так, что процедура DMA сначала отправляет партию 0? в противном случае, вам не нужно принимать это, пусть задача заполнения буфера возьмет это.
Мадиас
Чт 10 сентября 2015 г. 20:28
...Между тем я сразился с другой проблемой. Если я установите буфер DMA на высокий. Никаких кликов не происходит, если я установил буфер на 2 (только 1 значение для слева/справа)
У меня снова полный аудио-двигатель в DMA, если я не смогу очистить проблемы. У меня есть 2-3 задачи RTOS: некоторые гаджеты TFT, игрок с заметками и LFO.
Это тяжелое начало изучать RTO, потому что я использую критические вещи в реальном времени.
Я добавил версию «до» моего эскиза (аудио -двигатель на RTO) только две задачи: мелодия (включенная только развертка FREQ) и Audio_Engine. (TFT - это только начальный экран), как вы можете видеть в DMA IRQ, я пробовал много неуместных кодов.
Я думаю, что лучшее было бы «функция rtos One Trigger» для Audio_Engine --> Триггер будет в DMA IRQ, потому что это немного пустая трата ресурсов, имея петлю Audio_Engine "всегда на"
Второй файл эскиза (i2S-PT8211-Synth-Buffer_tft_rtos2)-мой текущий рабочий эскиз (кроме проблемы буфера, он работает довольно хорошо)
редактировать: Кроме того, почему вы принимаете семафор после его создания? Это было только для тестирования (я видел это в примере)
У меня снова полный аудио-двигатель в DMA, если я не смогу очистить проблемы. У меня есть 2-3 задачи RTOS: некоторые гаджеты TFT, игрок с заметками и LFO.
Это тяжелое начало изучать RTO, потому что я использую критические вещи в реальном времени.
Я добавил версию «до» моего эскиза (аудио -двигатель на RTO) только две задачи: мелодия (включенная только развертка FREQ) и Audio_Engine. (TFT - это только начальный экран), как вы можете видеть в DMA IRQ, я пробовал много неуместных кодов.
Я думаю, что лучшее было бы «функция rtos One Trigger» для Audio_Engine --> Триггер будет в DMA IRQ, потому что это немного пустая трата ресурсов, имея петлю Audio_Engine "всегда на"
Второй файл эскиза (i2S-PT8211-Synth-Buffer_tft_rtos2)-мой текущий рабочий эскиз (кроме проблемы буфера, он работает довольно хорошо)
редактировать: Кроме того, почему вы принимаете семафор после его создания? Это было только для тестирования (я видел это в примере)
Мадиас
Чт 10 сентября 2015 г. 20:49
Я думаю о чем -то подобном:
http: // www.Freertos.org/taskresumefromisr.HTML
DMA IRQ установил задачу AUDIO_ENGINE в резюме, задача запускает и прекращается.
Другая теория: время обновления задачи составляет 1 кГц, но я использую около 48 кГц в DMA IRQ (настройка более высокой скорости в RTOS-конфиг не приносит лекарство)
http: // www.Freertos.org/taskresumefromisr.HTML
DMA IRQ установил задачу AUDIO_ENGINE в резюме, задача запускает и прекращается.
Другая теория: время обновления задачи составляет 1 кГц, но я использую около 48 кГц в DMA IRQ (настройка более высокой скорости в RTOS-конфиг не приносит лекарство)
victor_pv
Чт 10 сентября 2015 г. 20:56
Мадиас написал:Я думаю о чем -то подобном:
http: // www.Freertos.org/taskresumefromisr.HTML
DMA IRQ установил задачу AUDIO_ENGINE в резюме, задача запускает и прекращается.
Другая теория: время обновления задачи составляет 1 кГц, но я использую около 48 кГц в DMA IRQ (настройка более высокой скорости в RTOS-конфиг не приносит лекарство)
http: // www.Freertos.org/taskresumefromisr.HTML
DMA IRQ установил задачу AUDIO_ENGINE в резюме, задача запускает и прекращается.
Другая теория: время обновления задачи составляет 1 кГц, но я использую около 48 кГц в DMA IRQ (настройка более высокой скорости в RTOS-конфиг не приносит лекарство)
Rogerclark
Чт 10 сентября 2015 г., 21:00
Freertos Systick вызывается той же функцией, которая обновляет количество Millis (), поэтому, если вы измените скорость Systick, вам необходимо скорректировать код Millis ()
Мадиас
Чт 10 сентября 2015 г., 21:20
Попробуйте установить время ожидания семафора как portmax_delay, а не NULL
Да, это смешивает слегка белый шум с аудио -выводом, звучит очень хорошо, но не то, что я хочу
Хорошо, я получил его почти запуска (но с худшим качеством звука, чем все в DMA ISR), потому что я установил Audio_Engine для более низкой задачи. Смотрите добавленный набросок
Хорошо, есть возможность установить временную задачу для более высокого приоритета, но синтаксис я немного смущаю меня:
Я пытался
Хорошо, я получил его почти запуска (но с худшим качеством звука, чем все в DMA ISR), потому что я установил Audio_Engine для более низкой задачи. Смотрите добавленный набросок
Хорошо, есть возможность установить временную задачу для более высокого приоритета, но синтаксис я немного смущаю меня:
Я пытался
void DMAEvent() {
BaseType_t xHigherPriorityTaskWoken = pdTRUE;
xSemaphoreGiveFromISR(event_signal, &xHigherPriorityTaskWoken ); // trigger
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
dma_clear_isr_bits(DMA2, DMA_CH2);
}
victor_pv
Пт 11 сентября 2015 г. 12:31
Но вы все еще используете это:
static void vFillBufferTask(void *pvParameters) {
while (1) {
if (xSemaphoreTake(event_signal, 0))
{
victor_pv
Пт 11 сентября 2015 г., 4:56 утра
Попробуйте этот код. Извините, у меня не было времени, чтобы скомпилировать его, поэтому у нее может быть небольшая ошибка, но если вы посмотрите на DMA ISR и функцию буфера заполнения, вы должны получить идею в очереди.
/* Pins:
#define BOARD_SPI3_NSS_PIN PA15 x timer
#define BOARD_SPI3_SCK_PIN PB3 x timer
#define BOARD_SPI3_MISO_PIN PB4 x timer
#define BOARD_SPI3_MOSI_PIN PB5 x timer
MCK Pins:
I2S2MCK: PC6 Timer 8, Channel 1
I2S3MCK: PC7 Timer 8, Channel 2
#define BOARD_SPI1_NSS_PIN PA4
#define BOARD_SPI1_SCK_PIN PA5
#define BOARD_SPI1_MISO_PIN PA6
#define BOARD_SPI1_MOSI_PIN PA7
*/
#include
#include "libmaple/spi.h"
#include "libmaple/dma.h"
#include "header.h"
#include
#include
#include
#include
#include
#include "fonts/Arial14.h"
#define TFT_DC PA1
#define TFT_CS PA0
#define rst PA2
#define BLACK 0x0000
#define RED 0xF800
#define GREEN 0x07E0
//#define BLUE 0x001F
#define BLUE 0x102E
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define ORANGE 0xFD20
#define GREENYELLOW 0xAFE5
#define DARKGREEN 0x03E0
#define WHITE 0xFFFF
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
ILI9341_due tft = ILI9341_due(TFT_CS, TFT_DC, rst);
ILI9341_due_gText t1(&tft);
#define LED PD2
#define buffer_size 2
#define buffer_size 128
int16_t i2s_buffer[buffer_size];
int16_t * i2s_buffer_tophalf = &i2s_buffer[buffer_size/2];
int16_t * i2s_buffer_ptr;
QueueHandle_t dmaQueue;
SemaphoreHandle_t event_signal;
xTaskHandle TaskHandle_1;
byte melo[] = {
40, 52, 40, 52, 47, 59, 47, 59,
40, 52, 40, 52, 47, 59, 47, 59,
43, 55, 43, 55, 50, 62, 50, 62,
43, 55, 43, 55, 50, 69, 50, 69,
};
byte wavecounter2 = 0;
byte counter = 0;
byte notestep = 0;
byte dacval = 0;
byte dacval2 = 0;
volatile byte testvol = 127;
volatile byte testvol2 = 127;
byte freq = 30;
void setup() {
disableDebugPorts(); // need to use SPI3!!!!
Serial.begin(9600);
tft.begin();
tft.setRotation(iliRotation270);
tft.fillScreen(BLUE);
t1.defineArea(0, 0, 320, 240);
t1.selectFont(Arial14);
timer_set_mode(TIMER6, 2, TIMER_DISABLED); // disable pwm on pins fuer jeden setzen!
gpio_set_mode(GPIOA, 15 , GPIO_AF_OUTPUT_PP); // SS pin
gpio_set_mode(GPIOB, 3 , GPIO_AF_OUTPUT_PP); // sck
gpio_set_mode(GPIOB, 4 , GPIO_INPUT_FLOATING); // miso
gpio_set_mode(GPIOB, 5 , GPIO_AF_OUTPUT_PP); // mosi
gpio_set_mode(GPIOC, 7 , GPIO_AF_OUTPUT_PP); // bck
createNoteTable(SAMPLE_RATE);
createWavetables();
ulPhaseIncrement_A[0] = nMidiPhaseIncrement[69]; // 69=440hz reference
ulPhaseIncrement_A[1] = nMidiPhaseIncrement[69]; // 69=440hz reference
pinMode (LED, OUTPUT);
tft.fillRect(0, 0, 320, 15, RED);
t1.setFontColor(WHITE, RED);
t1.drawString("* ILI9341_due UTFT 240x320 Demo *", 47, 0);
tft.fillRect(0, 226, 320, 240, tft.color565(64, 64, 64));
t1.setFontColor(YELLOW, tft.color565(64, 64, 64));
t1.drawString("bis dahin komm ich", gTextAlignBottomCenter, 227);
i2s_begin(SPI3); // untere Funktion verwenden
// ****DMA ******
dma_init(DMA2);
spi_tx_dma_enable(SPI3);
dma_attach_interrupt(DMA2, DMA_CH2, DMAEvent);
spi_tx_dma_enable(SPI3);
dma_setup_transfer(DMA2, DMA_CH2, &SPI3->regs->DR, DMA_SIZE_16BITS, i2s_buffer, DMA_SIZE_16BITS, (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_FROM_MEM | DMA_HALF_TRNS | DMA_TRNS_CMPLT));
dma_set_num_transfers(DMA2, DMA_CH2, buffer_size);
dma_set_priority(DMA2, DMA_CH2, DMA_PRIORITY_VERY_HIGH);
dma_enable(DMA2, DMA_CH2);// enable transmit
testvol = 127;
dmaQueue = xQueueCreate ( 2, sizeof (int16_t) );
vSemaphoreCreateBinary( event_signal ); // Create the semaphore
xSemaphoreTake(event_signal, 0); // Take semaphore after creating it.
xTaskCreate(vFillBufferTask,
"Task1",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 2,
&TaskHandle_1);
xTaskCreate(vMusicTask,
"Task2",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 1,
NULL);
vTaskStartScheduler();
}
void loop() {
}
static void vMusicTask(void *pvParameters) {
while (1)
{
freq++;
if (freq == 90)
freq = 30;
testvol = 127;
ulPhaseIncrement_A[0] = nMidiPhaseIncrement[byte(freq)]; // should be 440hz
ulPhaseIncrement_B[0] = nMidiPhaseIncrement[byte(freq)];
ulPhaseIncrement_A[1] = nMidiPhaseIncrement[byte(90-freq)]; // should be 440hz
ulPhaseIncrement_B[1] = nMidiPhaseIncrement[byte(90-freq)];
vTaskDelay(100);
/*
byte tune = melo[notestep];
ulPhaseIncrement_A[0] = nMidiPhaseIncrement[byte(tune)];
ulPhaseIncrement_B[0] = nMidiPhaseIncrement[byte(tune) + 7];
ulPhaseIncrement_A[1] = nMidiPhaseIncrement[byte(tune + 12)];
ulPhaseIncrement_B[1] = nMidiPhaseIncrement[byte(tune) + 19];
// Serial.println(nMidiPhaseIncrement[byte(tune)] );
notestep += 1;
if (notestep > 31)
notestep = 0;
// tft.fillRect(tune * 3, 100, 20, 20, GREEN);
for (byte x = 0; x < 127; x++)
{
testvol = x;
vTaskDelay(300);
}
for (byte x = 0; x < 127; x++)
{
testvol = 127 - x;
vTaskDelay(900);
}
// tft.fillRect(tune * 3, 100, 20, 20, BLUE);
*/
}
}
void DMAEvent() {
static signed BaseType_t xYieldRequired;
// xSemaphoreGiveFromISR(event_signal, NULL); // trigger
if ((dma_get_isr_bits( DMA2, DMA_CH2) & 0x2)==1) {
xQueueSendFromISR(dmaQueue, i2s_buffer, &xYieldRequired);
}
else {
xQueueSendFromISR(dmaQueue, i2s_buffer_tophalf, &xYieldRequired);
}
dma_clear_isr_bits(DMA2, DMA_CH2);
portEND_SWITCHING_ISR(xYieldRequired);
}
static void vFillBufferTask(void *pvParameters) {
while (1) {
if (xQueueReceive (dmaQueue, i2s_buffer_ptr , portMAX_DELAY)
{
// xSemaphoreTake(event_signal, 0);
// portENTER_CRITICAL();
// gpio_write_bit(GPIOD, 2, 1); // test led on
// byte flip=0;
for (int cc = 0; cc < (buffer_size/2)-1 ; cc +2)
{
// flip=!flip;
// if (flip==0)
// {
ulPhaseAccumulator_A[0] += ulPhaseIncrement_A[0] % SAMPLES_PER_CYCLE_FIXEDPOINT;
// if (ulPhaseAccumulator_A[0] > SAMPLES_PER_CYCLE_FIXEDPOINT)
// {
// ulPhaseAccumulator_A[0] -= SAMPLES_PER_CYCLE_FIXEDPOINT;
// }
ulPhaseAccumulator_B[0] += ulPhaseIncrement_B[0] % SAMPLES_PER_CYCLE_FIXEDPOINT;
// if (ulPhaseAccumulator_B[0] > SAMPLES_PER_CYCLE_FIXEDPOINT)
// {
// ulPhaseAccumulator_B[0] -= SAMPLES_PER_CYCLE_FIXEDPOINT;
// }
waveout_A[0] = (wavetable_A[ulPhaseAccumulator_A[0] >> 20] + wavetable_B[ulPhaseAccumulator_B[0] >> 20]) / 2;
// waveout_A[0] = ( (waveout_A[0] * testvol) / 128);
i2s_buffer_ptr[cc] = waveout_A[0];
// }
// else
// {
ulPhaseAccumulator_A[1] += ulPhaseIncrement_A[1] % SAMPLES_PER_CYCLE_FIXEDPOINT;
// if (ulPhaseAccumulator_A[1] > SAMPLES_PER_CYCLE_FIXEDPOINT)
// {
// ulPhaseAccumulator_A[1] -= SAMPLES_PER_CYCLE_FIXEDPOINT;
// }
ulPhaseAccumulator_B[1] += ulPhaseIncrement_B[1] % SAMPLES_PER_CYCLE_FIXEDPOINT;
// if (ulPhaseAccumulator_B[1] > SAMPLES_PER_CYCLE_FIXEDPOINT)
// {
// ulPhaseAccumulator_B[1] -= SAMPLES_PER_CYCLE_FIXEDPOINT;
// }
waveout_A[1] = (wavetable_A[ulPhaseAccumulator_A[1] >> 20] + wavetable_B[ulPhaseAccumulator_B[1] >> 20]) / 2;
waveout_A[1] = ( (waveout_A[1] * testvol2) / 128);
i2s_buffer_ptr[cc+1] = waveout_A[1] ;
// }
}
// gpio_write_bit(GPIOD, 2, 0); // test led off
//xSemaphoreTake(event_signal, 0);
// portEXIT_CRITICAL();
//vTaskSuspend(&TaskHandle_1 );
}
// vTaskPrioritySet( &TaskHandle_1 , tskIDLE_PRIORITY + 0 );
}
}
Мадиас
Пт 11 сентября 2015 г. 8:00 утра
Победители, спасибо за усилия!
К сожалению, это не будет функционировать, потому что данные не отправляются через MOSI (логический анал. --> SCK OK, WS OK, MOSI ---> Нет данных)
Я бы изменил некоторые вещи, вызванные компиляцией ошибок (очищенный код внизу):
Сначала линия
К сожалению, это не будет функционировать, потому что данные не отправляются через MOSI (логический анал. --> SCK OK, WS OK, MOSI ---> Нет данных)
Я бы изменил некоторые вещи, вызванные компиляцией ошибок (очищенный код внизу):
Сначала линия
static signed BaseType_t xYieldRequired;
Мадиас
Пт 11 сентября 2015 г. 8:25 утра
Хорошо, я изменил это:
dma_setup_transfer(DMA2, DMA_CH2, &SPI3->regs->DR, DMA_SIZE_16BITS, i2s_buffer , DMA_SIZE_16BITS, (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_FROM_MEM | DMA_HALF_TRNS | DMA_TRNS_CMPLT));
Мадиас
Пт 11 сентября 2015 г. 8:54 утра
Хорошо, я переделаю код в свою рабочую копию, только внедряет код победителей, такой как xqueuesdenfromisr (dmaqueue, i2s_buffer, &xyieldrequired); , portend_switching_isr (xyieldrequired); В DMA IRQ и if (xqueuereceive (dmaqueue, i2s_buffer, portmax_delay)) в буферном задании.
Результат такой же, как и во многих вещах, которые я пытался на аутсорсинг буферного кода из DMA IRQ в задачу RTOS: Звук потрескивания. Если я настрою
(xqueuereceive (dmaqueue, i2s_buffer, portmax_delay))
другие (низкие приоритетные) задачи выполняются, но потрескивающий звук
Если я настрою
(xqueuereceive (dmaqueue, i2s_buffer, 0)))
Никакая задача с низким приоритетом не запустила бы.
Рабочая копия: (с потрескивающим звуком)
Результат такой же, как и во многих вещах, которые я пытался на аутсорсинг буферного кода из DMA IRQ в задачу RTOS: Звук потрескивания. Если я настрою
(xqueuereceive (dmaqueue, i2s_buffer, portmax_delay))
другие (низкие приоритетные) задачи выполняются, но потрескивающий звук
Если я настрою
(xqueuereceive (dmaqueue, i2s_buffer, 0)))
Никакая задача с низким приоритетом не запустила бы.
Рабочая копия: (с потрескивающим звуком)
/* Pins:
#define BOARD_SPI3_NSS_PIN PA15 x timer
#define BOARD_SPI3_SCK_PIN PB3 x timer
#define BOARD_SPI3_MISO_PIN PB4 x timer
#define BOARD_SPI3_MOSI_PIN PB5 x timer
MCK Pins:
I2S2MCK: PC6 Timer 8, Channel 1
I2S3MCK: PC7 Timer 8, Channel 2
#define BOARD_SPI1_NSS_PIN PA4
#define BOARD_SPI1_SCK_PIN PA5
#define BOARD_SPI1_MISO_PIN PA6
#define BOARD_SPI1_MOSI_PIN PA7
*/
#include
#include "libmaple/spi.h"
#include "libmaple/dma.h"
#include "header.h"
#include
#include
#include
#include
#include
#include "fonts/Arial14.h"
#define TFT_DC PA1
#define TFT_CS PA0
#define rst PA2
#define BLACK 0x0000
#define RED 0xF800
#define GREEN 0x07E0
//#define BLUE 0x001F
#define BLUE 0x102E
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define ORANGE 0xFD20
#define GREENYELLOW 0xAFE5
#define DARKGREEN 0x03E0
#define WHITE 0xFFFF
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
ILI9341_due tft = ILI9341_due(TFT_CS, TFT_DC, rst);
ILI9341_due_gText t1(&tft);
#define LED PD2
//#define buffer_size 256
#define buffer_size 64
int16_t i2s_buffer[buffer_size];
int16_t * i2s_buffer_tophalf = &i2s_buffer[buffer_size / 2];
int16_t * i2s_buffer_ptr;
QueueHandle_t dmaQueue;
SemaphoreHandle_t event_signal;
xTaskHandle TaskHandle_1;
byte melo[] = {
40, 52, 40, 52, 47, 59, 47, 59,
40, 52, 40, 52, 47, 59, 47, 59,
43, 55, 43, 55, 50, 62, 50, 62,
43, 55, 43, 55, 50, 69, 50, 69,
};
byte wavecounter2 = 0;
byte counter = 0;
byte notestep = 0;
byte dacval = 0;
byte dacval2 = 0;
volatile byte testvol = 127;
volatile byte testvol2 = 127;
byte freq = 30;
void setup() {
disableDebugPorts(); // need to use SPI3!!!!
Serial.begin(9600);
tft.begin();
tft.setRotation(iliRotation270);
tft.fillScreen(BLUE);
t1.defineArea(0, 0, 320, 240);
t1.selectFont(Arial14);
timer_set_mode(TIMER6, 2, TIMER_DISABLED); // disable pwm on pins fuer jeden setzen!
gpio_set_mode(GPIOA, 15 , GPIO_AF_OUTPUT_PP); // SS pin
gpio_set_mode(GPIOB, 3 , GPIO_AF_OUTPUT_PP); // sck
gpio_set_mode(GPIOB, 4 , GPIO_INPUT_FLOATING); // miso
gpio_set_mode(GPIOB, 5 , GPIO_AF_OUTPUT_PP); // mosi
gpio_set_mode(GPIOC, 7 , GPIO_AF_OUTPUT_PP); // bck
createNoteTable(SAMPLE_RATE);
createWavetables();
ulPhaseIncrement_A[0] = nMidiPhaseIncrement[69]; // 69=440hz reference
ulPhaseIncrement_A[1] = nMidiPhaseIncrement[69]; // 69=440hz reference
pinMode (LED, OUTPUT);
tft.fillRect(0, 0, 320, 15, RED);
t1.setFontColor(WHITE, RED);
t1.drawString("* ILI9341_due UTFT 240x320 Demo *", 47, 0);
tft.fillRect(0, 226, 320, 240, tft.color565(64, 64, 64));
t1.setFontColor(YELLOW, tft.color565(64, 64, 64));
t1.drawString("bis dahin komm ich", gTextAlignBottomCenter, 227);
i2s_begin(SPI3); // untere Funktion verwenden
// ****DMA ******
dma_init(DMA2);
spi_tx_dma_enable(SPI3);
dma_attach_interrupt(DMA2, DMA_CH2, DMAEvent);
spi_tx_dma_enable(SPI3);
dma_setup_transfer(DMA2, DMA_CH2, &SPI3->regs->DR, DMA_SIZE_16BITS, i2s_buffer, DMA_SIZE_16BITS, (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_FROM_MEM | DMA_TRNS_CMPLT));
dma_set_num_transfers(DMA2, DMA_CH2, buffer_size);
dma_set_priority(DMA2, DMA_CH2, DMA_PRIORITY_VERY_HIGH);
dma_enable(DMA2, DMA_CH2);// enable transmit
testvol = 127;
dmaQueue = xQueueCreate ( 2, sizeof (int16_t) );
vSemaphoreCreateBinary( event_signal ); // Create the semaphore
xSemaphoreTake(event_signal, 0); // Take semaphore after creating it.
xTaskCreate(vFillBufferTask,
"Task1",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 5,
&TaskHandle_1);
xTaskCreate(vMusicTask,
"Task2",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 1,
NULL);
vTaskStartScheduler();
}
void loop() {
}
static void vMusicTask(void *pvParameters) {
while (1)
{
freq++;
if (freq == 90)
freq = 30;
testvol = 127;
ulPhaseIncrement_A[0] = nMidiPhaseIncrement[byte(freq)]; // should be 440hz
ulPhaseIncrement_B[0] = nMidiPhaseIncrement[byte(freq)];
ulPhaseIncrement_A[1] = nMidiPhaseIncrement[byte(90 - freq)]; // should be 440hz
ulPhaseIncrement_B[1] = nMidiPhaseIncrement[byte(90 - freq)];
vTaskDelay(100);
}
}
void DMAEvent() {
static signed portBASE_TYPE xYieldRequired;
// xSemaphoreGiveFromISR(event_signal, NULL); // trigger
// if ((dma_get_isr_bits( DMA2, DMA_CH2) & 0x2) == 1) {
xQueueSendFromISR(dmaQueue, i2s_buffer, &xYieldRequired);
// }
// else {
// xQueueSendFromISR(dmaQueue, i2s_buffer_tophalf, &xYieldRequired);
// }
portEND_SWITCHING_ISR(xYieldRequired);
dma_clear_isr_bits(DMA2, DMA_CH2);
}
static void vFillBufferTask(void *pvParameters) {
while (1) {
if (xQueueReceive (dmaQueue, i2s_buffer , portMAX_DELAY))
{
// gpio_write_bit(GPIOD, 2, 1); // test led on
byte flip=0;
// gpio_write_bit(GPIOD, 2, 1); // test led on
for (int cc = 0; cc < buffer_size; cc ++)
{
flip=!flip;
if (flip==0)
{
ulPhaseAccumulator_A[0] += ulPhaseIncrement_A[0];
if (ulPhaseAccumulator_A[0] > SAMPLES_PER_CYCLE_FIXEDPOINT)
{
ulPhaseAccumulator_A[0] =0;
}
ulPhaseAccumulator_B[0] += ulPhaseIncrement_B[0] ;
if (ulPhaseAccumulator_B[0] > SAMPLES_PER_CYCLE_FIXEDPOINT)
{
ulPhaseAccumulator_B[0] =0;
}
waveout_A[0] = (wavetable_A[ulPhaseAccumulator_A[0] >> 20] + wavetable_B[ulPhaseAccumulator_B[0] >> 20]) / 2;
waveout_A[0] = ( (waveout_A[0] * testvol) / 128);
i2s_buffer[cc] = waveout_A[0]; // half transfer
}
else
{
ulPhaseAccumulator_A[1] += ulPhaseIncrement_A[1] ;
if (ulPhaseAccumulator_A[1] > SAMPLES_PER_CYCLE_FIXEDPOINT)
{
ulPhaseAccumulator_A[1] -= SAMPLES_PER_CYCLE_FIXEDPOINT;
}
ulPhaseAccumulator_B[1] += ulPhaseIncrement_B[1] ;
if (ulPhaseAccumulator_B[1] > SAMPLES_PER_CYCLE_FIXEDPOINT)
{
ulPhaseAccumulator_B[1] -= SAMPLES_PER_CYCLE_FIXEDPOINT;
}
waveout_A[1] = (wavetable_A[ulPhaseAccumulator_A[1] >> 20] + wavetable_B[ulPhaseAccumulator_B[1] >> 20]) / 2;
waveout_A[1] = ( (waveout_A[1] * testvol2) / 128);
i2s_buffer[cc ] = waveout_A[1] ;
}
// gpio_write_bit(GPIOD, 2, 0); // test led on
}
}
}
}
Мадиас
Пт 11 сентября 2015 г. 11:18 утра
Хм.
Тем временем я обдумываю проект.
Может быть, было бы лучше (как мой первый план), оставляя «звуковой двигатель» на PIC32MX250 (код почти написан и работает без кликов) и использование STM32 в качестве устройства управления для всего остального: человеческий интерфейс, TFT, OLED, Serial-Midi , USB-MIDI, управление хранением (патчи, волны, даже на SD-карту или SPI-Flash) через RTOS
Хороший 4-канальный аудио-двигатель, даже с лучшими оптимизациями кода, потребует около 60-80% MCU (если не STM32F7 ), так что это было бы неисправное компромиссное упаковку все в один STM32F103 (например, лучшее качество звука, но абсолютно медленное обновление TFT, висящие миди ...) .
Большое преимущество большинства MCU (STM32F1, PIC32MX...): Они потрясающие дешевые!
Это также экономический факт: у меня дома около 10 Pic32mx250
Я не должен переосмыслить колесо: в моем бывшем проекте построил синтезатор с Tiva-TMC123 в качестве управляющего устройства и 4 Mini Arduino в качестве звуковых устройств (каждая с параллельным 8-битным ЦАП). Даже человеческий интерфейс контролировался ATMEGA328 (поэтому круговая плата интерфейса человека была независимой только два провода на главной плате) . Интересная вещь: i2c был лучшим протоколом связи между мини -и Tiva. Поэтому я бы сделал то же самое с STM32F1 и PIC32MX --> через I2C (потому что я использую все порты SPI на картинке как i2s)
Недостаток аутсорсинговой загрузки в серверы MCU: обновление прошивки. Таким образом, вы измените ядро, вы должны обновить прошивку на каждом устройстве. (Плохо, если я планирую продавать синтезаторы, обновление прошивки было бы слишком сложным для среднего пользователя)
Тем временем я обдумываю проект.
Может быть, было бы лучше (как мой первый план), оставляя «звуковой двигатель» на PIC32MX250 (код почти написан и работает без кликов) и использование STM32 в качестве устройства управления для всего остального: человеческий интерфейс, TFT, OLED, Serial-Midi , USB-MIDI, управление хранением (патчи, волны, даже на SD-карту или SPI-Flash) через RTOS
Хороший 4-канальный аудио-двигатель, даже с лучшими оптимизациями кода, потребует около 60-80% MCU (если не STM32F7 ), так что это было бы неисправное компромиссное упаковку все в один STM32F103 (например, лучшее качество звука, но абсолютно медленное обновление TFT, висящие миди ...) .
Большое преимущество большинства MCU (STM32F1, PIC32MX...): Они потрясающие дешевые!
Это также экономический факт: у меня дома около 10 Pic32mx250
Я не должен переосмыслить колесо: в моем бывшем проекте построил синтезатор с Tiva-TMC123 в качестве управляющего устройства и 4 Mini Arduino в качестве звуковых устройств (каждая с параллельным 8-битным ЦАП). Даже человеческий интерфейс контролировался ATMEGA328 (поэтому круговая плата интерфейса человека была независимой только два провода на главной плате) . Интересная вещь: i2c был лучшим протоколом связи между мини -и Tiva. Поэтому я бы сделал то же самое с STM32F1 и PIC32MX --> через I2C (потому что я использую все порты SPI на картинке как i2s)
Недостаток аутсорсинговой загрузки в серверы MCU: обновление прошивки. Таким образом, вы измените ядро, вы должны обновить прошивку на каждом устройстве. (Плохо, если я планирую продавать синтезаторы, обновление прошивки было бы слишком сложным для среднего пользователя)
victor_pv
Пт 11 сентября 2015 12:44
Мадиас написал:Хм.
Тем временем я обдумываю проект.
Может быть, было бы лучше (как мой первый план), оставляя «звуковой двигатель» на PIC32MX250 (код почти написан и работает без кликов) и используя STM32 в качестве устройства управления для всего остального: человеческий интерфейс, TFT, OLED, Serial-Midi , USB-MIDI, управление хранением (патчи, волны, даже на SD-карту или SPI-Flash) через RTOS
Хороший 4-канальный аудио-двигатель, даже с лучшими оптимизациями кода, потребует около 60-80% MCU (если не STM32F7 ), так что это было бы неисправное компромиссное упаковку все в один STM32F103 (например, лучшее качество звука, но абсолютно медленное обновление TFT, висящие миди ...) .
Большое преимущество большинства MCU (STM32F1, PIC32MX...): Они потрясающие дешевые!
Это также экономический факт: у меня дома около 10 Pic32mx250
Я не должен переосмыслить колесо: в моем бывшем проекте построил синтезатор с Tiva-TMC123 в качестве управляющего устройства и 4 Mini Arduino в качестве звуковых устройств (каждая с параллельным 8-битным ЦАП). Даже человеческий интерфейс контролировался ATMEGA328 (поэтому круговая плата интерфейса человека была независимой только два провода на главной плате) . Интересная вещь: i2c был лучшим протоколом связи между мини -и Tiva. Поэтому я бы сделал то же самое с STM32F1 и PIC32MX --> через I2C (потому что я использую все порты SPI на картинке как i2s)
Недостаток аутсорсинговой загрузки в серверы MCU: обновление прошивки. Таким образом, вы измените ядро, вы должны обновить прошивку на каждом устройстве. (Плохо, если я планирую продавать синтезаторы, обновление прошивки было бы слишком сложным для среднего пользователя)
Тем временем я обдумываю проект.
Может быть, было бы лучше (как мой первый план), оставляя «звуковой двигатель» на PIC32MX250 (код почти написан и работает без кликов) и используя STM32 в качестве устройства управления для всего остального: человеческий интерфейс, TFT, OLED, Serial-Midi , USB-MIDI, управление хранением (патчи, волны, даже на SD-карту или SPI-Flash) через RTOS
Хороший 4-канальный аудио-двигатель, даже с лучшими оптимизациями кода, потребует около 60-80% MCU (если не STM32F7 ), так что это было бы неисправное компромиссное упаковку все в один STM32F103 (например, лучшее качество звука, но абсолютно медленное обновление TFT, висящие миди ...) .
Большое преимущество большинства MCU (STM32F1, PIC32MX...): Они потрясающие дешевые!
Это также экономический факт: у меня дома около 10 Pic32mx250
Я не должен переосмыслить колесо: в моем бывшем проекте построил синтезатор с Tiva-TMC123 в качестве управляющего устройства и 4 Mini Arduino в качестве звуковых устройств (каждая с параллельным 8-битным ЦАП). Даже человеческий интерфейс контролировался ATMEGA328 (поэтому круговая плата интерфейса человека была независимой только два провода на главной плате) . Интересная вещь: i2c был лучшим протоколом связи между мини -и Tiva. Поэтому я бы сделал то же самое с STM32F1 и PIC32MX --> через I2C (потому что я использую все порты SPI на картинке как i2s)
Недостаток аутсорсинговой загрузки в серверы MCU: обновление прошивки. Таким образом, вы измените ядро, вы должны обновить прошивку на каждом устройстве. (Плохо, если я планирую продавать синтезаторы, обновление прошивки было бы слишком сложным для среднего пользователя)
Мадиас
Пт 11 сентября 2015 г. 14:19
Спасибо, что попробовали это, я должен отправить вам DAC PT8211 (Лучше: я заказываю для вас 20-30 пунктов на Али, это дешевле, чем отправлять один ПК из Австрии в США )
Даже без I2S ЦАП, это легко наблюдать: только с логическим анализатором Saleae и установите его на i2s (я разместил настройки для PT8211 в другой потоке) и используя слева и пишную волну вправо, так что В протоколе данные подсчитывают/вниз (в порядке, чтобы опробовать только 256 значений, легко обрабатывать протокол). Я думаю, что мы все слишком меньше используем логический анализатор
О обновлении прошивки:
Это моя старая идея, играя с досками Nucleo: ST-Link V2.1 Подключитесь к компьюте&Отбросить файл *bin для загрузки. Это должно быть (тихо) легкое решение для «перетаскивания&бросить "загрузчик. Таким образом, этот специальный загрузчик может быть загружен как «последний шаг» на готовом продукте. Я думаю, что многие из нас будут работать не только на себя, но и создавать проекты для семьи, друзей или даже коммерческого. Таким образом, этот конечный пользователь может легко загрузить новую прошивку через перетаскивание&бросить загрузчик. Должно быть возможно - или?
Я на свадьбе в эти выходные, так что в понедельник я снова нахожусь в бегах.
Приветствует
Матиас
Даже без I2S ЦАП, это легко наблюдать: только с логическим анализатором Saleae и установите его на i2s (я разместил настройки для PT8211 в другой потоке) и используя слева и пишную волну вправо, так что В протоколе данные подсчитывают/вниз (в порядке, чтобы опробовать только 256 значений, легко обрабатывать протокол). Я думаю, что мы все слишком меньше используем логический анализатор
О обновлении прошивки:
Это моя старая идея, играя с досками Nucleo: ST-Link V2.1 Подключитесь к компьюте&Отбросить файл *bin для загрузки. Это должно быть (тихо) легкое решение для «перетаскивания&бросить "загрузчик. Таким образом, этот специальный загрузчик может быть загружен как «последний шаг» на готовом продукте. Я думаю, что многие из нас будут работать не только на себя, но и создавать проекты для семьи, друзей или даже коммерческого. Таким образом, этот конечный пользователь может легко загрузить новую прошивку через перетаскивание&бросить загрузчик. Должно быть возможно - или?
Я на свадьбе в эти выходные, так что в понедельник я снова нахожусь в бегах.
Приветствует
Матиас
victor_pv
Пт 11 сентября 2015 г. 16:43
Мадиас написал:Спасибо, что попробовали это, я должен отправить вам DAC PT8211 (Лучше: я заказываю для вас 20-30 пунктов на Али, это дешевле, чем отправлять один ПК из Австрии в США )
Даже без I2S ЦАП, это легко наблюдать: только с логическим анализатором Saleae и установите его на i2s (я разместил настройки для PT8211 в другой потоке) и используя слева и пишную волну вправо, так что В протоколе данные подсчитывают/вниз (в порядке, чтобы опробовать только 256 значений, легко обрабатывать протокол). Я думаю, что мы все слишком меньше используем логический анализатор
О обновлении прошивки:
Это моя старая идея, играя с досками Nucleo: ST-Link V2.1 Подключитесь к компьюте&Отбросить файл *bin для загрузки. Это должно быть (тихо) легкое решение для «перетаскивания&бросить "загрузчик. Таким образом, этот специальный загрузчик может быть загружен как «последний шаг» на готовом продукте. Я думаю, что многие из нас будут работать не только на себя, но и создавать проекты для семьи, друзей или даже коммерческого. Таким образом, этот конечный пользователь может легко загрузить новую прошивку через перетаскивание&бросить загрузчик. Должно быть возможно - или?
Я на свадьбе в эти выходные, так что в понедельник я снова нахожусь в бегах.
Приветствует
Матиас
Даже без I2S ЦАП, это легко наблюдать: только с логическим анализатором Saleae и установите его на i2s (я разместил настройки для PT8211 в другой потоке) и используя слева и пишную волну вправо, так что В протоколе данные подсчитывают/вниз (в порядке, чтобы опробовать только 256 значений, легко обрабатывать протокол). Я думаю, что мы все слишком меньше используем логический анализатор
О обновлении прошивки:
Это моя старая идея, играя с досками Nucleo: ST-Link V2.1 Подключитесь к компьюте&Отбросить файл *bin для загрузки. Это должно быть (тихо) легкое решение для «перетаскивания&бросить "загрузчик. Таким образом, этот специальный загрузчик может быть загружен как «последний шаг» на готовом продукте. Я думаю, что многие из нас будут работать не только на себя, но и создавать проекты для семьи, друзей или даже коммерческого. Таким образом, этот конечный пользователь может легко загрузить новую прошивку через перетаскивание&бросить загрузчик. Должно быть возможно - или?
Я на свадьбе в эти выходные, так что в понедельник я снова нахожусь в бегах.
Приветствует
Матиас
Мадиас
Пт 11 сентября 2015 г., 21:06
You said that when using the half transfer flag, it does not send anything at all right?
victor_pv
Сб 12 сентября 2015 г. 14:21
Я обнаружил, что эта функция всегда читает 0, по -видимому, несмотря ни на что:
dma_get_isr_bits (dma2, dma_ch2);
Таким образом, DMA ISR всегда помещает одну и ту же половину буфера в очередь, в результате чего контроллер DMA отправляет 64 нулей и 64 байта с данными, и это повторяется снова и снова.
Я пробовал кучу разных способов чтения этой ценности, и она всегда терпит неудачу. Я знаю, что один и тот же код отлично работает для каналов SPI1 и SPI2, потому что я использовал DMA с этими двумя портами, и если бы это всегда было чтение 0, код был бы навсегда в первой передаче.
Но я не могу найти то, что не читает никакой ценности в этом случае. Я пытался прочитать его с переменной, объявленной нестабильной, объявленной статичной и не знаю, что еще, и, кажется, всегда делает то же самое.
Я не уверен, что это компилятор, оптимизирующий код, или что... Я могу попытаться изменить опцию оптимизации моего компилятора на -o0 и попробую еще раз...
Изменить: не могу выяснить, почему флаги не могут быть прочитаны, поэтому в настоящее время я просто использовал еще одну переменную FLIP, чтобы решить, какой указатель отправить.
Кажется, хорошо работает, насколько может показать Saleae, если у вас есть шанс проверить его с аудио:
dma_get_isr_bits (dma2, dma_ch2);
Таким образом, DMA ISR всегда помещает одну и ту же половину буфера в очередь, в результате чего контроллер DMA отправляет 64 нулей и 64 байта с данными, и это повторяется снова и снова.
Я пробовал кучу разных способов чтения этой ценности, и она всегда терпит неудачу. Я знаю, что один и тот же код отлично работает для каналов SPI1 и SPI2, потому что я использовал DMA с этими двумя портами, и если бы это всегда было чтение 0, код был бы навсегда в первой передаче.
Но я не могу найти то, что не читает никакой ценности в этом случае. Я пытался прочитать его с переменной, объявленной нестабильной, объявленной статичной и не знаю, что еще, и, кажется, всегда делает то же самое.
Я не уверен, что это компилятор, оптимизирующий код, или что... Я могу попытаться изменить опцию оптимизации моего компилятора на -o0 и попробую еще раз...
Изменить: не могу выяснить, почему флаги не могут быть прочитаны, поэтому в настоящее время я просто использовал еще одну переменную FLIP, чтобы решить, какой указатель отправить.
Кажется, хорошо работает, насколько может показать Saleae, если у вас есть шанс проверить его с аудио:
/* Pins:
#define BOARD_SPI3_NSS_PIN PA15 x timer
#define BOARD_SPI3_SCK_PIN PB3 x timer
#define BOARD_SPI3_MISO_PIN PB4 x timer
#define BOARD_SPI3_MOSI_PIN PB5 x timer
MCK Pins:
I2S2MCK: PC6 Timer 8, Channel 1
I2S3MCK: PC7 Timer 8, Channel 2
#define BOARD_SPI1_NSS_PIN PA4
#define BOARD_SPI1_SCK_PIN PA5
#define BOARD_SPI1_MISO_PIN PA6
#define BOARD_SPI1_MOSI_PIN PA7
*/
#include
#include "libmaple/spi.h"
#include "libmaple/dma.h"
#include "header.h"
#include
#include
#include
#include
#include
#include "fonts/Arial14.h"
#define TFT_DC PA1
#define TFT_CS PA0
#define rst PA2
#define BLACK 0x0000
#define RED 0xF800
#define GREEN 0x07E0
//#define BLUE 0x001F
#define BLUE 0x102E
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define ORANGE 0xFD20
#define GREENYELLOW 0xAFE5
#define DARKGREEN 0x03E0
#define WHITE 0xFFFF
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
ILI9341_due tft = ILI9341_due(TFT_CS, TFT_DC, rst);
ILI9341_due_gText t1(&tft);
#define LED PD2
//#define buffer_size 2
#define buffer_size 128
int16_t i2s_buffer[buffer_size];
int16_t *i2s_bottom = i2s_buffer;
int16_t *i2s_top = &i2s_buffer[buffer_size / 2];
static int16_t * i2s_buffer_ptr;
QueueHandle_t dmaQueue;
static void inline __attribute__((interrupt)) DMAEvent();
volatile byte flip2 = 0;
SemaphoreHandle_t event_signal;
xTaskHandle TaskHandle_1;
byte melo[] = {
40, 52, 40, 52, 47, 59, 47, 59,
40, 52, 40, 52, 47, 59, 47, 59,
43, 55, 43, 55, 50, 62, 50, 62,
43, 55, 43, 55, 50, 69, 50, 69,
};
byte wavecounter2 = 0;
byte counter = 0;
byte notestep = 0;
byte dacval = 0;
byte dacval2 = 0;
volatile byte testvol = 127;
volatile byte testvol2 = 127;
byte freq = 30;
void setup() {
disableDebugPorts(); // need to use SPI3!!!!
Serial.begin(9600);
tft.begin();
tft.setRotation(iliRotation270);
tft.fillScreen(BLUE);
t1.defineArea(0, 0, 320, 240);
t1.selectFont(Arial14);
timer_set_mode(TIMER6, 2, TIMER_DISABLED); // disable pwm on pins fuer jeden setzen!
gpio_set_mode(GPIOA, 15 , GPIO_AF_OUTPUT_PP); // SS pin
gpio_set_mode(GPIOB, 3 , GPIO_AF_OUTPUT_PP); // sck
gpio_set_mode(GPIOB, 4 , GPIO_INPUT_FLOATING); // miso
gpio_set_mode(GPIOB, 5 , GPIO_AF_OUTPUT_PP); // mosi
gpio_set_mode(GPIOC, 7 , GPIO_AF_OUTPUT_PP); // bck
createNoteTable(SAMPLE_RATE);
createWavetables();
ulPhaseIncrement_A[0] = nMidiPhaseIncrement[69]; // 69=440hz reference
ulPhaseIncrement_A[1] = nMidiPhaseIncrement[69]; // 69=440hz reference
pinMode (LED, OUTPUT);
tft.fillRect(0, 0, 320, 15, RED);
t1.setFontColor(WHITE, RED);
t1.drawString("* ILI9341_due UTFT 240x320 Demo *", 47, 0);
tft.fillRect(0, 226, 320, 240, tft.color565(64, 64, 64));
t1.setFontColor(YELLOW, tft.color565(64, 64, 64));
t1.drawString("bis dahin komm ich", gTextAlignBottomCenter, 227);
i2s_begin(SPI3); // untere Funktion verwenden
// ****DMA ******
dma_init(DMA2);
spi_tx_dma_enable(SPI3);
dma_attach_interrupt(DMA2, DMA_CH2, DMAEvent);
spi_tx_dma_enable(SPI3);
dma_setup_transfer(DMA2, DMA_CH2, &SPI3->regs->DR, DMA_SIZE_16BITS, i2s_buffer, DMA_SIZE_16BITS, (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_FROM_MEM | DMA_HALF_TRNS | DMA_TRNS_CMPLT));
dma_set_num_transfers(DMA2, DMA_CH2, buffer_size);
dma_set_priority(DMA2, DMA_CH2, DMA_PRIORITY_VERY_HIGH);
dma_enable(DMA2, DMA_CH2);// enable transmit
testvol = 127;
dmaQueue = xQueueCreate ( 2, sizeof (int16_t*) );
vSemaphoreCreateBinary( event_signal ); // Create the semaphore
xSemaphoreTake(event_signal, 0); // Take semaphore after creating it.
xTaskCreate(vFillBufferTask,
"Task1",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 2,
&TaskHandle_1);
xTaskCreate(vMusicTask,
"Task2",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 1,
NULL);
vTaskStartScheduler();
}
void loop() {
}
static void vMusicTask(void *pvParameters) {
while (1)
{
freq++;
if (freq == 90)
freq = 30;
testvol = 127;
ulPhaseIncrement_A[0] = nMidiPhaseIncrement[byte(freq)]; // should be 440hz
ulPhaseIncrement_B[0] = nMidiPhaseIncrement[byte(freq)];
ulPhaseIncrement_A[1] = nMidiPhaseIncrement[byte(90 - freq)]; // should be 440hz
ulPhaseIncrement_B[1] = nMidiPhaseIncrement[byte(90 - freq)];
vTaskDelay(100);
/*
byte tune = melo[notestep];
ulPhaseIncrement_A[0] = nMidiPhaseIncrement[byte(tune)];
ulPhaseIncrement_B[0] = nMidiPhaseIncrement[byte(tune) + 7];
ulPhaseIncrement_A[1] = nMidiPhaseIncrement[byte(tune + 12)];
ulPhaseIncrement_B[1] = nMidiPhaseIncrement[byte(tune) + 19];
// Serial.println(nMidiPhaseIncrement[byte(tune)] );
notestep += 1;
if (notestep > 31)
notestep = 0;
// tft.fillRect(tune * 3, 100, 20, 20, GREEN);
for (byte x = 0; x < 127; x++)
{
testvol = x;
vTaskDelay(300);
}
for (byte x = 0; x < 127; x++)
{
testvol = 127 - x;
vTaskDelay(900);
}
// tft.fillRect(tune * 3, 100, 20, 20, BLUE);
*/
}
}
static inline void DMAEvent() {
static signed portBASE_TYPE xYieldRequired;
//volatile uint8 isr = dma_get_isr_bits( DMA2, DMA_CH2);
//volatile dma_irq_cause event = dma_get_irq_cause(DMA2, DMA_CH2);
// xSemaphoreGiveFromISR(event_signal, NULL); // trigger
if (flip2 == 0 ) {
gpio_write_bit(GPIOD, 2, 0); // test led off
xQueueSendFromISR(dmaQueue, (void*)&i2s_bottom, &xYieldRequired);
}
else {
gpio_write_bit(GPIOD, 2, 1); // test led on
xQueueSendFromISR(dmaQueue, (void*)&i2s_top, &xYieldRequired);
}
dma_clear_isr_bits(DMA2, DMA_CH2);
flip2 = !flip2;
portEND_SWITCHING_ISR(xYieldRequired);
}
static void vFillBufferTask(void *pvParameters) {
while (1) {
if (xQueueReceive (dmaQueue, &i2s_buffer_ptr , portMAX_DELAY))
{
// xSemaphoreTake(event_signal, 0);
// portENTER_CRITICAL();
/* Serial.println ((uint32_t)i2s_buffer_ptr);
Serial.println ((uint32_t)i2s_bottom);
Serial.println ((uint32_t)i2s_top);
Serial.println ();
*/ // gpio_write_bit(GPIOD, 2, 1); // test led on
byte flip = 0;
for (int cc = 0; cc < (buffer_size / 2)-1 ; cc += 2)
{
ulPhaseAccumulator_A[0] += ulPhaseIncrement_A[0] ;
if (ulPhaseAccumulator_A[0] > SAMPLES_PER_CYCLE_FIXEDPOINT)
{
ulPhaseAccumulator_A[0] = 0;
}
ulPhaseAccumulator_B[0] += ulPhaseIncrement_B[0] ;
if (ulPhaseAccumulator_B[0] > SAMPLES_PER_CYCLE_FIXEDPOINT)
{
ulPhaseAccumulator_B[0] = 0;
}
waveout_A[0] = (wavetable_A[ulPhaseAccumulator_A[0] >> 20] + wavetable_B[ulPhaseAccumulator_B[0] >> 20]) / 2;
// waveout_A[0] = ( (waveout_A[0] * testvol) / 128);
i2s_buffer_ptr[cc] = waveout_A[0];
ulPhaseAccumulator_A[1] += ulPhaseIncrement_A[1] ;
if (ulPhaseAccumulator_A[1] > SAMPLES_PER_CYCLE_FIXEDPOINT)
{
ulPhaseAccumulator_A[1] = 0;
}
ulPhaseAccumulator_B[1] += ulPhaseIncrement_B[1] ;
if (ulPhaseAccumulator_B[1] > SAMPLES_PER_CYCLE_FIXEDPOINT)
{
ulPhaseAccumulator_B[1] = 0;
}
waveout_A[1] = (wavetable_A[ulPhaseAccumulator_A[1] >> 20] + wavetable_B[ulPhaseAccumulator_B[1] >> 20]) / 2;
waveout_A[1] = ( (waveout_A[1] * testvol2) / 128);
i2s_buffer_ptr[cc+1] = waveout_A[1] ;
}
// gpio_write_bit(GPIOD, 2, 0); // test led off
//xSemaphoreTake(event_signal, 0);
// portEXIT_CRITICAL();
//vTaskSuspend(&TaskHandle_1 );
}
// vTaskPrioritySet( &TaskHandle_1 , tskIDLE_PRIORITY + 0 );
}
}
Мадиас
Солнце 13 сентября 2015 г., 7:40
Странно, я обязательно получу хотя бы значение «3» назад (перевод полная+перевод половина). Должен проверить это завтра (я все еще не дома).
Я немного подумал о кликах и всплесках, которые у меня есть с более высоким буфером, возможно, мне следует установить DMA-IRQ на более высокий приоритет?
Я немного подумал о кликах и всплесках, которые у меня есть с более высоким буфером, возможно, мне следует установить DMA-IRQ на более высокий приоритет?
victor_pv
Солнце 13 сентября 2015 г., 22:42
Мадиас написал:Странно, я обязательно получу хотя бы значение «3» назад (перевод полная+перевод половина). Должен проверить это завтра (я все еще не дома).
Я немного подумал о кликах и всплесках, которые у меня есть с более высоким буфером, возможно, мне следует установить DMA-IRQ на более высокий приоритет?
Я немного подумал о кликах и всплесках, которые у меня есть с более высоким буфером, возможно, мне следует установить DMA-IRQ на более высокий приоритет?
Мадиас
Пн 14 сентября 2015 г. 5:52 утра
Я пробую это сегодня!
Один подумать: вы используете также «круговой буфер» в своем первом проекте? Я не уверен, но я думаю, что где-то я прочитал, что в круговом буфере полу-перенос (или полная передача) DMA не установит флаг.
Один подумать: вы используете также «круговой буфер» в своем первом проекте? Я не уверен, но я думаю, что где-то я прочитал, что в круговом буфере полу-перенос (или полная передача) DMA не установит флаг.
Мадиас
Пн 14 сентября 2015 г. 9:33 утра
ОК, Виктор, мы приближаемся!
Я попробовал ваш последний код, и он работает гладко на обоих каналах без отсевания/кликов.
Кроме того, я включил фиктивную задачу TFT (просто печать некоторые значения) с низким приоритетом. Итак, у меня есть четыре задачи: audio_engine, melody, serial и tft.
По соображениям безопасности (возможно, нет необходимости, но я включил его, чтобы помнить), я сделал
Я попробовал ваш последний код, и он работает гладко на обоих каналах без отсевания/кликов.
Кроме того, я включил фиктивную задачу TFT (просто печать некоторые значения) с низким приоритетом. Итак, у меня есть четыре задачи: audio_engine, melody, serial и tft.
По соображениям безопасности (возможно, нет необходимости, но я включил его, чтобы помнить), я сделал
nvic_irq_set_priority(NVIC_DMA2_CH2, 1); // DMA priority test
Мадиас
Пн 14 сентября 2015 г. 14:16
Хорошо,
Теперь я изменил DMA IRQ на:
Теперь я изменил DMA IRQ на:
static inline void DMAEvent() {
static signed portBASE_TYPE xYieldRequired;
if (dma_get_isr_bits( DMA2, DMA_CH2) == 3 ) {
gpio_write_bit(GPIOD, 2, 0); // test led off
xQueueSendFromISR(dmaQueue, (void*)&i2s_bottom, &xYieldRequired);
}
else {
gpio_write_bit(GPIOD, 2, 1); // test led on
xQueueSendFromISR(dmaQueue, (void*)&i2s_top, &xYieldRequired);
}
dma_clear_isr_bits(DMA2, DMA_CH2);
// flip2 = !flip2;
portEND_SWITCHING_ISR(xYieldRequired);
}
victor_pv
Вторник 15 сентября 2015 г. 12:59
Мадиас написал:ОК, Виктор, мы приближаемся!
Я попробовал ваш последний код, и он работает гладко на обоих каналах без отсевания/кликов.
Кроме того, я включил фиктивную задачу TFT (просто печать некоторые значения) с низким приоритетом. Итак, у меня есть четыре задачи: audio_engine, melody, serial и tft.
По соображениям безопасности (возможно, нет необходимости, но я включил его, чтобы помнить), я сделал
Я попробовал ваш последний код, и он работает гладко на обоих каналах без отсевания/кликов.
Кроме того, я включил фиктивную задачу TFT (просто печать некоторые значения) с низким приоритетом. Итак, у меня есть четыре задачи: audio_engine, melody, serial и tft.
По соображениям безопасности (возможно, нет необходимости, но я включил его, чтобы помнить), я сделал
nvic_irq_set_priority(NVIC_DMA2_CH2, 1); // DMA priority test
Мадиас
Вторник 15 сентября 2015 г., 21:01
Странно, что с переключением между DMA_BIT 5 и DMA_BIT3 в коде Один канал искажен.
Тем временем я создал полный лист для своего проекта. Только около 3-5 булавок бесплатно
Хорошо, я не очень экономный с булавками, поэтому каждая кнопка (только 5) получает собственную булавку, и мой энкодер (5) нуждается в 10 контактах (поэтому я могу настроить для них IRQ, что лучше для распознавания движений с разными скоростями, я В течение нескольких месяцев назад он опубликовал код с несколькими экодерками-ACC: ViewTopic.PHP?F = 18&t = 15 ), см. Прикрепленный PDF
Я также использую вместо внешнего (управление!) ЦАП для моей платы фильтров The Swm Pins, но я буду ждать, пока не будут отправлены мои фильтрующие доски (я сделал фильтрацию LP в цепи, поэтому SWM должен работать - с более высокой частотой)
Так что в целом мой проект был бы возможно только с одним STM32 (на чертежной доске).
Тем временем я создал полный лист для своего проекта. Только около 3-5 булавок бесплатно
Хорошо, я не очень экономный с булавками, поэтому каждая кнопка (только 5) получает собственную булавку, и мой энкодер (5) нуждается в 10 контактах (поэтому я могу настроить для них IRQ, что лучше для распознавания движений с разными скоростями, я В течение нескольких месяцев назад он опубликовал код с несколькими экодерками-ACC: ViewTopic.PHP?F = 18&t = 15 ), см. Прикрепленный PDF
Я также использую вместо внешнего (управление!) ЦАП для моей платы фильтров The Swm Pins, но я буду ждать, пока не будут отправлены мои фильтрующие доски (я сделал фильтрацию LP в цепи, поэтому SWM должен работать - с более высокой частотой)
Так что в целом мой проект был бы возможно только с одним STM32 (на чертежной доске).
victor_pv
Ср. 16 сентября 2015 г., 2:59
Мадиас написал:Странно, что с переключением между DMA_BIT 5 и DMA_BIT3 в коде Один канал искажен.
Тем временем я создал полный лист для своего проекта. Только около 3-5 булавок бесплатно
Хорошо, я не очень экономный с булавками, поэтому каждая кнопка (только 5) получает собственную булавку, и мой энкодер (5) нуждается в 10 контактах (поэтому я могу настроить для них IRQ, что лучше для распознавания движений с разными скоростями, я В течение нескольких месяцев назад он опубликовал код с несколькими экодерками-ACC: ViewTopic.PHP?F = 18&t = 15 ), см. Прикрепленный PDF
Я также использую вместо внешнего (управление!) ЦАП для моей платы фильтров The Swm Pins, но я буду ждать, пока не будут отправлены мои фильтрующие доски (я сделал фильтрацию LP в цепи, поэтому SWM должен работать - с более высокой частотой)
Так что в целом мой проект был бы возможно только с одним STM32 (на чертежной доске).
Тем временем я создал полный лист для своего проекта. Только около 3-5 булавок бесплатно
Хорошо, я не очень экономный с булавками, поэтому каждая кнопка (только 5) получает собственную булавку, и мой энкодер (5) нуждается в 10 контактах (поэтому я могу настроить для них IRQ, что лучше для распознавания движений с разными скоростями, я В течение нескольких месяцев назад он опубликовал код с несколькими экодерками-ACC: ViewTopic.PHP?F = 18&t = 15 ), см. Прикрепленный PDF
Я также использую вместо внешнего (управление!) ЦАП для моей платы фильтров The Swm Pins, но я буду ждать, пока не будут отправлены мои фильтрующие доски (я сделал фильтрацию LP в цепи, поэтому SWM должен работать - с более высокой частотой)
Так что в целом мой проект был бы возможно только с одним STM32 (на чертежной доске).
Мадиас
Ср. 16 сентября 2015 г. 5:38 утра
Просто для быстрого (должен идти на работу):
Вот XLS - Файл штифта, так что вы можете отредактировать его для собственных проектов:
Кстати: у меня есть ветеринарная доска (так же, как у вас!но я думаю, что это слишком хорошо, чтобы использовать его в этом проекте (хорошо, мне это нравится как основная доска для разработки!)
Использование кнопок с разделителем напряжения: может быть, идея с 5 кнопками (у меня дома много резисторных сет. (Немного другое основное напряжение = полное ложное значения).
Вот XLS - Файл штифта, так что вы можете отредактировать его для собственных проектов:
Кстати: у меня есть ветеринарная доска (так же, как у вас!но я думаю, что это слишком хорошо, чтобы использовать его в этом проекте (хорошо, мне это нравится как основная доска для разработки!)
Использование кнопок с разделителем напряжения: может быть, идея с 5 кнопками (у меня дома много резисторных сет. (Немного другое основное напряжение = полное ложное значения).
victor_pv
Чт 17 сентября 2015 г., 3:17 утра
Мадиас написал:Просто для быстрого (должен идти на работу):
Вот XLS - Файл штифта, так что вы можете отредактировать его для собственных проектов:
Кстати: у меня есть ветеринарная доска (так же, как у вас!но я думаю, что это слишком хорошо, чтобы использовать его в этом проекте (хорошо, мне это нравится как основная доска для разработки!)
Использование кнопок с разделителем напряжения: может быть, идея с 5 кнопками (у меня дома много резисторных сет. (Немного другое основное напряжение = полное ложное значения).
Вот XLS - Файл штифта, так что вы можете отредактировать его для собственных проектов:
Кстати: у меня есть ветеринарная доска (так же, как у вас!но я думаю, что это слишком хорошо, чтобы использовать его в этом проекте (хорошо, мне это нравится как основная доска для разработки!)
Использование кнопок с разделителем напряжения: может быть, идея с 5 кнопками (у меня дома много резисторных сет. (Немного другое основное напряжение = полное ложное значения).
Мадиас
Чт 17 сентября 2015 г. 14:31
Важное обновление (по крайней мере для меня)
Я дублирует I2S и код DMA (+задачи), чтобы получить два PT8211, поэтому я ближе к своей цели. Получить 4 независимых результатов. (Используя SPI2 (I2S) и SPI3 (I2S-2))
Статус: Работающий!
Забавный факт (По крайней мере, с сегодняшней точки зрения):
Второй Pt8211 всегда был шумным, и сигнал был тише, как только выходить из него 8-бит.
Я потратил 2 часа: (re) Написание кода, изучил правильные булавки, обменял PT8211....
В качестве последнего испытания я взял все кабели с первого PT до второго: тот же шум!
В отчаянии я в последний раз посмотрел на кабели и прыжки на макетинг - Vola! Джампер VCC для второго PT был на отверстии рядом с правым.
Заключение: Даже с наиболее сложным кодом решение может быть простой неправильно установленной перемычкой
Значит: PT работал без VCC, поэтому, если бы он не сработал, я бы быстрее пришел к ошибке....
Я дублирует I2S и код DMA (+задачи), чтобы получить два PT8211, поэтому я ближе к своей цели. Получить 4 независимых результатов. (Используя SPI2 (I2S) и SPI3 (I2S-2))
Статус: Работающий!
Забавный факт (По крайней мере, с сегодняшней точки зрения):
Второй Pt8211 всегда был шумным, и сигнал был тише, как только выходить из него 8-бит.
Я потратил 2 часа: (re) Написание кода, изучил правильные булавки, обменял PT8211....
В качестве последнего испытания я взял все кабели с первого PT до второго: тот же шум!
В отчаянии я в последний раз посмотрел на кабели и прыжки на макетинг - Vola! Джампер VCC для второго PT был на отверстии рядом с правым.
Заключение: Даже с наиболее сложным кодом решение может быть простой неправильно установленной перемычкой
Значит: PT работал без VCC, поэтому, если бы он не сработал, я бы быстрее пришел к ошибке....
Мадиас
Пт 18 сентября 2015 г. 15:34
Хорошо, в ожидании моих фильтров -досок (я надеюсь, что они будут отправлены в течение следующих 2 недель), я подумал еще о распиновки:
Кнопки, как предложил Виктор, теперь находятся на АЦП с разделителями напряжения (так что у меня около 10 кнопок)
Рукоявка выше-это полуавто. Просто перетащите «Использование» в списке, отсортированные по булавкам, и автоматическое, показанное в «Просмотке доски». Недостаток: цвета фона не клонированы (я понятия не имею, как это работает в Excel)
Итак, моя последняя установка:
2 Pt8211 ЦАП (4 независимых выходов)
10 кнопок (одна как нажмите энкодер)
5 энкодеров (один с кликом)
1 TFT ILI9341 с прикосновением
1 OLED (показывает функцию/значения энкодера)
1 Уинбонд Spi-Seeprom
1 23LC512 I2C-IEPROM (больше циклов записи/стирания)
SD-карта (от TFT)
Серийный миди
USB MIDI
Все элементы управления платой фильтров с помощью ШИМ (4x том, 4x отсечка и 1x резонанс (используется для всех голосов, нет необходимости в 4 независимых ресторанах)))
ST-Link Cable Out (самый простой способ обновления)
Кнопки, как предложил Виктор, теперь находятся на АЦП с разделителями напряжения (так что у меня около 10 кнопок)
Рукоявка выше-это полуавто. Просто перетащите «Использование» в списке, отсортированные по булавкам, и автоматическое, показанное в «Просмотке доски». Недостаток: цвета фона не клонированы (я понятия не имею, как это работает в Excel)
Итак, моя последняя установка:
2 Pt8211 ЦАП (4 независимых выходов)
10 кнопок (одна как нажмите энкодер)
5 энкодеров (один с кликом)
1 TFT ILI9341 с прикосновением
1 OLED (показывает функцию/значения энкодера)
1 Уинбонд Spi-Seeprom
1 23LC512 I2C-IEPROM (больше циклов записи/стирания)
SD-карта (от TFT)
Серийный миди
USB MIDI
Все элементы управления платой фильтров с помощью ШИМ (4x том, 4x отсечка и 1x резонанс (используется для всех голосов, нет необходимости в 4 независимых ресторанах)))
ST-Link Cable Out (самый простой способ обновления)
Мадиас
Вторник 29 сентября 2015 г., 19:35
Хорошо, вчера был мой самый темный день для этого проекта:
Мои доски для фильтров прибыли, я паял их, а потом: ничего. Проведен в целом около 12 часов (представьте себе: у меня есть жена, 3-летняя дочь и работа на полный рабочий день, так что время для меня очень * дорого) без решения. Я действительно думал сдаться даже со всей электроникой.
Сегодня я даю себе еще одну попытку, изучал мои файлы KICAD, оригинальные и таблицы, и я нашел это:
Снова супер глупый противный: я смутил один (!) 470R Резистор с крышкой 470PF. Ошибка была также в моем макете KICAD, и все остановилось на работе.
Хорошо, с рабочей платой фильтров (я полностью разгромил первую, ради небеса DirtyPcb отправил вам около 12 досок), я провел некоторое звуковое тестирование и упомянул, что с SWM нет шансов (3.3 В против 5 В (плата фильтров для 5 В)), поэтому я должен использовать Spi-Octal DAC (LT1660), не имеющего большого значения, потому что у меня есть их дома, но немного противно программировать: spi tft (и и SD) находится на Div2 и SPI-DAC потребности Div4. Пробовал много вещей, и самое лучшее для стабильности (без висящего TFT или ЦАП) - иметь дело с Div4.
Несколько слов о звуке платы фильтров: просто *потрясающе * !!! Настоящий аналоговый 4-полюсный низкий проход с дополнительным аналоговым VCA на борту. И самое лучшее: абсолютно никакого шума! Так что все мои сомнения исчезли....
Быстрая картинка настройки тестирования, плата фильтров - это белая печатная плата:
Мои доски для фильтров прибыли, я паял их, а потом: ничего. Проведен в целом около 12 часов (представьте себе: у меня есть жена, 3-летняя дочь и работа на полный рабочий день, так что время для меня очень * дорого) без решения. Я действительно думал сдаться даже со всей электроникой.
Сегодня я даю себе еще одну попытку, изучал мои файлы KICAD, оригинальные и таблицы, и я нашел это:
Снова супер глупый противный: я смутил один (!) 470R Резистор с крышкой 470PF. Ошибка была также в моем макете KICAD, и все остановилось на работе.
Хорошо, с рабочей платой фильтров (я полностью разгромил первую, ради небеса DirtyPcb отправил вам около 12 досок), я провел некоторое звуковое тестирование и упомянул, что с SWM нет шансов (3.3 В против 5 В (плата фильтров для 5 В)), поэтому я должен использовать Spi-Octal DAC (LT1660), не имеющего большого значения, потому что у меня есть их дома, но немного противно программировать: spi tft (и и SD) находится на Div2 и SPI-DAC потребности Div4. Пробовал много вещей, и самое лучшее для стабильности (без висящего TFT или ЦАП) - иметь дело с Div4.
Несколько слов о звуке платы фильтров: просто *потрясающе * !!! Настоящий аналоговый 4-полюсный низкий проход с дополнительным аналоговым VCA на борту. И самое лучшее: абсолютно никакого шума! Так что все мои сомнения исчезли....
Быстрая картинка настройки тестирования, плата фильтров - это белая печатная плата:
Вассилис
Вторник 29 сентября 2015 г. 20:57
Хороший!
Я хотел бы увидеть видео демонстрацию вашей доски, когда вы закончите ее!
пса. У меня есть жена, два Daugthers 13 и 11 лет, работа на полный рабочий день, и я работаю в химической промышленности с тремя сменами. Я знаю, что означает «свободное время» ...
Но... Когда вы любите что -то, вы можете найти время для этого
Я хотел бы увидеть видео демонстрацию вашей доски, когда вы закончите ее!
пса. У меня есть жена, два Daugthers 13 и 11 лет, работа на полный рабочий день, и я работаю в химической промышленности с тремя сменами. Я знаю, что означает «свободное время» ...
Но... Когда вы любите что -то, вы можете найти время для этого
victor_pv
Ср 30 сентября 2015 г. 1:46
Вассилис написал:Хороший!
Я хотел бы увидеть видео демонстрацию вашей доски, когда вы закончите ее!
Я хотел бы увидеть видео демонстрацию вашей доски, когда вы закончите ее!
Мадиас
Чт 01 октября 2015 г., 21:47
Я сделаю демо на YouTube, если готов представить что -то лучшее
ОБНОВЛЯТЬ:
ЦАП - ШИМ
Как я писал ранее, SWM как «аналоговое управление» для меня не является вариантом (3.3 против 5 В и слишком низкая частота ШИМ), поэтому я решил использовать SPI DAC LTC1660 (или LTC1665 (8 или 10 бит))).
Но у меня есть: 4x среза, 4x тома + общий канал для резонанса = 9 выходов. К сожалению, LTC - всего лишь восьмиугольный ЦАП. К счастью, STM32F103RCT имеет 2 бортовых ЦАП, но один (PA5) конфликт со SPI SCK. Но другой "чистый". Итак, у меня есть 9 аналоговых выходов
Отображать
Я думаю, что оставляю эту идею с TFT ILI9341 по нескольким причинам: замедлить систему, «негабаритный» - мне не нужны цвета для этого проекта, и на солнце не очень приятно видеть (яркость, просмотр угол). Поэтому я решил использовать большой монохромный дисплей 128x64 (ST7920, я написал библиотеку для этого --> См. Main Repo) как основной дисплей и вторичный I2C-oled (значения печати для кодеров).
RTOS
Я думаю, что я закончил с RTO для этого проекта: у меня слишком много проблем с ним. Хорошо, может быть.
Проблемы до сих пор: моя графическая библиотека LCD S7920 не будет работать с RTOS. Линии, коробки и другие графические элементы работают, но шрифт только мусор. Даже в коде установки я могу использовать шрифт. Поэтому я думаю, что должен быть большой конфликт памяти, особенно с библиотеками и большими массивами (например, шрифтами) (у меня было это при использовании библиотеки Adafruit ILI9341, но я поднимаю размер стека для задачи). Другая причина заключается в том, что я могу использовать около 90% письменного кода из моего бывшего проекта (с Tiva-TMC123), я справился со всем с таймерами. Следующая сделка: в RTO нет реальной интеграции с аппаратным таймером, а минимальная задержка составляет 1 мс (мне нужен NS). Я исследовал обе проблемы на форумах RTOS, нашел много записей, но нет решения.
редактировать: Получил ЖК -библиотеку для работы. Проблема заключалась в переменной «статической длинной XY» в другой задаче (ОК, кажется, что RTO не любят статические переменные в задачах....)
Но у меня есть вопрос:
В ЖК -библиотеке есть несколько задержек (x), я думаю, что это не подходит для RTOS (Vdelay), но я не могу справиться с этим (пытался использовать Vdelay в библиотеке, но она не будет функционировать)
ОБНОВЛЯТЬ:
ЦАП - ШИМ
Как я писал ранее, SWM как «аналоговое управление» для меня не является вариантом (3.3 против 5 В и слишком низкая частота ШИМ), поэтому я решил использовать SPI DAC LTC1660 (или LTC1665 (8 или 10 бит))).
Но у меня есть: 4x среза, 4x тома + общий канал для резонанса = 9 выходов. К сожалению, LTC - всего лишь восьмиугольный ЦАП. К счастью, STM32F103RCT имеет 2 бортовых ЦАП, но один (PA5) конфликт со SPI SCK. Но другой "чистый". Итак, у меня есть 9 аналоговых выходов
Отображать
Я думаю, что оставляю эту идею с TFT ILI9341 по нескольким причинам: замедлить систему, «негабаритный» - мне не нужны цвета для этого проекта, и на солнце не очень приятно видеть (яркость, просмотр угол). Поэтому я решил использовать большой монохромный дисплей 128x64 (ST7920, я написал библиотеку для этого --> См. Main Repo) как основной дисплей и вторичный I2C-oled (значения печати для кодеров).
RTOS
Я думаю, что я закончил с RTO для этого проекта: у меня слишком много проблем с ним. Хорошо, может быть.
Проблемы до сих пор: моя графическая библиотека LCD S7920 не будет работать с RTOS. Линии, коробки и другие графические элементы работают, но шрифт только мусор. Даже в коде установки я могу использовать шрифт. Поэтому я думаю, что должен быть большой конфликт памяти, особенно с библиотеками и большими массивами (например, шрифтами) (у меня было это при использовании библиотеки Adafruit ILI9341, но я поднимаю размер стека для задачи). Другая причина заключается в том, что я могу использовать около 90% письменного кода из моего бывшего проекта (с Tiva-TMC123), я справился со всем с таймерами. Следующая сделка: в RTO нет реальной интеграции с аппаратным таймером, а минимальная задержка составляет 1 мс (мне нужен NS). Я исследовал обе проблемы на форумах RTOS, нашел много записей, но нет решения.
редактировать: Получил ЖК -библиотеку для работы. Проблема заключалась в переменной «статической длинной XY» в другой задаче (ОК, кажется, что RTO не любят статические переменные в задачах....)
Но у меня есть вопрос:
В ЖК -библиотеке есть несколько задержек (x), я думаю, что это не подходит для RTOS (Vdelay), но я не могу справиться с этим (пытался использовать Vdelay в библиотеке, но она не будет функционировать)
victor_pv
Пт 02 октября 2015 г. 1:45
Чтобы использовать Vdelay в библиотеке, вам необходимо включить RTOS в файл CPP библиотеки.
Я провел некоторое тестирование, перезарязив библиотеку SPI и ILI9163 для COO, и должен был сделать это. Я не пробовал с Freertos, но я уверен, что был бы таким же случаем.
Тем не менее, вы можете сделать все это с таймерами, нет причин для RTOS. Я бы использовал RTOS, если бы это упростила мою жизнь, но не более сложной
Libmaple Systick ISR может быть настроен для обратного вызова вашей собственной функции каждые 1 мс, если это поможет вам запланировать некоторые задачи без использования RTO, а затем вы можете использовать любой другой таймер с гораздо более высокой частотой для других вещей. Дайте, чем вам не нужны таймеры для PWM, у вас должно быть много таймеров для этого.
О звуке, даже если это просто белый шум, я хотел бы его услышать, уделяло нам так много головных болей, чтобы заставить DMA i2s работать!!
Ах еще одна вещь, вы можете заблокировать планировщик RTOS во время чувствительных к времени функциям, так что это не оставляет определенного определения, когда вы не хотите, чтобы он был. Я забыл имена функций, но есть 2, один, один, чтобы заблокировать планировщик, а один, чтобы разблокировать его снова. Прерывания не будут затронуты. Вы можете сделать это, чтобы проверить, если вы подозреваете, что планировщик влияет на ваши функции каким -либо образом, поэтому вы блокируете, запускаете свой чувствительный код, разблокируйтесь снова.
Я провел некоторое тестирование, перезарязив библиотеку SPI и ILI9163 для COO, и должен был сделать это. Я не пробовал с Freertos, но я уверен, что был бы таким же случаем.
Тем не менее, вы можете сделать все это с таймерами, нет причин для RTOS. Я бы использовал RTOS, если бы это упростила мою жизнь, но не более сложной
Libmaple Systick ISR может быть настроен для обратного вызова вашей собственной функции каждые 1 мс, если это поможет вам запланировать некоторые задачи без использования RTO, а затем вы можете использовать любой другой таймер с гораздо более высокой частотой для других вещей. Дайте, чем вам не нужны таймеры для PWM, у вас должно быть много таймеров для этого.
О звуке, даже если это просто белый шум, я хотел бы его услышать, уделяло нам так много головных болей, чтобы заставить DMA i2s работать!!
Ах еще одна вещь, вы можете заблокировать планировщик RTOS во время чувствительных к времени функциям, так что это не оставляет определенного определения, когда вы не хотите, чтобы он был. Я забыл имена функций, но есть 2, один, один, чтобы заблокировать планировщик, а один, чтобы разблокировать его снова. Прерывания не будут затронуты. Вы можете сделать это, чтобы проверить, если вы подозреваете, что планировщик влияет на ваши функции каким -либо образом, поэтому вы блокируете, запускаете свой чувствительный код, разблокируйтесь снова.
Мадиас
Вт 20 октября 2015 г. 15:37
ОК, маленькое обновление:
В основном из модулей было построено:
В основном из модулей было построено:
Мадиас
Вт 20 октября 2015 г., 21:06
Быстрое и грязное видео (человеческий интерфейс - нет звука)
https: // youtu.be/tvv4jb7tqec
https: // youtu.be/tvv4jb7tqec
Ахулл
Вт 20 октября 2015 г., 22:05
Мадиас написал:Быстрое и грязное видео (человеческий интерфейс - нет звука)
https: // youtu.be/tvv4jb7tqec
https: // youtu.be/tvv4jb7tqec
Мадиас
Вт 17 ноября 2015 г., 17:03
Хорошо, этот проект действительно один шаг вперед и два шага назад:/
Я выгнал RTO из проекта, только проблемы с использованными библиотеками, и я не переписываю время каждого, и мне действительно лучше в таймерах с этим проектом.
ОК, мне удалось преобразовать все обратно, получил интерфейс запустить (кодеры, ручки, светодиоды...), Получил звук DMA для всех 4 каналов, работающих без кликов, все другие ЦАП (для VCA, отсечение...).
А теперь:
Я добавил еще несколько переменных и функций, и все шрифты на дисплее ST7920 - мусор. Все работает нормально, только шрифт - это проблема: так что печатные линии, круги, все в порядке. Так что я думаю, что должна быть утечка памяти и/или неправильные указатели. Но это происходит только с библиотекой ST8920, а не с Adafruit OLED, это ясно работает. Таким образом, чем больше кода (переменные) я вкладываю в него, тем больше мусора выходит, если я удаляю дополнительный код, шрифт становится правильным. Полностью расстраивает.
Я полагаю, что должны быть некоторые ошибки с разговором всего проглемема из оригинальной библиотеки, но я бы не подумал, что кто -то здесь может помочь мне, но я поместил здесь код библиотеки:
Что я сделал, так это сравнить обработку шрифта Adafruit GFX и из моей библиотеки (Extern Const... и так далее) без повезло.
Редактировать: во имя библиотеки есть «RTOS», но там больше нет RTOS.
с уважением
Матиас
Я выгнал RTO из проекта, только проблемы с использованными библиотеками, и я не переписываю время каждого, и мне действительно лучше в таймерах с этим проектом.
ОК, мне удалось преобразовать все обратно, получил интерфейс запустить (кодеры, ручки, светодиоды...), Получил звук DMA для всех 4 каналов, работающих без кликов, все другие ЦАП (для VCA, отсечение...).
А теперь:
Я добавил еще несколько переменных и функций, и все шрифты на дисплее ST7920 - мусор. Все работает нормально, только шрифт - это проблема: так что печатные линии, круги, все в порядке. Так что я думаю, что должна быть утечка памяти и/или неправильные указатели. Но это происходит только с библиотекой ST8920, а не с Adafruit OLED, это ясно работает. Таким образом, чем больше кода (переменные) я вкладываю в него, тем больше мусора выходит, если я удаляю дополнительный код, шрифт становится правильным. Полностью расстраивает.
Я полагаю, что должны быть некоторые ошибки с разговором всего проглемема из оригинальной библиотеки, но я бы не подумал, что кто -то здесь может помочь мне, но я поместил здесь код библиотеки:
Что я сделал, так это сравнить обработку шрифта Adafruit GFX и из моей библиотеки (Extern Const... и так далее) без повезло.
Редактировать: во имя библиотеки есть «RTOS», но там больше нет RTOS.
с уважением
Матиас
Mrburnette
Вторник 17 ноября 2015 г., 17:11
Мадиас написал:
<...>
Таким образом, чем больше кода (переменные) я вкладываю в него, тем больше мусора выходит, если я удаляю дополнительный код, шрифт становится правильным. Полностью расстраивает.
<...>
Матиас
Таким образом, чем больше кода (переменные) я вкладываю в него, тем больше мусора выходит, если я удаляю дополнительный код, шрифт становится правильным. Полностью расстраивает.
<...>
Матиас
Мадиас
Вт 17 ноября 2015 г., 17:18
Я использую RCT6 (и выбрал его), так что минимум 48 КБ (Victor использует этот чип с 64 КБ):
Sketch использует 141 844 байта (54%) пространства для хранения программы. Максимум составляет 262 144 байта.
Глобальные переменные используют 28 104 байта динамической памяти.
Sketch использует 141 844 байта (54%) пространства для хранения программы. Максимум составляет 262 144 байта.
Глобальные переменные используют 28 104 байта динамической памяти.
Мадиас
Вт 17 ноября 2015 г., 17:20
Хорошо, я определил большой массив как «const» (волнообразные данные, мне нужна скорость от SRAM, но это было легко попробовать):
Sketch использует 141 844 байта (54%) пространства для хранения программы. Максимум составляет 262 144 байта.
Глобальные переменные используют 11 720 байт динамической памяти.
Но тот же мусор на выставке. Я думаю, необходимо быть проблемой с указателем доступа к вспышке или что -то в этом роде.
Редактировать массивы шрифтов в Flash ("Extern Const fontdata XY")
Sketch использует 141 844 байта (54%) пространства для хранения программы. Максимум составляет 262 144 байта.
Глобальные переменные используют 11 720 байт динамической памяти.
Но тот же мусор на выставке. Я думаю, необходимо быть проблемой с указателем доступа к вспышке или что -то в этом роде.
Редактировать массивы шрифтов в Flash ("Extern Const fontdata XY")
Мадиас
Вторник 17 ноября 2015 г. 18:58
Хорошо, я думаю, что лучшее (и наиболее трудоемкое) решение - это объединить (лучше сокращать) моя библиотека ST8920 с Adafruit GFX One. Хорошая вещь в этом заключается в том, что мне не придется использовать несколько шрифтов (даже дважды), и все «графические функции» оставайтесь в пределах Adafruit GFX One. Следующие несколько часов, чтобы потратить....
Ахулл
Вторник 17 ноября 2015 г., 21:38
Искаженная дисплей звучит больше как проблема времени. Поскольку один либера. Я бы пошел с Adafruit Libs, добавить шрифты к ним, как правило, довольно просто.
Мадиас
Вт 17 ноября 2015 г., 22:36
Нет, не проблема времени, я установил все время задержки письма гораздо дольше. Странно то, что вся графика (коробки, строки) в порядке, без проблем, и вторичный дисплей (олинный библиотекой Adafruit) работает хорошо!
Должно быть действительно плохая вещь с «константом» и указателями для шрифтов (вся структура шрифта - это полностью указатель и «структура» безумие). Библиотека не идеальна, но неудача: я сделал полный графический интерфейс с этим куском S....без пост, включая создание собственных шрифтов и персонажей.
Я не могу использовать библиотеку Adafruit для этого дисплея (потому что их нет) . Единственная поддержка «Универсальной библиотеки» The ST7920 - это U8Glib, и я никогда не буду переносить этого монстра в STM32Duino, потому что он слишком большой и хочет поддержать все, поэтому вам нужны месяцы, чтобы адаптировать код. (Библиотека около 1 МБ!!).
Действительно плохая шутка в том, что я адаптировал многие библиотеки отображения с начала проекта STM32Duino для сообщества, и теперь я полностью терпеть неудачу со своим единственным.
Может быть, я немного объявляю структуру шрифта:
шрифты находятся в отдельном файле:
Пример: GLCD5X5_STM.CPP
В этом файле:
Должно быть действительно плохая вещь с «константом» и указателями для шрифтов (вся структура шрифта - это полностью указатель и «структура» безумие). Библиотека не идеальна, но неудача: я сделал полный графический интерфейс с этим куском S....без пост, включая создание собственных шрифтов и персонажей.
Я не могу использовать библиотеку Adafruit для этого дисплея (потому что их нет) . Единственная поддержка «Универсальной библиотеки» The ST7920 - это U8Glib, и я никогда не буду переносить этого монстра в STM32Duino, потому что он слишком большой и хочет поддержать все, поэтому вам нужны месяцы, чтобы адаптировать код. (Библиотека около 1 МБ!!).
Действительно плохая шутка в том, что я адаптировал многие библиотеки отображения с начала проекта STM32Duino для сообщества, и теперь я полностью терпеть неудачу со своим единственным.
Может быть, я немного объявляю структуру шрифта:
шрифты находятся в отдельном файле:
Пример: GLCD5X5_STM.CPP
В этом файле:
#include "lcd7920_STM_RTOS.h"
const uint8_t glcd5x5_STM[] = (...font data...)
Mrburnette
Вт 17 ноября 2015 г., 22:42
Мадиас написал:
<...>
Действительно плохая шутка в том, что я адаптировал многие библиотеки отображения с начала проекта STM32Duino для сообщества, и теперь я полностью терпеть неудачу со своим единственным.
<...>
Действительно плохая шутка в том, что я адаптировал многие библиотеки отображения с начала проекта STM32Duino для сообщества, и теперь я полностью терпеть неудачу со своим единственным.
<...>
Мадиас
Вторник 17 ноября 2015 г., 11:00 вечера
Здесь, в Вене, находится в середине ночи
Но спасибо за предложение с бокалом вина, я пью 1/8 время от времени
Но спасибо за предложение с бокалом вина, я пью 1/8 время от времени
Мадиас
Вторник 17 ноября 2015 г. 11:05
Кстати: «мусор» каждый раз один и тот же даже после сброса, так что не случайная вещь
Mrburnette
Вторник 17 ноября 2015 г. 11:35
Мадиас написал:Кстати: «мусор» каждый раз один и тот же даже после сброса, так что не случайная вещь
Ахулл
Ср 18 ноября 2015 г. 12:34
Хм в вашем примере вы начинаете с Font 5x5, затем
const extern lcdfont font5x9_stm;
5x9 тогда...
ЖК -дисплей.setFont (&font13x14_stm);
13x14.. Я в замешательстве, это 5x5, 5x9, 13x14... или я немного медленно поглощаю здесь?
const extern lcdfont font5x9_stm;
5x9 тогда...
ЖК -дисплей.setFont (&font13x14_stm);
13x14.. Я в замешательстве, это 5x5, 5x9, 13x14... или я немного медленно поглощаю здесь?
Мадиас
Ср 18 ноября 2015 г. 11:01
Ахулл написал: Я в замешательстве, это 5x5, 5x9, 13x14... или я немного медленно поглощаю?
Мадиас
Ср 18 ноября 2015 г., 17:16
ХОРОШО!
Я только что реализовал adafruit gfx_as вместо использования оригинальных шрифтов драйверов (и даже графических функций).
Первый тест выглядит хорошо, но я только что протестировал минимальный код, поэтому я могу принести его в свой основной код и переписать графический интерфейс. Надеюсь, это сработает.
Основное преимущество: Помимо того, что мне не нужно использовать разные шрифты (для ST7920 и OLED), библиотека ST7920 есть; более или менее; Полностью совместимо со всеми другими библиотеками дисплея Adafruit (почти 99% по сравнению с SSD1306 из -за того же размера экрана) плюс преимущества двух отдельных буферов аппаратного экрана (чтобы я мог написать на один экран, в то время как другой отображается, как Два виртуальных экрана, но с преимуществом, которое встроено в аппаратном обеспечении, поэтому для переключения между ними необходима одна команда, а не все версии программного обеспечения, которые просто отправляют весь буфер на дисплей во время переключения). Я думаю, что это было лучшее решение, и это не было - удивительно - на самом деле нет боли, чтобы переоценить его!
Для сообщества я проверю новую библиотеку как смогу, и я помесчу ее в главное репо. (Я думаю, что я смогу немного оптимизировать метод «Drawpixel».
Я только что реализовал adafruit gfx_as вместо использования оригинальных шрифтов драйверов (и даже графических функций).
Первый тест выглядит хорошо, но я только что протестировал минимальный код, поэтому я могу принести его в свой основной код и переписать графический интерфейс. Надеюсь, это сработает.
Основное преимущество: Помимо того, что мне не нужно использовать разные шрифты (для ST7920 и OLED), библиотека ST7920 есть; более или менее; Полностью совместимо со всеми другими библиотеками дисплея Adafruit (почти 99% по сравнению с SSD1306 из -за того же размера экрана) плюс преимущества двух отдельных буферов аппаратного экрана (чтобы я мог написать на один экран, в то время как другой отображается, как Два виртуальных экрана, но с преимуществом, которое встроено в аппаратном обеспечении, поэтому для переключения между ними необходима одна команда, а не все версии программного обеспечения, которые просто отправляют весь буфер на дисплей во время переключения). Я думаю, что это было лучшее решение, и это не было - удивительно - на самом деле нет боли, чтобы переоценить его!
Для сообщества я проверю новую библиотеку как смогу, и я помесчу ее в главное репо. (Я думаю, что я смогу немного оптимизировать метод «Drawpixel».