dj_miles 0 February 24, 2014 Posted February 24, 2014 · Report post Здравствуйте! Помогите разобраться с данным кодеком!!! В частности не получается конфигурировать его. Кодеком управляет PIC-контроллер по I2C интерфейсу, а тактируется от внутреннего генератора PIC'а 16 мГц. Сам же кодек юзаю в slave - режиме. Проблема заключается в записи регистров. Чтение проходит на ура, если читать по одному регистру. Прочитать все регистры разом не получается. Алгоритм чтения и записи выполняю точно так как описано в даташите. Что не так? Может кто то имел дело с данным чудом!!!! Quote Share this post Link to post Share on other sites More sharing options...
Jury093 1 February 25, 2014 Posted February 25, 2014 · Report post Что не так? Может кто то имел дело с данным чудом!!!! всегда удивлялся таким вопросам - исходной информации ноль, кроме "не работает".. где схема включения, где линк на даташит, где куски исходного кода, где лог с точкой неисправности? железки все типовые, протоколы тоже.. и если нет патологии конкретного кристалла и все сделано верно, то и работать должно, как задумано производителем.. если электрически все соединено правильно, то вероятно у вас ошибка в реализации протокола обмена.. может бит готовности не опрашиваете, может подтверждения транзакции не проверяете, может чип не поддерживает групповые операции чтения/записи.. Quote Share this post Link to post Share on other sites More sharing options...
dj_miles 0 February 25, 2014 Posted February 25, 2014 · Report post Спасибо за поправки!!! Даташит на 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; } Quote Share this post Link to post Share on other sites More sharing options...
Jury093 1 February 25, 2014 Posted February 25, 2014 · Report post Спасибо за поправки!!! ну вот так заметно лучше.. по электросхеме - использована шина i2c, а где подтяжки (pullup)? шина с ОК и должны стоять резисторы от контактов scl и sda на +3в3 (в диапазоне 4к7..10к) Quote Share this post Link to post Share on other sites More sharing options...
dj_miles 0 February 25, 2014 Posted February 25, 2014 · Report post ну вот так заметно лучше.. по электросхеме - использована шина i2c, а где подтяжки (pullup)? шина с ОК и должны стоять резисторы от контактов scl и sda на +3в3 (в диапазоне 4к7..10к) На схеме не указаны, но на самом деле стоят. По поводу номиналов: я так понимаю, что он выбирается в зависимости огт скорости? У меня сейчас стоят 1к. Quote Share this post Link to post Share on other sites More sharing options...
Jury093 1 February 25, 2014 Posted February 25, 2014 · Report post На схеме не указаны, но на самом деле стоят. По поводу номиналов: я так понимаю, что он выбирается в зависимости огт скорости? У меня сейчас стоят 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 Quote Share this post Link to post Share on other sites More sharing options...
dj_miles 0 February 25, 2014 Posted February 25, 2014 · Report post Короче сделал щас так: перевел его в режим мастера и все как по маслу работает. Вот теперь вопрос: почему он в слейв режиме не хотел записывать значения регистров?!!! Остается загадкой! Так ведь судя по всему касаясь шины I2C, он ведь так и остался в слейв режиме! По поводу подтверждения: согласен! Указанный флаг просто не учитывается у меня, но по факту читается бы ло ли подтверждение от слейва. Quote Share this post Link to post Share on other sites More sharing options...
dj_miles 0 February 28, 2014 Posted February 28, 2014 · Report post Выкладываю свой тестовый проект, может кому понадобиться. Камень PIC24FJ64GA004. Среда MPLAB IDE. Компилятор XC16. В кратце опишу: TLV320 работает в Master-режиме, так как в slave добиться нормальной и стабильной работы так и не удалось, да и работать как оказалось в этом режиме очень удобно. Возможно это связано с процедурой сброса. Частота тактирования кодека взята с PIC, с выхода частоты переферии( у меня внутренний генератор с PLL 32 мГц, выход на лапе 16 мГц). В проекте есть файл ded.h - это тестовый кусочек для воспроизведения. Для теста микрофонного входа можно соеденить сигнал SPI_DIN_1 и SPI_DOUT_1, тогда все , что вы говорите в микрофон можно сразу услышать в динамике. В целом кодек не плохой. Мощности для динамика маловато или может, что то с конфигурацией намудрил. А так качество вполне неплохое. Будут вопросы, с удовольствием отвечу! TLV320AIC12k_Test.zip Quote Share this post Link to post Share on other sites More sharing options...
Россиянин 0 June 17, 2017 Posted June 17, 2017 · Report post Спасибо за поправки!!! Даташит на 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 не нашёл. Quote Share this post Link to post Share on other sites More sharing options...
Vladimir_T 0 August 7, 2020 Posted August 7, 2020 · Report post Здравствуйте, уважаеые коллеги, подскажите, пожалуйста по кодеку 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)*/ Quote Share this post Link to post Share on other sites More sharing options...
Obam 8 August 7, 2020 Posted August 7, 2020 · Report post А что ж вы I2S-шину не задействовали? Шрифт гостовский - красота ;-) По SPI только управлене осуществляется; данные в\из ЦАП\АЦП по I2S бегают (BCLK, WCLK, DIN, DOUT они для кого?). Стр 44 в slas549d "ковбои" старались рисовали-рисовали ;-) Quote Share this post Link to post Share on other sites More sharing options...
Vladimir_T 0 August 10, 2020 Posted August 10, 2020 · Report post On 8/8/2020 at 12:35 AM, Obam said: А что ж вы I2S-шину не задействовали? Шрифт гостовский - красота Благодарю за разъяснения. Шибко много времени потерял по этой причине. Беспечность в очередной раз подвела. Но, конечно, это время ушло еще и на изучение работы и параметров кодека. Я его использую в биометрической системе и потому грех не воспользоваться встроенным ЦОС -процессором для обработки зашумленных сигналов. Но без PurePath Studio не обойтись и TI не раздает софт, а я спрашивал, но, видать, ужесточения у них. Планировал делать перестраиваемые узкополосные режекторные фильтры с очень стабильными фазовыми задержками. В связи с этим еще вопрос. Возможно ли выходной файл из PurePath Studio залить во внутренний ЦОС-процессор TLV320AIC3254 из пользовательской программы? Про этот ЦОС-процессор мало литературы нашел. По шрифтам. Давайте я вам шрифты пришлю на почту. Quote Share this post Link to post Share on other sites More sharing options...
Obam 8 August 10, 2020 Posted August 10, 2020 · Report post Т.е. реально I2S из микросхемы не вывели? Вот про PurePathStudio ничего сказать не могу. Результирующий файл они дают? Вот с ним и надо "шаманить". На всякий случай: TLV320AIC3254Q1_DesignAndConfigGuide_slaa404c.pdf TLV320AIC3254Q1_AppRefGuide_slau497a.pdf Про шрифты спасибо, конечно, но давно нет в них нужды (в смысле, много лет как в наличии). Quote Share this post Link to post Share on other sites More sharing options...
Vladimir_T 0 August 11, 2020 Posted August 11, 2020 · Report post 16 hours ago, Obam said: Т.е. реально I2S из микросхемы не вывели? Не вывел, сработал стереотип мышления, впервые осваиваю кодек. И просто пропускал понятия, что есть интерфейс управления, а есть оцифрованный поток. Три проводничка ПЭВТЛК обеспечат не реализованный интерфейс. Конечно я разглядывал схему КИТа, где все сделано правильно и видел оба интерфейса, но себя я это объяснял тем, что делалось это на все случаи. Благодарю вас за дополнительную информацию Quote Share this post Link to post Share on other sites More sharing options...
Vladimir_T 0 August 11, 2020 Posted August 11, 2020 · Report post Хотя есть осадок. Ведь есть у кодека режим 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 менять крайне не желательно Quote Share this post Link to post Share on other sites More sharing options...