Jump to content

    
Sign in to follow this  
dj_miles

Нужна помощь с кодеком TLV320AIC12K

Recommended Posts

Здравствуйте! Помогите разобраться с данным кодеком!!! В частности не получается конфигурировать его. Кодеком управляет PIC-контроллер по I2C интерфейсу, а тактируется от внутреннего генератора PIC'а 16 мГц. Сам же кодек юзаю в slave - режиме. Проблема заключается в записи регистров. Чтение проходит на ура, если читать по одному регистру. Прочитать все регистры разом не получается. Алгоритм чтения и записи выполняю точно так как описано в даташите. Что не так? Может кто то имел дело с данным чудом!!!!

Share this post


Link to post
Share on other sites
Что не так? Может кто то имел дело с данным чудом!!!!

всегда удивлялся таким вопросам - исходной информации ноль, кроме "не работает"..

где схема включения, где линк на даташит, где куски исходного кода, где лог с точкой неисправности?

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

 

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

Share this post


Link to post
Share on other sites

Спасибо за поправки!!!

 

Даташит на TLV320AIC12K TLV320AIK12, схема в файле.

 

Коды функций работы с I2C:

 

void IIC_STR() { I2C2CONbits.SEN = 1; while (I2C2CONbits.SEN); }

void IIC_RST() { I2C2CONbits.RSEN = 1; while (I2C2CONbits.RSEN); }

void IIC_STP() { I2C2CONbits.PEN = 1; while (I2C2CONbits.PEN);}

void IIC_WTX(unsigned char data){I2C2TRN = data; while (I2C2STATbits.TRSTAT == 1); while (I2C2STATbits.TBF == 1);}

unsigned char IIC_WRX() { I2C2CONbits.RCEN = 1; while (I2C2CONbits.RCEN);I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN); I2C2STATbits.I2COV = 0; return I2C2RCV;}

void IIC_IDL(){ while(I2C2CONbits.SEN || I2C2CONbits.RSEN || I2C2CONbits.PEN || I2C2CONbits.RCEN || I2C2CONbits.ACKEN || I2C2STATbits.TRSTAT);}

void IIC_ACK() { I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN);}

 

void I2C_Write(unsigned char add, unsigned char byte)

{

IIC_IDL();

IIC_STR();

IIC_WTX(0x80);

IIC_WTX(add);

IIC_STP();

IIC_IDL();

IIC_STR();

IIC_WTX(0x80);

if (I2C2STATbits.ACKSTAT);

IIC_WTX(add);

if (I2C2STATbits.ACKSTAT);

IIC_WTX(byte);

if (I2C2STATbits.ACKSTAT);

IIC_STP();

}

 

unsigned char I2C_Read(unsigned char add)

{

unsigned char r = 0;

IIC_IDL();

IIC_STR();

IIC_WTX(0x80);

IIC_WTX(add);

IIC_STP();

IIC_STR();

IIC_WTX(0x81);

r = IIC_WRX();

IIC_STP();

return r;

}

 

Забыл коменты написать!

 

Коды функций работы с I2C:

 

void IIC_STR() { I2C2CONbits.SEN = 1; while (I2C2CONbits.SEN); }

void IIC_RST() { I2C2CONbits.RSEN = 1; while (I2C2CONbits.RSEN); }

void IIC_STP() { I2C2CONbits.PEN = 1; while (I2C2CONbits.PEN);}

void IIC_WTX(unsigned char data){I2C2TRN = data; while (I2C2STATbits.TRSTAT == 1); while (I2C2STATbits.TBF == 1);}

unsigned char IIC_WRX() { I2C2CONbits.RCEN = 1; while (I2C2CONbits.RCEN);I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN); I2C2STATbits.I2COV = 0; return I2C2RCV;}

void IIC_IDL(){ while(I2C2CONbits.SEN || I2C2CONbits.RSEN || I2C2CONbits.PEN || I2C2CONbits.RCEN || I2C2CONbits.ACKEN || I2C2STATbits.TRSTAT);}

void IIC_ACK() { I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN);}

 

void I2C_Write(unsigned char add, unsigned char byte)

