Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F407 и I2S, DMA
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
rx9cim
Здравствуйте!
1) написал инициализацию I2S для STM32F407 и получил странный результат - мне нужно, чтобы процессор генерил сигнал тактирования (MCK - мастер клок) для аудиокодека. Генерация идет (на выходе МСК, 63 нога есть сигнал с частотой 5644800 Гц ) только в режиме, когда контроллер мастер-приемник. А вот когда он мастер-передатчик генерации нет. В даташите ничего про это не нашел, почему так? И еще - не совсем понял про режим полного дуплекса для I2S - можно ли (а может и нужно!?) считывать данные с соответствующего регистра данных SPI?
2) Настраиваю ДМА контроллер и непонятно что такое за параметры MBURST и PBURST. Из описания смутно понял, что они используются когда пишешь из периферии в память не постоянно (например по одному байту из SPI), а пачками -по 4, 8, 16 и т.д. байт. Прав ли я? При работе ДМА ставится ли ядро процессора под ХОЛД или нет?
Привожу код инициализации I2S:
CODE
void I2S_init (void)
{
/*Настройка I2S
частота дискретизации 22050Гц
f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN / PLLM)
f(PLL I2S clock output) = f(VCO clock) / PLLI2SR
*/
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;//включил GPIOC
GPIOC->MODER|=GPIO_MODER_MODER6_1;//выход AF
GPIOC->AFR[0]|=0x05000000;//AF5-MCKI2S

RCC->AHB1ENR|=RCC_AHB1ENR_GPIOBEN;//включил GPIOB
GPIOB->MODER|=GPIO_MODER_MODER12_1;//выход AF
GPIOB->MODER|=GPIO_MODER_MODER13_1;//выход AF
GPIOB->MODER|=GPIO_MODER_MODER14_1;//выход AF
GPIOB->MODER|=GPIO_MODER_MODER15_1;//выход AF
GPIOB->AFR[1]|=0x55550000;//AF5-I2S/SPI

RCC->PLLI2SCFGR=0;//обнуляю
RCC->PLLI2SCFGR|=PLLI2SN(429);//
RCC->PLLI2SCFGR|=PLLI2SR(4);//
RCC->CR|=RCC_CR_PLLI2SON;//Включил PLL I2S
#ifndef SIMULATOR
while ((RCC->CR&RCC_CR_PLLI2SRDY)!=RCC_CR_PLLI2SRDY);//пока заработает PLL
#endif
RCC->APB1ENR|=RCC_APB1ENR_SPI2EN;//включил Spi2
SPI2->I2SCFGR|=SPI_I2SCFGR_I2SMOD;//включил I2S
SPI2->I2SCFGR|=SPI_I2SCFGR_DATLEN_0;//24бит данные
SPI2->I2SCFGR|=SPI_I2SCFGR_CHLEN;//32бит длина данных
SPI2->I2SPR=I2SDIV(9);//
SPI2->I2SPR|=I2SODD(1);//
SPI2->I2SCFGR|=I2SCFG(3);//Режим Мастер - применик
SPI2->I2SPR|=I2SMCKOE(1);//выход Мастер клока
SPI2->I2SCFGR|=SPI_I2SCFGR_I2SE;//включил SPI
}


Прошу ответить на мои вопросы.
aaarrr
Цитата(rx9cim @ Jul 2 2012, 19:27) *
А вот когда он мастер-передатчик генерации нет. В даташите ничего про это не нашел, почему так?

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

Цитата(rx9cim @ Jul 2 2012, 19:27) *
И еще - не совсем понял про режим полного дуплекса для I2S - можно ли (а может и нужно!?) считывать данные с соответствующего регистра данных SPI?

Не совсем понятен вопрос. Можно и не считывать, а смысл?

