Статистика
Время:
Зарегистрированных: 88378
Последним зарегистрирован: psa07
Рекорд посещаемости: 12585
Групп пользователей: 4
 Группы:
[Admin] [Cоучастник] [Автор] [Модератор]
 Сейчас на сайте
 Всего: 386
 Гостей: 380
 Анонимных: 0
 Пользователей: 6
 Зарегистрированные:
kollega wasa63 pavel23 MIRW vaneok ded

> Для дома, для семьи. -> Мультимедиа-плеер с OLED-дисплеем
А не замутить ли нам цифровой мультимедиа-плеер?

© Riba 2018

1. Предыстория.

В новогодние праздники появилось свободное время, которое решил потратить на создание какого-нибудь электронного устройства. При наведении порядка в своём электронном барахле, провёл ревизию и обнаружил без дела лежащие компоненты: дисплеи от сотовых телефонов, OLED-дисплеи, отладочная плата с дисплеем 320x240, повышающий преобразователь напряжения MT3608, отладочная плата STM32F4-Discovery, дохлый аудио-плеер Ritmix на базе чипа RKnanoB, Li-Po аккумулятор от сотового телефона, переходник SD-SDmicro, мелкие динамики от сотовых телефонов и ещё куча мелочей…
Мозг долго думал, что можно из всего этого интересного сделать и наконец надумал! Было принято решение сделать несложный мультимедиа-плеер, для просмотра видео со звуком. В качестве ядра решил использовать микроконтроллер STM32F407 в отладочной плате STM32F4-Discovery. Почему был выбран именно он? Есть ряд причин, определяющих выбор в его пользу:

- есть в наличии как сами микроконтроллеры, так и отладочная плата
- есть опыт в его освоении
- аппаратная поддержка расчётов с плавающей точкой (для обработки данных это важно)
- 32 разряда, относительно высокая частота (для обработки данных это также важно)
- несколько видов DMA-каналов (память-память, память-внешнее устройство)
- есть ЦАП для вывода звука (вместе с таймером и DMA можно замутить SoundBlaster)
- есть FSMC для подключения дисплея (это быстрее, чем SPI или ногодроч через GPIO)
- несложная обвязка, одно напряжение питания
- паябельный корпус и относительно небольшое число выводов
- наличие IDE для написания программ

2. Выбор видео-формата.

Учитывая относительно скромные возможности микроконтроллера STM32F407 по сравнению с теми же BlackFin или AllWinner, было принято решение выбрать видео-кадр с разрешением QQVGA (буквально “четверть четверти VGA”) – 160x120, позже увеличено до 160x128 из-за дисплея. Был выбран формат сжатия MJPEG, который позволяет получить среднее сжатие в 5 раз, при этом отдельно взятый кадр выглядит не хуже JPEG с качеством 80%. В MJPEG сжатие идёт только для каждого кадра в отдельности, в отличие от MPEG4, где для большей эффективности применяется ещё и межкадровое сжатие.

Пример: видеозапись MJPEG 160x128 yuv420 длительностью 58 секунд с 12 FPS занимает 4.2 МБ. Без сжатия размер составил бы: 160*128 *2 байта/пиксел * 12 FPS * 58 s /1024/1024 = 27.1875 МБ. Выигрыш в сжатии: 27.1875/4.2 = 6.47 > 5.

При таком раскладе, максимальный FPS на STM32F407 при частоте 168 МГц получается в районе 20..24. При этом видеоданные считываются с SD-карты порциями по 512 байт (один сектор SD-карты). Карта работает в 4-битном SDIO-режиме на тактовой частоте 24 МГц. Было принято решение выбрать число кадров в секунду равным 12, так как для просмотра мультфильмов этого оказалось достаточно. Также при 12 FPS обеспечивается лёгкое согласование со звуковым потоком, о нём дальше.

Макет мультимедиа-плеера:

image

3. Выбор аудио-формата.

