First publishment of Shimabara Audio Codec Controller library. Including code for ADAU1361 and UMB-ADAU1361A. Working pretty fine. Checked with LPCXpresso 4337 and Unzen_lpc4337

Dependents:   unzen_sample_LPC4088_quickstart unzen_sample_lpcxpresso_4337_callbacks unzen_sample_nucleo_f746 unzen_delay_sample_nucleo_f746 ... more

shimabaraは、mbedからオーディオ・コーデックのハードウェアを操作するクラス・ライブラリです。このライブラリは雲仙オーディオ・フレームワークと共に使うことを想定して開発しましたが、独立して使うことも可能です。

使い方

shimabaraは BaseAudioCodec, ADAU1361, UMB_ADAU1361Aの三つのクラスを定義しています。いずれのクラスも名前空間simabaraに属しています。実際のアプリケーションで使用するのはshimabara::UMB_ADAU1361Aだけで、このクラスはアクアシグナルのUMB-ADAU1361-Aに対応しています。ヘッダーファイルは umb_adau1361a.hです。

shimabara::UMB_ADAU1361Aのコンストラクタは三つの引数を受け取ります。

  • Fs はサンプル周波数です。これはenum Fs_type型の引数で、やはり名前空間shimabaraに属しています。
  • controller はADAU1361Aが接続されているI2Cポートに対応するI2Cオブジェクトを与えます。shimabaraはこのポートを通してCODECと通信します。
  • Addrには、コーデックのI2Cアドレスを与えます。現時点ではこの引数は0x38固定です。

コンストラクタでオブジェクトを初期化したら、start()メソッドを呼んでください。これでshimabaraはコーデックと通信し、I2Sモードでの動作が始まります。

参考リンク

