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