Было принято решение использовать IMA ADPCM-сжатие для звука, которое даёт всегда выигрыш в сжатии ровно в 4 раза. В одном байте IMA ADPCM закодировано два 16-битных сэмпла PCM. При этом мощности STM32F407 вполне хватает, а ставить дополнительно MP3-декодер не хотелось (по причине усложнения конструкции). Чтобы не усложнять декодирование видео- и аудио- контента, а также не увеличивать размер файла данных избыточными служебными данными, было принято решение хранить данные видео и звука в разных файлах.

4. Конверсия данных.

Для конверсии данных используется программа fmmpeg (бесплатная и свободная). Для исходного файла видео:

ffmpeg -i in.mp4 -s 160x128 -r 12 -c:v mjpeg -qscale:v 0 -an out.avi

где:
in.mp4 – исходный видео-файл
160x128 – требуемое разрешение на выходе
12 - требуемый FPS на выходе
mjpeg – требуемый кодер
0 – наилучшее качество кадра
out.avi – выходной видео-файл

ffmpeg -i in.mp4 -ar 24000 -ac 1 -c:a pcm_s16le out.wav

где:
24000 – требуемая частота дискретизации (24 кГц, верхняя будет 12 кГц)
1 – требуемое количество каналов (моно)
pcm_s16le – требуемый формат сэмпла (PCM 16 бит, знаковый, Little Endian)

Так как программа fmmpeg даёт разделенный на фреймы поток IMA ADPCM на выходе, было решено использовать дополнительную конверсию WAV=>IMA ADPCM (одним непрерывным потоком, без разделения на фреймы) с помощью программы imacodec:

imacodec out.wav out.ima out2.wav

где:
out.wav – исходный звуковой файл (получен ранее от fmmpeg)
out.ima – требуемый выходной файл (непрерывный поток, без деления на фреймы)
out2.wav – декодированный out.ima обратно (не нужен, только в качестве проверки)

В итоге мы получили нужные файлы: out.avi и out.ima. Их и будем декодировать STM32F4.

Исходники программы imacodec в Приложении 1 (проект написан в среде OpenWatcom C).
Видео работающего плеера в Приложении 2.

Мультимедиа-плеер в действии:

image

5. Библиотеки.

Для написания программы мультимедиа-плеера использовались следующие библиотеки:

TJpgDec - Tiny JPEG Decompressor: http://elm-chan.org/fsw/tjpgd/00index.html
FatFs - Generic FAT Filesystem Module: http://elm-chan.org/fsw/ff/00index_e.html
IMA ADPCM Codec: http://easyelectronics.ru/files/WE/redsh/ima_project.zip

6. Выбор дисплея.

Вначале рассматривал дисплей от сотового телефона LG KP105. Этот дисплей поддерживает разрешение 132x132, количество цветов до 65 тыс. Обмен данными через SPI, контроллер дисплея ST7637 или S6B33BG. Зарядив SPI обмен через DMA, можно было получить до 89 FPS в пределе (SPI клок 40 нс, значит отрисовка всего кадра займёт 132*132 *16 бит * 40 нс = 0.01115135 с, что соответствует 89 FPS). Но плохие отзывы “качества картинки” оттолкнули меня от использования данного дисплея. Из описания владельцев телефона LG KP105: “картинка в синих тонах”, “не видно на солнце”. Ещё добавить сюда большой отклик матрицы, который смазывает картинку при движении.

Этот дисплей был подробно разжёван на http://vrtp.ru/index.php?showtopic=28969

image

Следующим кандидатом стал знаменитый “китайский” QVGA-дисплей в виде отладочной платы, на которой кроме дисплея ещё установлены: разъем для SD-карты и контроллер резистивного тачпада. Эта “сборная солянка” удобна прежде всего тем, что у неё есть штыри PLS для подключения. Контроллер дисплея ILI9341. На первых порах использовал его. Обмен данными был через FSMC, шина 16 бит. Сделал даже отрисовку дисплея через DMA, причем 32-битными порциями. Данный дисплей пришлось заменить на OLED по следующим причинам: большая часть площади не задействована под кадр (у нас 160x128, а не 320x240), большие габариты и самое главное – относительно низкая чёткость картинки (намного лучше, чем у LG KP105 LCD, но хуже, чем у OLED), “белый” чёрный цвет.