{

IIC_IDL(); //Ожидаем освобождения модуля I2C

IIC_STR(); // Последовательность старт-бита

IIC_WTX(0x80);//Адрес слейва с признаком записи

if (I2C2STATbits.ACKSTAT); //Проверка подтверждения

IIC_WTX(add); //Адрес регистра

if (I2C2STATbits.ACKSTAT);

IIC_WTX(byte); //Значение регистра

if (I2C2STATbits.ACKSTAT);

IIC_STP();//Стоп-бит

}

 

unsigned char I2C_Read(unsigned char add)

{

unsigned char r = 0;

//Запись индекса регистра

IIC_IDL(); //Ожидаем освобождения модуля I2C

IIC_STR();// Последовательность старт-бита

IIC_WTX(0x80);//Адрес слейва с признаком записи

IIC_WTX(add); //Адрес регистра

IIC_STP(); //Стоп-бит

 

IIC_STR(); //Старт-бит

IIC_WTX(0x81); //Адрес слейва с признаком чтения

r = IIC_WRX(); //Чтение

IIC_STP(); //Стоп-бит

return r;

}

post-80386-1393322236_thumb.png

Share this post


Link to post
Share on other sites
Спасибо за поправки!!!

ну вот так заметно лучше..

по электросхеме - использована шина i2c, а где подтяжки (pullup)? шина с ОК и должны стоять резисторы от контактов scl и sda на +3в3 (в диапазоне 4к7..10к)

Share this post


Link to post
Share on other sites
ну вот так заметно лучше..

по электросхеме - использована шина i2c, а где подтяжки (pullup)? шина с ОК и должны стоять резисторы от контактов scl и sda на +3в3 (в диапазоне 4к7..10к)

 

 

На схеме не указаны, но на самом деле стоят. По поводу номиналов: я так понимаю, что он выбирается в зависимости огт скорости? У меня сейчас стоят 1к.

Share this post


Link to post
Share on other sites
На схеме не указаны, но на самом деле стоят. По поводу номиналов: я так понимаю, что он выбирается в зависимости огт скорости? У меня сейчас стоят 1к.

понятно, 1к в принципе не криминал, раз чтение работает, то сгодится..

 

по исходникам (по счастью я Пиками не работал) - визуально не хватает в п/п чтения таких строчек (это из п/п записи)

if (I2C2STATbits.ACKSTAT); //Проверка подтверждения

 

я очень давно не возился с отладкой i2c, но по протоколу на каждое обращение к чипу должен прийти Ask (который может отсутствовать при передачи нескольких байт в блоке)..

 

на всякий случай - по вышеприведенной ссылке не даташит, а "TLV320AIC12/13/14/15 Codec Operating In Stand-Alone Slave Mode"

даташит лежит рядом - www.ti.com/cn/lit/gpn/tlv320aic12k

Share this post


Link to post
Share on other sites

Короче сделал щас так: перевел его в режим мастера и все как по маслу работает. Вот теперь вопрос: почему он в слейв режиме не хотел записывать значения регистров?!!! Остается загадкой! Так ведь судя по всему касаясь шины I2C, он ведь так и остался в слейв режиме!

 

По поводу подтверждения: согласен! Указанный флаг просто не учитывается у меня, но по факту читается бы ло ли подтверждение от слейва.

Share this post


Link to post
Share on other sites

Выкладываю свой тестовый проект, может кому понадобиться. Камень PIC24FJ64GA004. Среда MPLAB IDE. Компилятор XC16.

 

В кратце опишу: TLV320 работает в Master-режиме, так как в slave добиться нормальной и стабильной работы так и не удалось, да и работать как оказалось в этом режиме очень удобно. Возможно это связано с процедурой сброса. Частота тактирования кодека взята с PIC, с выхода частоты переферии( у меня внутренний генератор с PLL 32 мГц, выход на лапе 16 мГц). В проекте есть файл ded.h - это тестовый кусочек для воспроизведения. Для теста микрофонного входа можно соеденить сигнал SPI_DIN_1 и SPI_DOUT_1, тогда все , что вы говорите в микрофон можно сразу услышать в динамике.

 

В целом кодек не плохой. Мощности для динамика маловато или может, что то с конфигурацией намудрил. А так качество вполне неплохое.

 

