Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SAM7S и I2S кодек
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
HeOHuKC
Здравствуйте уважаемые форумчане!
Третий день бьюсь с подключением к SAM7S I2S кодека, все делаю по апноту от атмела, а он отказываеться петь. Сто раз проверял сигналы на SSC порту логическим анализатором, все данные идут, частоты совпадают. WAV файл читаеться с флешки, файл тоже подготовлен тот, что нужно. Может кто поделится примером, для кодеков с внешним тактированием. Ибо уже сил никаких нету, кодек у меня используется Wolfson WM8714ED.
aaarrr
Цитата(HeOHuKC @ May 31 2010, 01:42) *
Сто раз проверял сигналы на SSC порту логическим анализатором, все данные идут, частоты совпадают.

Ну если так, то, может, и не в SSC дело?

Цитата(HeOHuKC @ May 31 2010, 01:42) *
Может кто поделится примером, для кодеков с внешним тактированием.

Если под кодеком с внешним тактированием понимается кодек в режиме slave, то пожалуйста. Замечательно поет через CS4344:

CODE

void ssc_start_i2s(void)
{
audio_pll_sw(1); // Switch to I2S clock

AT91C_BASE_PMC->PMC_PCER = 1UL << AT91C_ID_SSC;

AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;

AT91C_BASE_SSC->SSC_CMR = 16; // MCK / 32

// PERIOD: 32, STTDLY: 1, START: falling edge on TF, CKO: continuous, CKS: TK
AT91C_BASE_SSC->SSC_TCMR = (15 << 24) | (1 << 16) | AT91C_SSC_START_FALL_RF | AT91C_SSC_CKO_CONTINOUS | AT91C_SSC_CKS_DIV;
// FSOS: negative pulse on TF, DATNB: 1, MSB first, 16 bits
AT91C_BASE_SSC->SSC_TFMR = AT91C_SSC_FSOS_NEGATIVE | (15 << 16) | (1 << 8) | AT91C_SSC_MSBF | 15;

AT91C_BASE_SSC->SSC_TPR = (u_int)&audio_tx_buffer[0][0];
AT91C_BASE_SSC->SSC_TCR = AUDIO_BUFFER_SAMPLES_PER_CH * 2;
AT91C_BASE_SSC->SSC_TNPR = (u_int)&audio_tx_buffer[1][0];
AT91C_BASE_SSC->SSC_TNCR = AUDIO_BUFFER_SAMPLES_PER_CH * 2;
AT91C_BASE_SSC->SSC_PTCR = AT91C_PDC_TXTEN;

AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SSC] = PRIOR_SSC;
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SSC] = (u_int)ssc_irq_handler;
AT91C_BASE_AIC->AIC_IECR = 1UL << AT91C_ID_SSC;

AT91C_BASE_SSC->SSC_IER = AT91C_SSC_ENDTX;

AT91C_BASE_SSC->SSC_CR = AT91C_SSC_TXEN;

*AT91C_PMC_SCER = AT91C_PMC_PCK1; // Enable MCLK
}
HeOHuKC
aaarrr Спасибо, завтра опробую ваш код в действии wink.gif , камень у вас работает от кварца 18.432 мГц ? Просто там точных частот с таким кварцем не получить, и воспроизведение будет бежать чуть быстрее чем надо. Меня еще смутила фраза в даташите на мой кодек WM8714, что при не совпадении частоты тактирования и частоты семплирования кодек отключает ЦАПы.
aaarrr
Цитата(HeOHuKC @ May 31 2010, 02:33) *
камень у вас работает от кварца 18.432 мГц ? Просто там точных частот с таким кварцем не получить, и воспроизведение будет бежать чуть быстрее чем надо

Никаких несовпадений: PLL настроена на 45.1584МГц, Fs = MCK/1024 = 44100Гц.
HeOHuKC
Понятно, попробую поиграться с частотами smile.gif Еще раз спасибо.
HeOHuKC
Что то никак не хочет петь мой кодек, вообщем решил я выбрать частоту дискретизации 48кГц. Кварц стоит на 18.432 мГц, через вывод PA31(PCK2) идет тактирование на кодек, при такой частоте кварца это 48 кГц (384fs). Я уже совсем ничего не пойму, анализатором всё проверил, данные идут, клок есть. Не понимаю что ему еще надо, может есть какие то нюансы которые я не учел ?
Код
Код
#define SLOT_BY_FRAME 2
#define BITS_BY_SLOT 16
#define FILE_SAMPLING_FREQ 48000

#define IRQ_LEVEL_I2S    5