Тем не менее, исходный код для работы с этим дисплеем выложен в Приложении 3.

Здесь упомяну лишь важные моменты.

Времянки FSMC для этого дисплея должны быть такими:

CODE
fsmcTiming.FSMC_AddressSetupTime=0;
fsmcTiming.FSMC_AddressHoldTime=0;
fsmcTiming.FSMC_DataSetupTime=3;
fsmcTiming.FSMC_BusTurnAroundDuration=0;
fsmcTiming.FSMC_CLKDivision=0;
fsmcTiming.FSMC_DataLatency=0;


Использование времянок, взятых из интернета у “китайских друзей”, приводило к эффекту “прокручивания кадра по горизонтали”, что указывало на некорректную установку FSMC для этого дисплея (или из-за длинных проводов?). Тем не менее, мой вариант времянки более быстр, чем “китайский” и работает “как часы”, что не может не радовать!

Функция вывода на дисплей ведётся 32-битными записями. Так как дисплей был подключен к 16-битной шине, то FSMC формировал два обращения по 16 бит, что быстрее, чем одно:

CODE
void Frame_To_LCD(void)
{
register u32* FB=(u32*)FrameBuffer;
register u32 i=(W*H)>>1;
while(i--)LCD_Reg_DAT32=FB++[0];
}


Сами же порты ввода-вывода дисплея описаны как участки памяти:

CODE
#define LCD_Reg_COM (*(volatile u16*)0x60000000)
#define LCD_Reg_DAT (*(volatile u16*)0x60020000)
#define LCD_Reg_DAT32 (*(volatile u32*)0x60020000)


Вариант работы дисплея через DMA. Здесь также передаём порциями по 32 бита. Подготовка DMA память-память:

CODE
void Frame_To_LCD_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);

DMA_DeInit(DMA2_Stream0);

DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&FrameBuffer[0];
DMA_InitStructure.DMA_Memory0BaseAddr   =(u32)&LCD_Reg_DAT32;
DMA_InitStructure.DMA_DIR               =DMA_DIR_MemoryToMemory;
DMA_InitStructure.DMA_BufferSize        =(W*H)>>1;
DMA_InitStructure.DMA_PeripheralInc     =DMA_PeripheralInc_Enable;
DMA_InitStructure.DMA_MemoryInc         =DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize    =DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode              =DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority          =DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_FIFOMode          =DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold     =DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst       =DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst   =DMA_PeripheralBurst_Single;

DMA_Init(DMA2_Stream0,&DMA_InitStructure);
}


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

CODE
void Frame_To_LCD_DMA(void)
{
while(DMA_GetCmdStatus(DMA2_Stream0)!=DISABLE);
DMA_ClearITPendingBit(DMA2_Stream0,DMA_IT_TCIF0);
DMA_Cmd(DMA2_Stream0,ENABLE);
}


Далее нет смысла задерживаться на этом дисплее. Напоследок приведу внешний вид отладочной платы на нём:

image

Ну и наконец, OLED-дисплей. Давным-давно, когда не было китайской барахолки ALI и всяких разных Arduino с китайскими сорцами, мне удалось в КТЦ МК через юрлицо заказать несколько OLED-дисплеев UG-6028 и разъёмов к ним. Дисплей имеет разрешение 160x128 и способен воспроизводить до 262 тыс. цветов. Контроллер SEPS525, шина у дисплея 9 бит (быстрее, чем SPI, но медленнее 16-битной).

Так как отладочной платы у меня не было, пришлось её ЛУТ-ом самому сделать. В Sprint Layout быстро накидал и вот что вышло:

image

Файл печатной платы – в Приложении 4. Подключение дисплея было выбрано 8-битным для удобства. Схема включения:

image

Сам дисплей и качество картинки на нём:

image

Высокие: чёткость, насыщенность и контрастность картинки, малые габариты этого OLED-дисплея, видимость под любым углом, быстрый отклик матрицы – определили мой выбор в пользу его использования.