Будут вопросы, с удовольствием отвечу!

TLV320AIC12k_Test.zip

Share this post


Link to post
Share on other sites
Спасибо за поправки!!!

 

Даташит на TLV320AIC12K TLV320AIK12, схема в файле.

 

Коды функций работы с I2C:

 

void IIC_STR() { I2C2CONbits.SEN = 1; while (I2C2CONbits.SEN); }

void IIC_RST() { I2C2CONbits.RSEN = 1; while (I2C2CONbits.RSEN); }

void IIC_STP() { I2C2CONbits.PEN = 1; while (I2C2CONbits.PEN);}

void IIC_WTX(unsigned char data){I2C2TRN = data; while (I2C2STATbits.TRSTAT == 1); while (I2C2STATbits.TBF == 1);}

unsigned char IIC_WRX() { I2C2CONbits.RCEN = 1; while (I2C2CONbits.RCEN);I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN); I2C2STATbits.I2COV = 0; return I2C2RCV;}

void IIC_IDL(){ while(I2C2CONbits.SEN || I2C2CONbits.RSEN || I2C2CONbits.PEN || I2C2CONbits.RCEN || I2C2CONbits.ACKEN || I2C2STATbits.TRSTAT);}

void IIC_ACK() { I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN);}

 

void I2C_Write(unsigned char add, unsigned char byte)

{

IIC_IDL();

IIC_STR();

IIC_WTX(0x80);

IIC_WTX(add);

IIC_STP();

IIC_IDL();

IIC_STR();

IIC_WTX(0x80);

if (I2C2STATbits.ACKSTAT);

IIC_WTX(add);

if (I2C2STATbits.ACKSTAT);

IIC_WTX(byte);

if (I2C2STATbits.ACKSTAT);

IIC_STP();

}

 

unsigned char I2C_Read(unsigned char add)

{

unsigned char r = 0;

IIC_IDL();

IIC_STR();

IIC_WTX(0x80);

IIC_WTX(add);

IIC_STP();

IIC_STR();

IIC_WTX(0x81);

r = IIC_WRX();

IIC_STP();

return r;

}

 

Забыл коменты написать!

 

Коды функций работы с I2C:

 

void IIC_STR() { I2C2CONbits.SEN = 1; while (I2C2CONbits.SEN); }

void IIC_RST() { I2C2CONbits.RSEN = 1; while (I2C2CONbits.RSEN); }

void IIC_STP() { I2C2CONbits.PEN = 1; while (I2C2CONbits.PEN);}

void IIC_WTX(unsigned char data){I2C2TRN = data; while (I2C2STATbits.TRSTAT == 1); while (I2C2STATbits.TBF == 1);}

unsigned char IIC_WRX() { I2C2CONbits.RCEN = 1; while (I2C2CONbits.RCEN);I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN); I2C2STATbits.I2COV = 0; return I2C2RCV;}

void IIC_IDL(){ while(I2C2CONbits.SEN || I2C2CONbits.RSEN || I2C2CONbits.PEN || I2C2CONbits.RCEN || I2C2CONbits.ACKEN || I2C2STATbits.TRSTAT);}

void IIC_ACK() { I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN);}

 

void I2C_Write(unsigned char add, unsigned char byte)

{

IIC_IDL(); //Ожидаем освобождения модуля I2C

IIC_STR(); // Последовательность старт-бита

IIC_WTX(0x80);//Адрес слейва с признаком записи

if (I2C2STATbits.ACKSTAT); //Проверка подтверждения

IIC_WTX(add); //Адрес регистра

if (I2C2STATbits.ACKSTAT);

IIC_WTX(byte); //Значение регистра

if (I2C2STATbits.ACKSTAT);

IIC_STP();//Стоп-бит

}

 

unsigned char I2C_Read(unsigned char add)

{

unsigned char r = 0;

//Запись индекса регистра

IIC_IDL(); //Ожидаем освобождения модуля I2C

IIC_STR();// Последовательность старт-бита

IIC_WTX(0x80);//Адрес слейва с признаком записи

IIC_WTX(add); //Адрес регистра

IIC_STP(); //Стоп-бит

 

IIC_STR(); //Старт-бит

IIC_WTX(0x81); //Адрес слейва с признаком чтения

r = IIC_WRX(); //Чтение

IIC_STP(); //Стоп-бит

return r;

}