Цитата(rx9cim @ Jul 2 2012, 19:27) *
2) Настраиваю ДМА контроллер и непонятно что такое за параметры MBURST и PBURST. Из описания смутно понял, что они используются когда пишешь из периферии в память не постоянно (например по одному байту из SPI), а пачками -по 4, 8, 16 и т.д. байт. Прав ли я? При работе ДМА ставится ли ядро процессора под ХОЛД или нет?

MBURST можно выставить, PBURST - нет, так как у SPI/I2S регистр данных один, соответственно, INCRx работать не будет.
rx9cim
Грузить постоянно данные в передатчик пробовал - эффекта ноль. Да и не должно быть так для I2S - сигнал тактирования кодека должен всегда передаваться.
BURST - все-таки длина пачки?
aaarrr
Цитата(rx9cim @ Jul 2 2012, 20:24) *
Да и не должно быть так для I2S - сигнал тактирования кодека должен всегда передаваться.

Тем не менее так есть. Сам был удивлен.

Цитата(rx9cim @ Jul 2 2012, 20:24) *
BURST - все-таки длина пачки?

Да, разумеется.
rx9cim
Еще подскажите пожалкйста. Совсем запутался. Настроил дма для работы с памятью 32 бита (слово). Регистр данных настроен как 8бит (такой обмен). Включил инкремент памяти в соответствии с длиной памяти 32 бита. Настроил количество транзакций из спиай в память - 44 (необходимо передать 11 32 битных слов). Нужно ли трогать мберст или нет? Если мберст поставить 4, то в память можно будет писать 11 раз, а не 44?

aaarrr
MBURST можно поставить. Работать будет в любом случае, но с burst полоса расходуется эффективнее. Количество транзакций в регистре менять при этом не нужно.

Только I2S ведь не поддерживает 8 бит.
Allregia
Цитата(rx9cim @ Jul 2 2012, 18:24) *
Грузить постоянно данные в передатчик пробовал - эффекта ноль. Да и не должно быть так для I2S - сигнал тактирования кодека должен всегда передаваться.


Вот такой у ST этот I2S, сам на эти грабли наступил. Там еще есть большая каверза с непереносимым сигналом внешнего клока sad.gif
Зато фулдуплекс порадовал.

P.S. А как народ определяет при 32-х (24) битной работе, какой канал и какой 16-битное слово из 32 надо грузить?
По прерываниям понятно, а вот с ДМА не очень понятно.
rx9cim
Вопрос по I2S - посмотрел примеры инициализации от ST и понял, что в фулл дуплекс I2S работает только слэйвом? т.е. не может выдавать сигнал тактирования? Рытаюсь настроить работу с аужио кодеком и считываю постоянно нули из SPI DR.
rx9cim
Точнее может ли I2S в режиме Master-recieve работать в полном дуплексе?
rx9cim
Есть ли разница в каком режиме настраивать Alternate function для GPIO (для I2S_SDext) - в опен драйн или пуш-пуш. Вроде без разницы, это влияет только на входное сопротивление. На данный момент работает в режиме пуш-пул.Это правильно?
И еще заметил следующее - при приеме данных с АЦП на пин I2S_SDext я принимаю в SPI->DR какой-то мусор - постоянно меняющиеся произвольные значения. Формат длины - 32 бита, формат передачи - 24 бит. Считываю два раза. Оба раза мусор. С чем это может быть связано?
Прошу помочь ответами на мои вопросы. Дальше не знаю куда двигаться...


P.S. как редактировать свои же сообщения?
aaarrr
Цитата(rx9cim @ Jul 4 2012, 21:26) *
И еще заметил следующее - при приеме данных с АЦП на пин I2S_SDext я принимаю в SPI->DR какой-то мусор - постоянно меняющиеся произвольные значения. Формат длины - 32 бита, формат передачи - 24 бит. Считываю два раза. Оба раза мусор. С чем это может быть связано?
Прошу помочь ответами на мои вопросы. Дальше не знаю куда двигаться...

А зачем считывать SPI->DR, если данные принимаются I2Sext?