В настоящее время на ALI можно заказать отладочную плату с таким OLED-дисплеем и не мудохаться с изготовлением своей платы. А также, нет гемора с требованием оформления заказа через юрлицо. И разъём искать не нужно (там 35 контактов с шагом 0.5 мм)! На плату даже напаян повышающий преобразователь напряжения для питания матрицы!

image

К недостаткам этого OLED-дисплея следует отнести:

1. Два напряжения питания как минимум, одно из которых +12V для питания матрицы
2. Высокий максимальный ток потребления матрицы 150 мА
3. Более короткий срок службы по сравнению с другими видами дисплеев

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

Упомяну важные детали при работе с дисплеем.

В мультимедиа-плеере выбран режим 65 тыс. цветов, что требует 16 бит. Но шина дисплея выбрана 8 бит, причём старший байт передаётся первым (см. даташит на контроллер дисплея SEPS525). Значит, для работы DMA в случае длины 16 или 32 бит требуется коррекция данных – перестановка байтов в пикселе (byte swap). На STM32F407 эта задача решается крайне красиво, с применением всего одной ассемблерной инструкции:

CODE
__asm("REV16 w,w"); //или что равносильно, но медленее: w=(w<<8)|(w>>8);


Данное изменение сделано в файле tjpgd.c.
В этом же файле добавлена ещё одна ассемблерная инструкция STM32 для беззнакового насыщения, которая работает быстрее, чем проверка границ через условия или задание табличных данных:

CODE
inline BYTE BYTECLIP(INT val)
{
__asm("USAT val,#8,val");
return (BYTE)val;
}


Также следует учесть, что в случае 8-битной длины шины, адреса портов ввода-вывода дисплея через FSMC будут такими:

CODE
#define OLED_Reg_COM   (*(volatile  u8*)0x60000000)
#define OLED_Reg_DAT   (*(volatile  u8*)0x60010000)
#define OLED_Reg_DAT32 (*(volatile u32*)0x60010000)


Напоследок приведу тайминги FSMC для OLED-дисплея:

CODE
fsmcTiming.FSMC_AddressSetupTime=0;
fsmcTiming.FSMC_AddressHoldTime=0;
fsmcTiming.FSMC_DataSetupTime=2;
fsmcTiming.FSMC_BusTurnAroundDuration=0;
fsmcTiming.FSMC_CLKDivision=0;
fsmcTiming.FSMC_DataLatency=0;


7. Повышающий преобразователь напряжения.

Для питания матрицы OLED-дисплея нужно напряжение питания 8..18V с током отдачи до 150 мА. Даташит на SEPS525 говорит, что оптимальное напряжение питание 16V, а в Evaluation Kit User Guide на UG-6028 говорится о величине 12V.

Мной были проведены эксперименты с замерами, в результате которых стало ясно, что повышать напряжение выше 12V нет смысла, матрица входит в насыщение и максимальный ток потребления (когда весь экран белый) достигает 150 мА. Яркость при этом растёт уже не так быстро, как в промежутке от 8 до 12V.

Был выбран преобразователь MT3608 из-за его наличия у меня на руках:

image

Следует отметить, что данный “китайский шедевр” – великая коллекция “гениальных” ошибок, которые разжёваны в интернете. Но лучшего, к сожалению, у меня не оказалось.
Ошибка номер 1: неправильно включен регулировочный резистор. Вы будете до упора крутить его в надежде поймать изменение выходного напряжения, но лёд тронется только ближе к концу, причём внезапно и резко! Ошибка лечится припайкой перемычки:

image

После исправления этой ошибки обязательно проверить и выставить нужное выходное напряжение на холостом ходу (теперь оно будет плавно регулироваться на полном диапазоне резистора), иначе велик риск сжечь дисплей (данный преобразователь способен отдать до 25V на выходе).

Ошибка номер 2: сильно длинная трасса от диода Шоттки, что порождает импульсы на выходе и высокий уровень помех по воздуху (может отрицательно сказаться на помехозащищённости в отношении микроконтроллера и аналоговых узлов). Лечится тотальной переразводкой печатной платы как надо.

Ошибка номер 3: отсутствие конденсаторов высокой ёмкости на входе и особенно на выходе. Были поставлены танталовые конденсаторы 100 мкФ 25V + керамические 10 мкФ. Уровень пульсаций выходного напряжения заметно уменьшился.