void dac_init(void)
{    
///Clock 12 Mhz
    AT91PS_PMC pPMC = AT91C_BASE_PMC;

    pPMC->PMC_PCKR[2] = (AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_MAIN_CLK);
    *AT91C_PMC_SCER = AT91C_PMC_PCK2;
    while( !(*AT91C_PMC_SR & AT91C_PMC_PCK2RDY) );
    *AT91C_PIOA_BSR = AT91C_PA31_PCK2;
    *AT91C_PIOA_PDR = AT91C_PA31_PCK2;
///SSC init
*AT91C_PIOA_PDR = AT91C_PA16_TK | AT91C_PA15_TF | AT91C_PA17_TD;
AT91F_SSC_CfgPMC();
*AT91C_SSC_CR = AT91C_SSC_SWRST;

AT91F_PDC_Close((AT91PS_PDC) & (AT91C_BASE_SSC->SSC_RPR));

AT91F_SSC_SetBaudrate(AT91C_BASE_SSC,MCK,FILE_SAMPLING_FREQ*(BITS_BY_SLOT*SLOT_BY_FRAME));

*AT91C_SSC_TFMR = (AT91C_SSC_FSOS_NEGATIVE | (((BITS_BY_SLOT-1)<<16) & AT91C_SSC_FSLEN)
         | (((SLOT_BY_FRAME-1)<<8) & AT91C_SSC_DATNB) | AT91C_SSC_MSBF | (BITS_BY_SLOT-1) );

*AT91C_SSC_TCMR = (((((BITS_BY_SLOT*SLOT_BY_FRAME)/2) -1) <<24) | ((1<<16) & AT91C_SSC_STTDLY) |
            AT91C_SSC_START_FALL_RF | AT91C_SSC_CKO_CONTINOUS| AT91C_SSC_CKS_DIV);

AT91F_PDC_SetTx ((AT91PS_PDC) &(AT91C_BASE_SSC->SSC_RPR),        // PDC SSC base address
                     (char *)wav_file,    // pointer to data
                     wav_size/2);// Number of 16 bits words

AT91F_PDC_SetNextTx ((AT91PS_PDC) &(AT91C_BASE_SSC->SSC_RPR),    // PDC SSC base address
                         (char *)wav_file,     // pointer to next data
                         wav_size/2);

*AT91C_SSC_PTCR = AT91C_PDC_TXTEN;
*AT91C_SSC_PTSR == AT91C_PDC_TXTEN;

AT91F_SSC_EnableTx (AT91C_BASE_SSC);

}
aaarrr
Цитата(HeOHuKC @ Jun 3 2010, 23:57) *
Не понимаю что ему еще надо, может есть какие то нюансы которые я не учел ?

Если данные идут правильно, а кодек совсем молчит, то остается предположить какой-нибудь косяк в подключении. На MUTE, например, высокий уровень, или что-то столь же глобальное.
HeOHuKC
Mute точно правильно подключен и интерфейс на кодеке выбран I2S. Звуков никаких он не издает вообще sad.gif
В исходнике инициализация SSC правильно сделана ? И еще вопрос по поводу AT91C_PMC_CSS_MAIN_CLK, это же будет частота кварца ?
aaarrr
Цитата(HeOHuKC @ Jun 4 2010, 00:21) *
В исходнике инициализация SSC правильно сделана ?

При MCLK = 18.432MHz и MCK = 48MHz, тут и близко не будет требуемых кодеком +/-8 тактов MCLK:
Код
AT91F_SSC_SetBaudrate(AT91C_BASE_SSC,MCK,FILE_SAMPLING_FREQ*(BITS_BY_SLOT*SLOT_BY_FRAME));

Кстати, советую ознакомиться с исходником данной функции, чтобы в полной мере насладиться прелестями индусского кода.
Настоятельно рекомендую избегать использования убогой атмеловской "либы".

Цитата(HeOHuKC @ Jun 4 2010, 00:21) *
И еще вопрос по поводу AT91C_PMC_CSS_MAIN_CLK, это же будет частота кварца ?

Да, кварца.
HeOHuKC
Спасибо, за информацию smile.gif Исходник видел biggrin.gif , у меня до этого было сделано не так, это из атмеловского примера взял. Я нашел кодек от Cirrus Logic, там есть автоматическая генерация SCLK пока мучаю его. Пока не могу придумать какой кварц применить, чтоб и ядро работало на нормальной частоте и кодек не возмущался. До этого просто дела с I2S вообще не имел, первый опыт и пока не очень удачный sad.gif
aaarrr
Цитата(HeOHuKC @ Jun 4 2010, 02:16) *
Пока не могу придумать какой кварц применить, чтоб и ядро работало на нормальной частоте и кодек не возмущался.

Нормальная частота для ядра - это 48.0MHz? Я имею в виду, ограничения на тактовую (USB и т.п.) в системе есть?

А то для первого кодека вполне можно было бы выбрать MCK=49.152MHz при кварце 18.432MHz.
HeOHuKC
На USB уже плюнул, теперь выставил PLL на такую же частоту как в вашем проекте, кодек стал шуметь smile.gif буду разбираться дальше. Спасибо Вам smile.gif
HeOHuKC
Всё запустил играет smile.gif но есть огромнейшая проблема. Шум, очень громкий, а сам сигнал на его фоне тихий. Похоже на проблемы с частотой дискретизации.
HeOHuKC
Уже мозг сломал, выставляю FSLEN равный 16, играет один канал без шума и чисто, ставлю FSLEN 15 (как во всех примерах) кодек начинает ужасно шипеть но играют два канала. Что это может быть, частота дискретизации точно совпадает с нужной кодеку.
aaarrr
Цитата(HeOHuKC @ Jun 5 2010, 23:51) *
Что это может быть, частота дискретизации точно совпадает с нужной кодеку.

