Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Audio Codec Si3000 от Silabs
Форум разработчиков электроники ELECTRONIX.ru > Интерфейсы > Форумы по интерфейсам > Аудио/Видео интерфейсы
alvol
Для ввода кодека в режим Slave подключаю вывод SCLK через резистор 50кОм к питанию, а вывод SDO через 50кОм к корпусу. При инициализации подаю на вход сигнал сброса Reset (единичный уровень) в течении 50 мс, после чего устанавливаю его в рабочее состояние (нулевой уровень).
Заметил, что в половине случаев кодек входит в режим Slave и с него получается считывать данные, а в остальных случаях не входит и доступа к нему нет. Посоветуйте что-нить, кто знает.
Alex B._
Код для dsPIC30 и его DCI модуля. Я думаю разберетесь

Код
/* -----------------------------------------------------------------------------
        Константы инициализации кодека
     ----------------------------------------------------------------------------- */

#define MINUS_ONE                 0x8000
#define MINUS_ONE_WITH_SECONDARY  0x8001

#define PLUS_ONE                  0x7FFE
#define PLUS_ONE_WITH_SECONDARY   0x7FFF

/* -----------------------------------------------------------------------------
        Адреса регистров кодека Si3000
        При чтении бит <13> сброшен, при записи - установлен
     ----------------------------------------------------------------------------- */

#define READ_CONTROL_1            0x2100          
#define WRITE_CONTROL_1           0x0100

#define READ_CONTROL_2            0x2200
#define WRITE_CONTROL_2           0x0200

#define READ_PLL1_DIVIDE_N1       0x2300
#define WRITE_PLL1_DIVIDE_N1      0x0300

#define READ_PLL1_MULTIPLY_M1     0x2400
#define WRITE_PLL1_MULTIPLY_M1    0x0400

#define READ_RX_GAIN_CONTROL_1    0x2500
#define WRITE_RX_GAIN_CONTROL_1   0x0500

#define READ_ADC_VOLUME_CONTROL   0x2600
#define WRITE_ADC_VOLUME_CONTROL  0x0600

#define READ_DAC_VOLUME_CONTROL   0x2700
#define WRITE_DAC_VOLUME_CONTROL  0x0700

#define READ_STATUS_REPORT        0x2800
#define WRITE_STATUS_REPORT       0x0800

#define READ_ANALOG_ATTENUATION   0x2900
#define WRITE_ANALOG_ATTENUATION  0x0900