Ошибка номер 4 (опционально): заменить дроссель 22 мкГн на нужный номинал при известном выходном напряжении и токе отдачи. Проще говоря, произвести перерасчёт с заменой.

Ну и конечно же, этот модуль не выдаст 2A, как клятвенно обещает даташит на него. Почему, подумайте сами…

А теперь посмотрим, сколько будет потреблять это преобразователь, в случае максимального тока потребления OLED-дисплея (весь экран белый).

На выходе максимальная мощность: 12V * 150 мА = 1.8 Вт.
КПД преобразователя при токе 150 мА – 92.5% :

image

Значит потребляемая мощность на входе: 1.8/0.925 ~ 1.946 Вт
Источник питания – аккумулятор Li-ion 3.7V, значит максимальный потребляемый ток преобразователя будет равен: 1.946/3.7 ~ 0.526 А !!!

Мой опыт показал, что свежезаряженной Li-Polymer батареи от телефона Sony Ericsson ёмкостью 930 mAh и напряжением 3.6V - хватило на 170 минут (около 3 часа). Это соответствует среднему току потреблению всего устройства: 930/2.8(3) ~ 328 мА.

В окончательной версии, лучше предусмотреть аккум ёмкостью по-больше.

8. Звуковая система.

Для вывода звука было принято решение использовать внутренний DAC STM32F407 в режиме 12 бит. Вместе с DMA, который тактируется таймером, а также прерыванием по заполнению буфера - возможно реализовать звуковую подсистему, похожую на старый добрый SoundBlaster (олдфаги помнят!). Программно реализован кольцевой буфер, каждое заполнение его половины вызывает прерывание, в котором считываются новые данные, а также декодируется IMA ADPCM в PCM. Таким образом, реализовано непрерывное воспроизведение звуковых данных через DAC, при этом микроконтроллер отвлекается только во время прерываний.

Несколько слов о выборе частоты сэмплирования и прочих вещах.

Частота была выбрана 24 кГц, при ADPCM сжатии (4 бита на сэмпл) битрейт будет равным 24 кГц* 4 бит = 96 кБит/с. Верхняя звуковая частота: 24 кГц /2 = 12 кГц (теорема Котельникова), что приемлемо для уха. Таким образом, воспроизводятся звуковые частоты в диапазоне 0..12 кГц. Теперь надо подсчитать длину звукового буфера ADPCM в байтах, чтобы засинхронизировать показ кадров видео с прерыванием DMA DAC: 24 кГц / 12 FPS * 0.5 = 1000 байт. Берется 0.5 потому что в одном байте ADPCM содержится 2 семпла.

В обработчик прерывания вводим переменную-флаг для синхронизации показа кадров видео – как только отыграла любая половина звукового буфера, разрешаем декодировать и показать 1 кадр видео, затем делаем всё остальное и ждём до тех пор, пока снова не отыграет следующая очередная половина звукового буфера. Таким образом, показ видео жёстко засинхронизирован со звуком.

Если слушать на наушники (от 30 Ом и выше), то сигнал можно брать прямо с ножки DAC без усилителя. Схема ниже:

image

В этой схеме номинал конденсатора ФНЧ выбран слишком большим из-за того, что добротность фильтра занижена низкоомными наушниками. Поэтому чтобы убрать избыток ВЧ, пришлось ёмкость увеличить. Наушники рекомендуется включить последовательно, чтобы увеличить сопротивление нагрузки. Использование динамика вместо наушников в этой схеме не оправдано: звук будет очень тихим.

Было принято решение использовать УНЧ с динамиком для увеличения громкости. В качестве усилителя использована микросхема MC34119 – мостовой УНЧ, который качает мембрану динамика в два направления, в таких схемах нет разницы какой полярностью подсоединять динамик. Коэффициент усиления по напряжению выбран небольшим Ku=2, усилитель в основном усиливает по току Ki~∞. В цепи обратной связи конденсатор для реализации ФНЧ с частотой среза: fc = 1/(2*π * 1.2 кОм * 10 нФ) = 13.2 кГц.