Данные смещены на один бит, судя по всему. Возьмите настройки из моего примера - там точно играют два канала.
HeOHuKC
С вашим примером то же самое sad.gif пока не могу найти причину, пока FSLEN равен 15 на выходе шум, зато играют два канала.
aaarrr
Цитата(HeOHuKC @ Jun 7 2010, 19:37) *
С вашим примером то же самое

Он был вырван из рабочего проекта, поэтому сомневаться в правильности не приходится. А какой сейчас кодек мучаете?
HeOHuKC
Текущий кодек Wolfson WM8714, пробовал ставить Cirrus Logic CS4338, на обоих кодеках такая проблема. Идей пока нету.
aaarrr
А что с тактированием (MCLK, SCLK)? Выложите свои настройки.
HeOHuKC
Вот
Код
#define EXT_OC          18432000   // Exetrnal ocilator MAINCK
#define MCK             45158400   // MCK (PLLRC )

//cs_startup.c
pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x14) |
                      (AT91C_CKGR_PLLCOUNT & (28<<8)) |
                      (AT91C_CKGR_MUL & (48<<16)));

//dac.c

//Clock 11.2896 Mhz
AT91PS_PMC pPMC = AT91C_BASE_PMC;
pPMC->PMC_PCKR[2] = (AT91C_PMC_PRES_CLK_4 | AT91C_PMC_CSS_PLL_CLK);
*AT91C_PMC_SCER = AT91C_PMC_PCK2;
while( !(*AT91C_PMC_SR & AT91C_PMC_PCK2RDY) );
*AT91C_PIOA_BSR = AT91C_PA18_PCK2;
*AT91C_PIOA_PDR = AT91C_PA18_PCK2;
    ///SSC init
*AT91C_PMC_PCER = (1 << AT91C_ID_SSC); // Enable Clock for SSC controller
*AT91C_SSC_CR = AT91C_SSC_SWRST; // reset
*AT91C_SSC_CMR = 16;
*AT91C_PIOA_PDR = AT91C_PA16_TK | AT91C_PA15_TF | AT91C_PA17_TD;

*AT91C_SSC_TCMR = (15 << 24) | (1 << 16) | AT91C_SSC_START_FALL_RF | AT91C_SSC_CKO_CONTINOUS | AT91C_SSC_CKS_DIV;
// FSOS: negative pulse on TF, DATNB: 1, MSB first, 16 bits
*AT91C_SSC_TFMR = AT91C_SSC_FSOS_NEGATIVE | (16 << 16) | (1 << 8) | AT91C_SSC_MSBF | 15;
aaarrr
Выходная частота PLL не укладывается в паспортный минимум (80MHz), надо установить вдвое большую и выставить делитель 2 для MCK. Больше криминала не вижу sad.gif
С данными точно все в порядке? Попробуйте синус/пилу подать - по осциллограмме можно будет сориентироваться, что и куда заползает.

Цитата(HeOHuKC @ Jun 7 2010, 20:42) *
Текущий кодек Wolfson WM8714, пробовал ставить Cirrus Logic CS4338, на обоих кодеках такая проблема. Идей пока нету.

Стоп. CS4338 - это же Right Justified, уж не установлен ли и на WM8714 такой же режим? Тогда данные как раз сползут на бит, если подавать честный I2S.
HeOHuKC
У WM8714 стоит I2S режим, это высокий уровень на выводе FORMAT. Если на этом выводе ноль то он разумеется не играет, а просто шипит даже если FSLEN равен 16. Данные гружу с флешки, сначала грузил вместе с заголовком файла, просто в начале был щелчок, сейчас переделал чтоб грузить с заголовка data, но всё также.. Смотрел данные логическим анализатором, при FSLEN 15 переключение фреймов происходит без паузы, если FSLEN 16 то появляется пауза.
HeOHuKC
Победил эту фигню, теперь играют два канала smile.gif проблема оказалась в регистре SSC_TCMR, если параметр STTDLY не равен нулю вставляется задержка перед передачей данных. Убрал задержку запел и второй канал, на анализаторе не было заметно никаких пауз.
Выглядит теперь это так
Код
*AT91C_SSC_TCMR = (15 << 24) | (0 << 16) | AT91C_SSC_START_FALL_RF | AT91C_SSC_CKO_CONTINOUS | AT91C_SSC_CKS_DIV;
*AT91C_SSC_TFMR = AT91C_SSC_FSOS_NEGATIVE | (15 << 16) | (1 << 8) | AT91C_SSC_MSBF | 15;
aaarrr
Цитата(HeOHuKC @ Jun 10 2010, 17:30) *
...если параметр STTDLY не равен нулю вставляется задержка перед передачей данных.

У I2S данные относительно LRC задержаны на один такт. То что у вас есть сейчас - это не I2S.
HeOHuKC
Я проблем больше никаких не вижу, возможно это особенность кодека. Т.к всё остальное я перепроверил десяток раз smile.gif у меня еще где то лежит кодек от BurnBrown PCM1742E, спаяю платку и проверю с ним smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.