В Протеусе нарисована схма? В в версии 8.0 TLV320 не нашёл.

Share this post


Link to post
Share on other sites

Здравствуйте, уважаеые коллеги, подскажите, пожалуйста по кодеку TLV320AIC3254.
Питание внешнее 3.3В. Схема включения - обычная, внешний генератор на MCLK = 25 МГц.
После инициализации АЦП не стартует, в регистре состояния нет готовности даееых (Sticky Flag Register 3 - 0x00 / 0x2D (P0_R45)).
Вывод  MFP5 подключен на INT1 (сигнал должен формироваться по готовности данных) его также нет.
Все регистры программируюся корректно, проверяю их чтением.
Аналоговый модуль запускается и внутренние стабилизаторы включены, на выводах AVDD, DVDD, REF корректные напряжения.
Что может быть и почему не стартует АЦП?
Буду очень признателен за любой совет. 


 Write_ADC_TLV320 (0x00, 0x00);  /* Initialize to Page 0 */
 Write_ADC_TLV320 (0x01, 0x01);  /* Initialize the device through software reset */
	  Delay (25);
	
 Write_ADC_TLV320 (0x04, 0x00); /* MCLK pin is CODEC_CLKIN. MCLK = 25MHz */
 Write_ADC_TLV320 (0x12, 0x84); /* NADC = 4 */
 Write_ADC_TLV320 (0x13, 0x84); /* MADC = 4 */
 Write_ADC_TLV320 (0x14, 0x20); /* AOSR = 32 */
 Write_ADC_TLV320 (0x3d, 0x0D); /* ADC PRB_R13 = 13 */
	
 Write_ADC_TLV320 (0x00, 0x01); /* Select Page 1 */
 Write_ADC_TLV320 (0x01, 0x08); /* Disable Internal Crude AVdd in presence of external */ 	
 Write_ADC_TLV320 (0x02, 0x01); /* Power up AVDD LDO */
 Write_ADC_TLV320 (0x7b, 0x01); /* REF Power-Up */
 Write_ADC_TLV320 (0x14, 0x25); /* HP soft stepping settings for optimal pop performance at power up Rpop used is 6k with N = 6 and soft step = 20usec.
																		This should work with 47uF coupling capacitor. Can try N=5,6 or 7 time constants as well. 
																		Trade-off delay vs ???pop??? sound. */
 Write_ADC_TLV320 (0x0A, 0x33); // Set full chip common mode to 0.9V
 Write_ADC_TLV320 (0x3d, 0x00); /* Select ADC PTM_R4 */
 Write_ADC_TLV320 (0x47, 0x32); /* Set MicPGA startup delay to 3.1ms */
 Write_ADC_TLV320 (0x34, 0x10); /* Route IN2L to LEFT_P with 10K */
 Write_ADC_TLV320 (0x36, 0x10); /* Route IN2R to LEFT_N with 10K */
 Write_ADC_TLV320 (0x37, 0x04); /* Route IN3R to RIGHT_P with 10K */
 Write_ADC_TLV320 (0x39, 0x04); /* Route IN3L to RIGHT_N with 10K */
 Write_ADC_TLV320 (0x3c, 0x00); /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */
 Write_ADC_TLV320 (0x3d, 0x00); /* Select ADC PRB_R1 */
 Write_ADC_TLV320 (0x3b, 0);    /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */
 
 Write_ADC_TLV320 (0x00, 0x00);  /* Initialize to Page 0 */
 Write_ADC_TLV320 (0x51, 0xc0);  /* Power up Left and Right ADC Channels */
 Write_ADC_TLV320 (0x52, 0x00);  /* Unmute Left and Right ADC Digital Volume Control */    

 Write_ADC_TLV320 (0x66, 0xc1);  /* DC Measurement Mode enabled for Left and Right ADC Channels
																		0 0001: DC Measurement D parameter = 1*/    
 Write_ADC_TLV320 (0x67, 0x00);  /* Left and Right Channel DC measurement result update enabled
																	  For IIR based DC measurement, the measurement value is 
																	  updated before periodic clearing of IIR filter*/    

 Write_ADC_TLV320 (0x30, 0x01);  /* INT1 Interrupt for DC Measurement
																  	 DC Measurement data available will generate INT1 interrupt 
																		 INT1 is active high interrupt of multiple pulses, each of duration 2ms. */
 Write_ADC_TLV320 (0x34, 0x14);  /* INT1 output from MFP5 (32pin)*/ 

 