image

На скорую руку развёл в Sprint Layout плату для этого усилителя:

image

Файл этой платы дан в Приложении 5.

Тут следует упомянуть, что максимально возможное напряжение на выходе DAC равно напряжению питания микроконтроллера +3V, поэтому при Ku=2 ожидаемая максимальная амплитуда сигнала 6V, но при питании УНЧ +3V произойдет отсечка амплитуды выходного сигнала, что приведёт к искажениям. Расчёт был сделан исходя из того, что большинство видео имеют звуковую дорожку со слабой амплитудой, используется до 50% от максимального значения.

Вместо голого динамика было решено использовать модуль акустической системы от сотового телефона Sony Ericsson W580i. Наличие резонатора (корпуса) вокруг динамика – эффективно увеличивает громкость звука, независимо от положения динамика. Ниже на картинке - опробованные варианты крохотных динамиков от телефонов и ноутбуков:

image

Все что сверху – не подошли из-за очень тихого звучания. Сгруппированные под буквой “A” – звучали громче всех, но при условии, если соприкасались с деревянной поверхностью стола или держались в руке. Динамик под буквой “B” – звучал довольно громко, если его держать перед лицом, то режет слух и вызывает слёзы на глазах. Под буквой “C” – акустические системы от SE W580i и ноутбука соответственно – лучшие кандидаты на использование в мультимедиа-плеере!

9. Источник данных.

Было принято решение использовать карту SD micro для хранения видео- и аудио- данных. Карта подключена к SDIO интерфейсу STM32F407 в 4-битном режиме и работает на частоте 24 МГц. Использовалась стандартная библиотека от ST (написана индусами – очень глючная и нестабильная) для работы с картами. Режим работы - чтение SD карты без DMA, так как совместно с FatFs режим DMA работал нестабильно. Подключение карты SD к микроконтроллеру стандартное, без использования внешних подтягивающих резисторов на линиях D0..D3 и CMD – используются внутренние подтяжки:

image

Тут следует отметить очень важную деталь – напряжение питания SD карты должно быть одинаково с напряжением логической единицы портов! Если запитать карту напряжением 3.3V, а микроконтроллер 3V, то карта работать не будет из-за перекоса логических уровней – лично проверено.

Также карта может потреблять довольно много тока, рекомендуется разделять аналоговые питания/земли во избежание помех в звуковом тракте DAC-УНЧ.

В текущем макете мультимедиа-плеера используется SD micro + переходник на SD + SD-разъём. Это сделано прежде всего для удобства пайки толстых “макарон” – шаг между контактами разъёма SD больше, чем у SD micro.

10. Источник питания и его зарядка.

В макете может использоваться один из трёх типов питания:

отладочное питание – с USB компа на отладочную плату STM32F4-Discovery
автономное питание – Li-Polymer аккумулятор 3.6V 930mAh
питание с подзарядки – с USB компа или зарядное устройство от розетки

В качестве контроллера зарядки выбрана микросхема EMC5754 от старого умершего аудио-плеера Ritmix. Микросхема работает по типовой схеме и прямо на плате от старого плеера (лень было делать новую, да и не нужно для макета). Для исключения влияния с платы были выпаяны все остальные активные элементы. Увеличен ток зарядки до 480 мА (это терпимо для зарядки от USB) и добавлен индикатор заряда в виде светодиода:

image

Возможна работа мультимедиа-плеера во время зарядки, хотя для микросхемы контроллера зарядки это будет больно, особенно когда аккумулятор близок к полной разрядке. Во время зарядки аккумулятора и во время работы устройства – нагрева аккумулятора и контроллера зарядки обнаружено не было.

Питание от аккумулятора/системы зарядки заведено на плату STM32F4-Discovery на пины +5V и GND. Следует исключить одновременное попадание напряжения питания с отладочного USB и аккумулятора/питания подзарядки! На макете добавлен выключатель (управляет подачей питания с аккумулятора и микросхемы контроллера зарядки).

Как уже было написано ранее, свежезаряженного аккумулятора на 930 mAh хватает на 170 минут непрерывного просмотра/прослушивания.