Цитата(Allregia @ Jul 3 2012, 12:23) *
P.S. А как народ определяет при 32-х (24) битной работе, какой канал и какой 16-битное слово из 32 надо грузить?
По прерываниям понятно, а вот с ДМА не очень понятно.

Инициализируете канал DMA, потом запускаете I2S. Все получается вполне предсказуемо.

Цитата(rx9cim @ Jul 3 2012, 19:33) *
Вопрос по I2S - посмотрел примеры инициализации от ST и понял, что в фулл дуплекс I2S работает только слэйвом? т.е. не может выдавать сигнал тактирования? Рытаюсь настроить работу с аужио кодеком и считываю постоянно нули из SPI DR.

Просто в full duplex используется дополнительный блок I2Sext, который действительно всегда слейв (или по отношению к ведущему SPI, или же к внешнему источнику).

Цитата(rx9cim @ Jul 3 2012, 21:04) *
Точнее может ли I2S в режиме Master-recieve работать в полном дуплексе?

Может.
rx9cim
Спасибо Большое за ответы.
Наконец-то получилось передавать звук - пока то что на входе кодека передаю на выход.

Еще возникли вопросы:
1) Почему-то принимаю иногда с кодека значения 0xFFFF или около того. Использую стандарт I2S Philips, 32 бита, 24 - длина кадра. С чем это может быть связано?
2) Как правильно настроить ДМА?
Режим работы I2S2 -Master-recieve, I2S2ext-Slave TX.
Я принимаю 24 бита с одного канала за 2 подхода - сначала старшие 16 бит, затем еще 8 бит остальные. С двух каналов (правый и левый ) - в 4 захода
Необходимо писать данные в две 32-х разрядных переменных, т.е. пишу в регистр NDTR значение 4. Как нужно настроить инкремент и размерность памяти (наверное для памяти удобнее 16бит?)? надо в каждую 32-х разрядную переменную записать дважды значение из приемного регистра. Как хранятся переменные в паяти - старшей или младшей частью вперед? Ведь если делаю инкремент и младшая часть переменной лежит по младшему адресу надо будет переменную затем "переклеивать"?
rx9cim
Не могу еще ни как понять, почему с кодека периодически читаю 0xFFFF
rx9cim
Видимо Мастер приемник несинхронно принимает биты. Кодек cs4221. К сожалению нет осциллографа, чтобы посмотреть обмен. Периферия настроена правильно - много раз перепроверял. Неужели ни у кого не было такой проблемы?
rx9cim
Все-таки решил описать то, что проделал. Может кому-то будет полезным.
Как написано в Еррата, при применении полнодуплексного I2S, слайв нужно включать после мастера, причем так, чтобы включение совпало с сигналом WS I2S, иначе будет рассинхронизация, информация будет со сдвигом приниматься.
Второе, информацию, принимаемую в виде близком к 0xFFFFFF я поначалу считал за неверную. Однако вчитавшись в даташит на кодек и описание I2S, понял, что это значения АЦП, в комплиментарном виде.
Возникает дополнительная масса вопросов по обработке этой информации и собственно кодеку (cs4221):
1) Нужно ли эти данные переводить в нормальный вид (из инт в ансигнед инт) или при цифровой фильтрации этого делать не нужно?
2) у кодека есть ряд параметров, суть которых мне не понятна, объясните пожалуйста:
- soft ramp step rate, измеряется в количестве шагов на такт - это по сути скорость АЦП или ЦАП?
- zero cross level - это что? как указано в даташите это имееет отношение к Soft ramp control.
Пока не могу разобраться, почему частота дискретизации реальная не соответствует теоритической. при этом частоты всех сигналов в норме.
aaarrr
1. Можно переводить, можно не переводить - дело вкуса
2. Оба помянутых термина касаются регулировки громкости:
soft ramp - плавное изменение усиления
zero cross - изменение усиления в момент перехода сигнала через "0"
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.