Revision:
1:ea6d442bd68a
Child:
2:fba0b8afebf0
diff -r dc22d60383f0 -r ea6d442bd68a adau1361.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adau1361.cpp	Sun May 08 09:52:42 2016 +0000
@@ -0,0 +1,262 @@
+/**
+* \file Adau1361.cpp
+* \brief implementation of class Adau1361. See Adau1361.h as class definition. 
+*/
+
+#include "adau1361.h"
+#include <algorithm>
+
+namespace audiocodec
+{
+
+        // Core clock setting
+    static const char init_PLL[][3] =
+    {
+        {0x40, 0x00, 0x00},    // R0:Clock control
+        {0x40, 0x17, 0x00},    // R17, SRC = 1
+        {0x40, 0x00, 0x0F}     // R0:Clock Control. Core clock. PLL Start
+    };
+
+    
+    
+    
+        // Set non clock registers as default 
+    static const char init_Adau1361[][3] =
+    {
+            // R0,1, are set by init_freq_xxx table
+        {0x40, 0x08, 0x00},     // R2: Digital Mic
+        {0x40, 0x09, 0x00},     // R3: Rec Power Management
+        {0x40, 0x0a, 0x00},     // R4: Rec Mixer Left 0
+        {0x40, 0x0b, 0x00},     // R5: Rec Mixer Left 1
+        {0x40, 0x0c, 0x00},     // R6: Rec Mixer Right 0
+        {0x40, 0x0d, 0x00},     // R7: Rec Mixer Right 1
+        {0x40, 0x0e, 0x00},     // R8: Left diff input vol
+        {0x40, 0x0f, 0x00},     // R9: Right diff input vol
+        {0x40, 0x10, 0x00},     // R10: Rec mic bias
+        {0x40, 0x11, 0x00},     // R11: ALC0
+        {0x40, 0x12, 0x00},     // R12: ALC1
+        {0x40, 0x13, 0x00},     // R13: ALC2
+        {0x40, 0x14, 0x00},     // R14: ALC3
+        {0x40, 0x15, 0x00},     // R15: Serial Port 0
+        {0x40, 0x16, 0x00},     // R16: Serial Port 1
+            // R17 is set by init_freq_xxx table
+        {0x40, 0x18, 0x00},     // R18: Converter 1
+        {0x40, 0x19, 0x10},     // R19:ADC Control. 
+        {0x40, 0x1a, 0x00},     // R20: Left digital volume
+        {0x40, 0x1b, 0x00},     // R21: Rignt digital volume
+        {0x40, 0x1c, 0x00},     // R22: Play Mixer Left 0
+        {0x40, 0x1d, 0x00},     // R23: Play Mixer Left 1
+        {0x40, 0x1e, 0x00},     // R24: Play Mixer Right 0
+        {0x40, 0x1f, 0x00},     // R25: Play Mixer Right 1
+        {0x40, 0x20, 0x00},     // R26: Play L/R mixer left
+        {0x40, 0x21, 0x00},     // R27: Play L/R mixer right
+        {0x40, 0x22, 0x00},     // R28: Play L/R mixer monot
+        {0x40, 0x23, 0x02},     // R29: Play HP Left vol
+        {0x40, 0x24, 0x02},     // R30: Play HP Right vol
+        {0x40, 0x25, 0x02},     // R31: Line output Left vol
+        {0x40, 0x26, 0x02},     // R32: Line output Right vol
+        {0x40, 0x27, 0x02},     // R33: Play Mono output
+        {0x40, 0x28, 0x00},     // R34: Pop surpress
+        {0x40, 0x29, 0x00},     // R35: Play Power Management
+        {0x40, 0x2a, 0x00},     // R36: DAC Control 0
+        {0x40, 0x2b, 0x00},     // R37: DAC Control 1
+        {0x40, 0x2c, 0x00},     // R38: DAC control 2
+        {0x40, 0x2d, 0xaa},     // R39: Seial port Pad
+        {0x40, 0x2f, 0xaa},     // R40: Control Pad 1
+        {0x40, 0x30, 0x00},     // R41: Control Pad 2
+        {0x40, 0x31, 0x08},     // R42: Jack detect
+        {0x40, 0x36, 0x03},     // R67: Dejitter control
+    };
+
+    static const char lock_status_address[] = {0x40, 0x07};     // R2 : Byte 5.
+
+    
+        // Send single command 
+    void Adau1361::send_command( const char table[], int size)
+    {
+        i2c->write( addr, table, size);
+    }
+
+
+        // Send entire command table
+    void Adau1361::send_command_table( const char table[][3], int rows )
+    {
+        for ( int i=0; i<rows; i++ )  
+        {
+            send_command(table[i], 3);
+        }
+    }
+    
+    
+        // loop while the PLL is not locked.
+    void Adau1361::wait_pll_lock(void)
+    {
+        
+        do {
+            i2c->write( addr, lock_status_address, sizeof(lock_status_address), true);  // send address to read. 
+        } while ( !(i2c->read(1) & 0x2) );  // read the PLL status.
+    }
+    
+        
+        #define DATA 2  /* data payload of register */
+        #define ADDL 1  /* lower address of register */
+    void Adau1361::start(void)
+    {
+
+            // then, start of configuration as register address order
+        send_command_table(init_PLL, sizeof(init_PLL)/3);
+        
+        
+        configure_pll();
+        
+            // Set all registers.
+        send_command_table(init_Adau1361, sizeof(init_Adau1361)/3);    // init Adau1361 as default state.
+
+        configure_board();
+            
+            // set input gain
+        set_line_input_gain( 0, 0 );        // unmute
+        set_aux_input_gain( 0, 0, true );   // mute
+        set_mic_input_gain( 0, 0, true );    // mute
+        set_line_output_gain( 0, 0, true ); // mute
+        set_hp_output_gain( 0, 0, true );   // mute
+    }
+    
+#define SET_INPUT_GAIN( x ) ((x<<1)|1)
+
+    void Adau1361::set_line_input_gain(float left_gain, float right_gain, bool mute)
+    {
+        char data[3];
+        int left, right;
+        
+        
+        data[0] = 0x40; // Upper address of register
+
+        if ( mute )
+        {
+            data[ADDL] = 0x0a; data[DATA] = 0x01; i2c->write( addr, data, 3 );    // R4: mixer 1 enable
+            data[ADDL] = 0x0c; data[DATA] = 0x01; i2c->write( addr, data, 3 );    // R6: mixer 2 enable 
+        }
+        else 
+        {
+            
+                // set left gain
+            left = (left_gain+15)/3 ;   // See table 31 LINNG
+            left = max( left, 0 );
+            left = min( left, 7 );
+            data[DATA] = SET_INPUT_GAIN( left );
+            
+            data[ADDL] = 0x0a; i2c->write( addr, data, 3 );    // R4: mixer 1 enable
+
+                // set right gain
+            right = (right_gain+15)/3 ;   // See table 31 LINNG
+            right = max( right, 0 );
+            right = min( right, 7 );
+            data[DATA] = SET_INPUT_GAIN( right );
+            
+            data[ADDL] = 0x0c; i2c->write( addr, data, 3 );    // R4: mixer 1 enable
+            
+        }
+    }
+
+        
+    void Adau1361::set_aux_input_gain(float left_gain, float right_gain, bool mute)
+    {
+        char data[3];
+        int left, right;
+        
+        
+        data[0] = 0x40; // Upper address of register
+
+        if ( mute )
+        {
+            data[ADDL] = 0x0b; data[DATA] = 0x01; i2c->write( addr, data, 3 );    // R5: mixer 1 L aux mute
+            data[ADDL] = 0x0d; data[DATA] = 0x01; i2c->write( addr, data, 3 );    // R7: mixer 2 R aux mute
+        }
+        else 
+        {
+            
+                // set left gain
+            left = (left_gain+15)/3 ;   // See table 31 LINNG
+            left = max( left, 0 );
+            left = min( left, 7 );
+            data[DATA] = left ;
+            
+            data[ADDL] = 0x0b; i2c->write( addr, data, 3 );    // R5: mixer 1 enable
+
+                // set right gain
+            right = (right_gain+15)/3 ;   // See table 31 LINNG
+            right = max( right, 0 );
+            right = min( right, 7 );
+            data[DATA] = right;
+            
+            data[ADDL] = 0x0d; i2c->write( addr, data, 3 );    // R4: mixer 1 enable
+            
+        }
+    }
+
+        
+#define SET_LO_GAIN( x ) ((x<<2)|2)
+
+    void Adau1361::set_line_output_gain(float left_gain, float right_gain, bool mute)
+    {
+        char data[3];        
+        int left, right;
+        
+        data[0] = 0x40; // Upper address of register
+        
+        if ( mute )
+        {
+            data[ADDL] = 0x25; data[DATA] = 0x01; i2c->write( addr, data, 3 );    // R31: LOUTVOL
+            data[ADDL] = 0x26; data[DATA] = 0x01; i2c->write( addr, data, 3 );    // R32: LOUTVOL 
+        }
+        else 
+        {
+            left = left_gain+57;
+            left = max( left, 0 );
+            left = min( left, 63 );
+                            
+            right = right_gain+57;
+            right = max( right, 0 );
+            right = min( right, 63 );
+            
+            data[ADDL] = 0x25; data[DATA] = SET_LO_GAIN(left ); i2c->write( addr, data, 3 );    // R31: LOUTVOL
+            data[ADDL] = 0x26; data[DATA] = SET_LO_GAIN(right); i2c->write( addr, data, 3 );    // R32: LOUTVOL 
+
+        }
+    }
+
+#define SET_HP_GAIN( x ) ((x<<2)|3)
+
+    void Adau1361::set_hp_output_gain(float left_gain, float right_gain, bool mute)
+    {
+        char data[3];        
+        int left, right;
+        
+        data[0] = 0x40; // Upper address of register
+        
+        if ( mute )
+        {
+            data[ADDL] = 0x23; data[DATA] = 0x01; i2c->write( addr, data, 3 );    // R29: LHPVOL
+            data[ADDL] = 0x24; data[DATA] = 0x01; i2c->write( addr, data, 3 );    // R30: LHPVOL 
+        }
+        else 
+        {
+            left = left_gain+57;
+            left = max( left, 0 );
+            left = min( left, 63 );
+                            
+            right = right_gain+57;
+            right = max( right, 0 );
+            right = min( right, 63 );
+            
+            data[ADDL] = 0x23; data[DATA] = SET_HP_GAIN(left ); i2c->write( addr, data, 3 );    // R29: LHPVOL
+            data[ADDL] = 0x24; data[DATA] = SET_HP_GAIN(right); i2c->write( addr, data, 3 );    // R30: LHPVOL
+
+        }
+    }
+
+
+
+}
+    
\ No newline at end of file