11. Работа программы.

На SD карту должны быть записаны пары файлов - *.avi и *.ima, нумерация с нуля. Например: 0.avi 0.ima, 1.avi 1.ima, 2.avi 2 ima, … О получении файлов данных нужного формата говорилось выше.

При включении, плеер начинает воспроизводить пару файлов, начинающихся с 0, с каждым нажатием кнопки сброса – переход к следующему видео (с 1). Если следующее видео не обнаружено – переходит к первому. По этой причине прерываний в нумерации пар файлов быть не должно!

На отладочной плате STM32F4-Discovery: вторая кнопка – пауза/снятие с паузы.

Небольшой хак, с помощью которого можно заставить при нажатии кнопки RESET играть новый медиа файл:

CODE
#define SC (*(volatile u32*)0x10004004)
#define SN (*(volatile u32*)0x10004008)

if(SC=='NEXT')SN++; //при последующих сбросах новые Video/Audio
else
{
 SC='NEXT';
 SN=0;
}


Тут всё понятно – за пределами регионов стека и кучи объявляются 2 переменные, первая из которых хранит признак первого запуска плеера (включение), вторая – номер видео. При первом включении, мала вероятность, что значение переменной будет ‘NEXT’, поэтому это считается первым включением и запускается первый ролик (0.avi 0.ima). При последующих нажатиях сброса, происходит увеличение второй переменной – будет играться следующий ролик.
Ну и конечно же, надо настроить компилятор так, чтобы функции очистки не касались регионов памяти 0x10004004..0x1000400B, иначе данный хак будет бесполезен.

В Приложении 6 – полный проект программы плеера (среда разработки: µVision 5.16a). Более предыдущая версия µVision 4.74 при уровне оптимизации –O3 (по скорости) – давала нерабочий код декодера JPEG. Готовая прошивка в папке obj, файл led.hex.

В Приложении 7 – тестовый ролик: 0.avi + 0.ima и convert.bat - для автоматического конвертирования (нужны fmmpeg и imacodec – первая качается из интернета, вторая вместе с сорцами в Приложении 1).

12. Перспективы.

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

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

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

Данный проект полностью открыт по части софта и харда. Надеюсь, было интересно и чем-нибудь поможет!

Приложения:

Приложение 1: Кодек IMA ADPCM с сорцами (обновлено 13.01.2018)

Приложение 2: Демонстрация работы плеера

Приложение 3: Сорцы для LCD 320x240 + FSMC + DMA

Приложение 4: макетная плата для OLED дисплея

Приложение 5: Макетная плата усилителя

Приложение 6: Сорцы плеера MJPEG+IMA ADPCM (проект Keil uVision) + прошивка (hex) (обновлено 13.01.2018)

Приложение 7: видео(MJPEG)- и аудио(IMA ADPCM)- дорожки для тестирования + батник для авто-конверсии роликов

Обсуждение на форуме, новые прошивки - здесь: http://vrtp.ru/index.php?act=ST&f=59&t=29688

UPDATE => 13.01.2018

1)
Добавил в плеер софтовый MP3-декодер.
Исходный код взят здесь: https://github.com/lieff/minimp3

Параметры звукового потока в плеере выбраны следующие: 24 kHz, 40 kbps, mono. При таком раскладе звучание удовлетворительное.
Пробовал понизить битрейт до 32 kbps, звучание было хуже - на высоких тонах появлялся металлический оттенок, поэтому оставил 40 kbps.

Процессор работает также на 168 МГц, имплементирование MP3-декодера прошло с некоторыми ухищрениями.
Основные проблемы - синхронизация вывода видео со звуком (длительность одного видео-фрейма НЕ КРАТНА длительности одного аудио-фрейма),
а также нахождение эффективного алгоритма программы.

Выигрыш в сжатии: ~2.4 раза (MP3 40kbps 24 kHz vs. IMA ADPCM 96 kbps 24kHz).

Исходный код проекта (µVision 5.16a) + прошивка (obj/led.hex) даны в Приложении 8.