Схема подключения.png

Share this post


Link to post
Share on other sites

А что ж вы I2S-шину не задействовали? Шрифт гостовский - красота ;-)
По SPI только управлене осуществляется; данные в\из ЦАП\АЦП по I2S бегают (BCLK, WCLK, DIN, DOUT они для кого?). Стр 44 в slas549d "ковбои" старались рисовали-рисовали ;-)

Share this post


Link to post
Share on other sites
On 8/8/2020 at 12:35 AM, Obam said:

А что ж вы I2S-шину не задействовали? Шрифт гостовский - красота

 

Благодарю за разъяснения. Шибко много времени потерял по этой причине. Беспечность в очередной раз подвела. 

Но, конечно, это время ушло еще и на изучение работы и параметров кодека. Я его использую в биометрической системе и потому грех не воспользоваться встроенным ЦОС -процессором для обработки зашумленных сигналов. Но без PurePath Studio не обойтись и TI не раздает софт, а я спрашивал, но, видать, ужесточения у них.  Планировал делать перестраиваемые узкополосные режекторные фильтры с очень стабильными фазовыми задержками. В связи с этим еще вопрос. Возможно ли выходной файл из PurePath Studio залить во внутренний ЦОС-процессор TLV320AIC3254 из пользовательской программы? Про этот ЦОС-процессор мало литературы нашел. 

По шрифтам. Давайте я вам шрифты пришлю на почту.
 

 

Share this post


Link to post
Share on other sites

Т.е. реально I2S из микросхемы не вывели?

Вот про PurePathStudio ничего сказать не могу. Результирующий файл они дают? Вот с ним и надо "шаманить".

На всякий случай:

TLV320AIC3254Q1_DesignAndConfigGuide_slaa404c.pdf

TLV320AIC3254Q1_AppRefGuide_slau497a.pdf
Про шрифты спасибо, конечно, но давно нет в них нужды (в смысле, много лет как в наличии).

Share this post


Link to post
Share on other sites
16 hours ago, Obam said:

Т.е. реально I2S из микросхемы не вывели?

Не вывел, сработал стереотип мышления, впервые осваиваю кодек. И просто пропускал понятия, что есть интерфейс управления, а есть оцифрованный поток. Три проводничка ПЭВТЛК обеспечат не реализованный интерфейс. Конечно я разглядывал схему КИТа, где все сделано правильно и видел оба интерфейса, но себя я это объяснял тем, что делалось это на все случаи.

Благодарю вас за дополнительную информацию  

 

Share this post


Link to post
Share on other sites

Хотя есть осадок. Ведь есть у кодека режим DC измерений с доступными фильтрами, этот режим устанавливаю и идут прерывания INT1, после его обработки вычитываю регистры АЦП:

	 Read_ADC_TLV320 (0x68, 0);
	 Read_ADC_TLV320 (0x69, 0);
	 Read_ADC_TLV320 (0x6A, 0);

	 Read_ADC_TLV320 (0x6B, 0);
	 Read_ADC_TLV320 (0x6C, 0);
	 Read_ADC_TLV320 (0x6D, 0);

Есть ведь доступ к регистрам данных АЦП через SPI. Но прерывания идут редко - периодом 2.4 мсек, как написано в документации (P0_R49)

 

Но главное, что АЦП на запускается на потоковую обработку, возможно ли из-за несоответствия:

CODEC_CLKIN   = NADC * MADC * AOSR * ADC_FS

25МГц = MCLK ≠    1 *       4 *    128 *     48000  = 24.576 МГц

Может внутренние коллизии не дают АЦП стартовать? На PLL переходить не желательно, а MCLK менять крайне не желательно

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this