Перейти к содержанию
    

Audio Codec Si3000 от Silabs

Для ввода кодека в режим Slave подключаю вывод SCLK через резистор 50кОм к питанию, а вывод SDO через 50кОм к корпусу. При инициализации подаю на вход сигнал сброса Reset (единичный уровень) в течении 50 мс, после чего устанавливаю его в рабочее состояние (нулевой уровень).

Заметил, что в половине случаев кодек входит в режим Slave и с него получается считывать данные, а в остальных случаях не входит и доступа к нему нет. Посоветуйте что-нить, кто знает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Код для 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 модуля
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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, а после проходит его настройка согласно установленным значениям регистров программно.

 

Поправте, пожалуйста, где я неправильно понимаю и расскажите как это делаете вы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...