Медиа-данные для теста и convert.bat (для автоматического конвертирования, нужна программа fmmpeg) - в Приложении 9.

2)
Поправил мелкие баги в предыдущем проекте программы плеера.
Обновлённый исходный код проекта (µVision 5.16a) + прошивка (obj/led.hex) в Приложении 6.

Приложение 8: Сорцы плеера MJPEG+MP3 (проект Keil uVision) + прошивка (hex)

Приложение 9: видео(MJPEG)- и аудио(MP3)- дорожки для тестирования + батник для авто-конверсии роликов


UPDATE => 25.03.2018

Принципиальная схема плеера: http://vrtp.ru/screenshots/3712_nanoP.gif

Внешний вид плеера:
image

Демонстрационные видео (на мерцание изображения -не обращать внимание: видеокамера!):

1) http://vrtp.ru/index.php?act=Attach&type=post&id=772222
2) http://vrtp.ru/index.php?act=Attach&type=post&id=772224

Отдельная статья про Lossless Bitexact Video-Codec (декодер поддерживается nanoPlayer): http://vrtp.ru/index.php?act=categories&CO...le&article=3713

Новые исходники и прошивки:

1)
Декодер видео PackMan rev.0 + FLAC-декодер аудио, оптимизированный на Ассемблере(порт с RockChip на STM32F4) + чтение с SD-карты через DMA. На карту файлы заливать парами: видео *.pak, аудио *.fla. Параметры FLAC аудио: 24 кГц, 1 канал, 16 бит знаковый. Диапазон амплитуд: -2048 ... +2047, тоесть 12 бит. Размер расжатого фрейма должен быть фиксированным: 2000 семплов.

http://vrtp.ru/index.php?act=Attach&type=post&id=772014

Кодер брать здесь: http://vrtp.ru/index.php?act=Attach&type=post&id=772011

2)
Обновлённые прошивки предыдущих декодеров: ADPCM, MP3, MJPEG, MP4(H264) - исправлены мелкие ошибки и улушен алгоритм синхронизации видео и звука:
http://vrtp.ru/screenshots/3712_nanoPlay_I..._MJPEG_H264.zip

Если используется STM32F4DISCOVERY, то в исходниках ничего менять не нужно!

Если nanoPlayer, то в main.c заменить макрос PAUSE на такой:

CODE
#define PAUSE (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)^1)


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


UPDATE => 29.03.2018

Усовершенствованный вариант Lossless видео-кодека "PackMan" - с мульти-стратегическим конвейером. Теперь жмёт ещё лучше! Не совместим с ранними версиями !
Исходники усовершенствованного кодера/декодера, там же и билды под Win32, DOS: http://vrtp.ru/index.php?act=Attach&type=post&id=772868

Исходники усовершенствованного декодера для nanoPlayer: http://vrtp.ru/index.php?act=Attach&type=post&id=772869

Вариант печатной платы (4-слойка) герберы: http://vrtp.ru/index.php?act=Attach&type=post&id=772870

Демонстрационное видео на ЮТУБ: https://www.youtube.com/watch?v=ZCZwsP3rf8Y

UPDATE => 06.08.2018

Декодеры: (MP4 + MP3), (Packman320 + FLAC) на STM32H743: http://vrtp.ru/index.php?showtopic=29688&st=150

Видео:

MP4+MP3:


<embed src="http://www.youtube.com/v/x3sADTqlfj8" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350" align="center"></embed>



PackMan320+FLAC:


<embed src="http://www.youtube.com/v/s2a_DqrIFaw" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350" align="center"></embed>



Исходники:

MP4+MP3: http://vrtp.ru/index.php?act=Attach&type=post&id=784681

PackMan320 + FLAC: http://vrtp.ru/index.php?act=Attach&type=post&id=784393

Остальное -в теме: http://vrtp.ru/index.php?showtopic=29688 и http://vrtp.ru/index.php?showtopic=30174

Mp4+Mp3 на плате EmuPocket:






© Riba 25.03.2018




  banner DIPTRACE - САМЫЙ ЛУЧШИЙ ТАКСИРОВЩИК ПЕЧАТНЫХ ПЛАТ
Portal-X