void Init_Codec_Slave(void)
{
    unsigned int i;

    CODEC_RESET = 0;
  __asm__("nop");
  TRIS_CODEC_RESET = OUT;                            // Сброс кодека

    for (i = 0; i <= 40; i++)
  {
    __asm__("nop");                         // Пауза 5 мкс для устойчивого сброса кодека
  }

    TRIS_CODEC_RESET = IN;                                        // Включени кодека

    DCICON1bits.DCIEN = 1;                    // Включение модуля DCI

    /*    PLL кодека
    
            Делитель N1 и множитель M1 PLL кодека определяются следующим соотношением:

            (M1 + 1) / (N1 + 1) = (K * 1024 * Fs) / Fsck
            где K = [5, 10], что определяется битом PLL в регистре CON2 кодека.

            В данном примере N1 = 0, M1 = 19, K = 5
    */

    TXBUF0 = PLUS_ONE_WITH_SECONDARY;                    // Программирование значения делителя PLL кодека (N1)
  TXBUF1 = WRITE_PLL1_DIVIDE_N1 | 0x0000;
  while (DCISTATbits.TMPTY == 0);

    TXBUF0 = PLUS_ONE_WITH_SECONDARY;
  TXBUF1 = WRITE_PLL1_MULTIPLY_M1 | 0x0013; // Программирование значения умножителя PLL кодека (M1)
  while (DCISTATbits.TMPTY == 0);

  TXBUF0 = PLUS_ONE_WITH_SECONDARY;
  TXBUF1 = WRITE_CONTROL_1 | 0x0018;        // Включение линейного усилителя и усилителя ГД
  while (DCISTATbits.TMPTY == 0);

  TXBUF0 = PLUS_ONE_WITH_SECONDARY;                    // Программирование регистра CON2 кодека
  TXBUF1 = WRITE_CONTROL_2;
  while (DCISTATbits.TMPTY == 0);

  TXBUF0 = PLUS_ONE_WITH_SECONDARY;
#ifdef CODEC_IN_MICRO
  TXBUF1 = WRITE_RX_GAIN_CONTROL_1 | 0x7A;  // Коэффициент усиления микрофонного усилителя = +30 дБ
#else
  TXBUF1 = WRITE_RX_GAIN_CONTROL_1 | 0x5E;  // Коэффициент усиления линейного усилителя = 0 дБ
#endif
  while (DCISTATbits.TMPTY == 0);

  TXBUF0 = PLUS_ONE_WITH_SECONDARY;
  TXBUF1 = WRITE_ADC_VOLUME_CONTROL | 0x5C; // Программный коэффициент усиления после АЦП = 0 дБ
  while (DCISTATbits.TMPTY == 0);

  TXBUF0 = PLUS_ONE_WITH_SECONDARY;
  TXBUF1 = WRITE_DAC_VOLUME_CONTROL | 0x005F; // Установка КУ выходного PGA = 0 дБ, левый и правый канал активны
  while (DCISTATbits.TMPTY == 0);

    while(DCISTATbits.SLOT != 0);                            // Для гарантированной инициализации кодека
  while(DCISTATbits.SLOT == 0);
  while(DCISTATbits.SLOT != 0);
  while(DCISTATbits.SLOT == 0);
    
  if(DCISTATbits.ROV == 1)                                    // Сброс битов переполнения вх. буфера, если они установлены
  {
    i = RXBUF0;            // dummy
    i = RXBUF1;     // dummy
  }
    
  DCICON1bits.DCIEN = 0;                    // Выключение DCI модуля

    // Переинициализация модуля DCI

  DCICON2bits.WS = 15;                                     // Слово данных - 16 бит
  DCICON2bits.COFSG = 15;                        // Фрейм данных - 16 слов (256 бит)

  DCICON2bits.BLEN = 0;                                            // Установка глубины буфера
                                                                                        // В буфер будет помещаться 1 слово данных между прерываниями

  IFS2bits.DCIIF = 0;                           // Сброс флага прерывания DCI
  IPC10bits.DCIIP = 6;                          // Установка приоритета прерывания DCI = 6
  IEC2bits.DCIIE = 1;                           // Разрешение DCI прерываний

    DCICON1bits.DCIEN = 1;    // Включение DCI модуля
}
alvol
Alex, cпасибо за пример кода.
Как я понимаю это настройка регистров кодека,
которая происходит во время вторичного запроса (Secondary Request), согласно
описанию протокола кодека. Т.е. в этом коде вы после организации сброса посылаете
запросы с адресом регистра кодека и значением, которое хотите устанвоить в данный регистр.
(
Figure 16. Secondary Communication Data Format—Write Cycle
Figure 17. Secondary Frame Format—Read Cycle
на страницах 16 и 17
)

Меня интересует момент уставноки режима согласно Table 11. Serial Modes в описании на транице 15.
+--------+--------+--------+--------------------------------------+
|..Mode..|.SCLK..|..SDO.|................Description...............|
|=====|=====| ====|======================|
|.....0.....|....0.....|....0....| FSYNC frames data..................|
|.....1.....|....0.....|....1....| FSYNC pulse starts data frame|
|.....2.....|....1.....|....0....| Slave mode..............................| <<-------
|.....3.....|....1.....|....1....| Reserved.................................|
+------+----------+-------+---------------------------------------+

Как вы вибираете режимработы кодека?
Выставляете подтягивающими резисторами (по 50кОм) SCLK и SDO код инициализации
или же управляете процессором значением логического нуля и единицы на пинах кодека в момент
сразу после сброса?
В момент инициализации у меня и возникаетпроблема. кодеки инициализируются верно только в половине случаев.
Я так понял кодек инициализируется динамически в зависимости от состояния пинов SCLK и SDO, а после проходит его настройка согласно установленным значениям регистров программно.

Поправте, пожалуйста, где я неправильно понимаю и расскажите как это делаете вы.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.