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モードでの動作が始まります。

参考リンク

Committer:
shorie
Date:
Fri Jan 27 21:08:29 2017 +0000
Revision:
7:6d921f8c38d6
Parent:
4:a838173c951d
Doxygen comment update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shorie 1:ea6d442bd68a 1 /**
shorie 1:ea6d442bd68a 2 * \file Adau1361.cpp
shorie 1:ea6d442bd68a 3 * \brief implementation of class Adau1361. See Adau1361.h as class definition.
shorie 1:ea6d442bd68a 4 */
shorie 1:ea6d442bd68a 5
shorie 1:ea6d442bd68a 6 #include "adau1361.h"
shorie 1:ea6d442bd68a 7 #include <algorithm>
shorie 1:ea6d442bd68a 8
shorie 2:fba0b8afebf0 9 namespace shimabara
shorie 1:ea6d442bd68a 10 {
shorie 2:fba0b8afebf0 11
shorie 4:a838173c951d 12 Adau1361::Adau1361( Fs_Type Fs, I2C & controler, unsigned int Addr ):
shorie 2:fba0b8afebf0 13 BaseAudioCodec( Fs )
shorie 2:fba0b8afebf0 14 {
shorie 4:a838173c951d 15 i2c = & controler;
shorie 2:fba0b8afebf0 16 addr = Addr<<1; // Justify to right to use mbed library
shorie 2:fba0b8afebf0 17 }
shorie 2:fba0b8afebf0 18
shorie 1:ea6d442bd68a 19
shorie 1:ea6d442bd68a 20 // Core clock setting
shorie 1:ea6d442bd68a 21 static const char init_PLL[][3] =
shorie 1:ea6d442bd68a 22 {
shorie 1:ea6d442bd68a 23 {0x40, 0x00, 0x00}, // R0:Clock control
shorie 1:ea6d442bd68a 24 {0x40, 0x17, 0x00}, // R17, SRC = 1
shorie 1:ea6d442bd68a 25 {0x40, 0x00, 0x0F} // R0:Clock Control. Core clock. PLL Start
shorie 1:ea6d442bd68a 26 };
shorie 1:ea6d442bd68a 27
shorie 1:ea6d442bd68a 28
shorie 1:ea6d442bd68a 29
shorie 1:ea6d442bd68a 30
shorie 1:ea6d442bd68a 31 // Set non clock registers as default
shorie 1:ea6d442bd68a 32 static const char init_Adau1361[][3] =
shorie 1:ea6d442bd68a 33 {
shorie 1:ea6d442bd68a 34 // R0,1, are set by init_freq_xxx table
shorie 1:ea6d442bd68a 35 {0x40, 0x08, 0x00}, // R2: Digital Mic
shorie 1:ea6d442bd68a 36 {0x40, 0x09, 0x00}, // R3: Rec Power Management
shorie 1:ea6d442bd68a 37 {0x40, 0x0a, 0x00}, // R4: Rec Mixer Left 0
shorie 1:ea6d442bd68a 38 {0x40, 0x0b, 0x00}, // R5: Rec Mixer Left 1
shorie 1:ea6d442bd68a 39 {0x40, 0x0c, 0x00}, // R6: Rec Mixer Right 0
shorie 1:ea6d442bd68a 40 {0x40, 0x0d, 0x00}, // R7: Rec Mixer Right 1
shorie 1:ea6d442bd68a 41 {0x40, 0x0e, 0x00}, // R8: Left diff input vol
shorie 1:ea6d442bd68a 42 {0x40, 0x0f, 0x00}, // R9: Right diff input vol
shorie 1:ea6d442bd68a 43 {0x40, 0x10, 0x00}, // R10: Rec mic bias
shorie 1:ea6d442bd68a 44 {0x40, 0x11, 0x00}, // R11: ALC0
shorie 1:ea6d442bd68a 45 {0x40, 0x12, 0x00}, // R12: ALC1
shorie 1:ea6d442bd68a 46 {0x40, 0x13, 0x00}, // R13: ALC2
shorie 1:ea6d442bd68a 47 {0x40, 0x14, 0x00}, // R14: ALC3
shorie 1:ea6d442bd68a 48 {0x40, 0x15, 0x00}, // R15: Serial Port 0
shorie 1:ea6d442bd68a 49 {0x40, 0x16, 0x00}, // R16: Serial Port 1
shorie 1:ea6d442bd68a 50 // R17 is set by init_freq_xxx table
shorie 1:ea6d442bd68a 51 {0x40, 0x18, 0x00}, // R18: Converter 1
shorie 1:ea6d442bd68a 52 {0x40, 0x19, 0x10}, // R19:ADC Control.
shorie 1:ea6d442bd68a 53 {0x40, 0x1a, 0x00}, // R20: Left digital volume
shorie 1:ea6d442bd68a 54 {0x40, 0x1b, 0x00}, // R21: Rignt digital volume
shorie 1:ea6d442bd68a 55 {0x40, 0x1c, 0x00}, // R22: Play Mixer Left 0
shorie 1:ea6d442bd68a 56 {0x40, 0x1d, 0x00}, // R23: Play Mixer Left 1
shorie 1:ea6d442bd68a 57 {0x40, 0x1e, 0x00}, // R24: Play Mixer Right 0
shorie 1:ea6d442bd68a 58 {0x40, 0x1f, 0x00}, // R25: Play Mixer Right 1
shorie 1:ea6d442bd68a 59 {0x40, 0x20, 0x00}, // R26: Play L/R mixer left
shorie 1:ea6d442bd68a 60 {0x40, 0x21, 0x00}, // R27: Play L/R mixer right
shorie 1:ea6d442bd68a 61 {0x40, 0x22, 0x00}, // R28: Play L/R mixer monot
shorie 1:ea6d442bd68a 62 {0x40, 0x23, 0x02}, // R29: Play HP Left vol
shorie 1:ea6d442bd68a 63 {0x40, 0x24, 0x02}, // R30: Play HP Right vol
shorie 1:ea6d442bd68a 64 {0x40, 0x25, 0x02}, // R31: Line output Left vol
shorie 1:ea6d442bd68a 65 {0x40, 0x26, 0x02}, // R32: Line output Right vol
shorie 1:ea6d442bd68a 66 {0x40, 0x27, 0x02}, // R33: Play Mono output
shorie 1:ea6d442bd68a 67 {0x40, 0x28, 0x00}, // R34: Pop surpress
shorie 1:ea6d442bd68a 68 {0x40, 0x29, 0x00}, // R35: Play Power Management
shorie 1:ea6d442bd68a 69 {0x40, 0x2a, 0x00}, // R36: DAC Control 0
shorie 1:ea6d442bd68a 70 {0x40, 0x2b, 0x00}, // R37: DAC Control 1
shorie 1:ea6d442bd68a 71 {0x40, 0x2c, 0x00}, // R38: DAC control 2
shorie 1:ea6d442bd68a 72 {0x40, 0x2d, 0xaa}, // R39: Seial port Pad
shorie 1:ea6d442bd68a 73 {0x40, 0x2f, 0xaa}, // R40: Control Pad 1
shorie 1:ea6d442bd68a 74 {0x40, 0x30, 0x00}, // R41: Control Pad 2
shorie 1:ea6d442bd68a 75 {0x40, 0x31, 0x08}, // R42: Jack detect
shorie 1:ea6d442bd68a 76 {0x40, 0x36, 0x03}, // R67: Dejitter control
shorie 1:ea6d442bd68a 77 };
shorie 1:ea6d442bd68a 78
shorie 1:ea6d442bd68a 79 static const char lock_status_address[] = {0x40, 0x07}; // R2 : Byte 5.
shorie 1:ea6d442bd68a 80
shorie 1:ea6d442bd68a 81
shorie 1:ea6d442bd68a 82 // Send single command
shorie 1:ea6d442bd68a 83 void Adau1361::send_command( const char table[], int size)
shorie 1:ea6d442bd68a 84 {
shorie 1:ea6d442bd68a 85 i2c->write( addr, table, size);
shorie 1:ea6d442bd68a 86 }
shorie 1:ea6d442bd68a 87
shorie 1:ea6d442bd68a 88
shorie 1:ea6d442bd68a 89 // Send entire command table
shorie 1:ea6d442bd68a 90 void Adau1361::send_command_table( const char table[][3], int rows )
shorie 1:ea6d442bd68a 91 {
shorie 1:ea6d442bd68a 92 for ( int i=0; i<rows; i++ )
shorie 1:ea6d442bd68a 93 {
shorie 1:ea6d442bd68a 94 send_command(table[i], 3);
shorie 1:ea6d442bd68a 95 }
shorie 1:ea6d442bd68a 96 }
shorie 1:ea6d442bd68a 97
shorie 1:ea6d442bd68a 98
shorie 1:ea6d442bd68a 99 // loop while the PLL is not locked.
shorie 1:ea6d442bd68a 100 void Adau1361::wait_pll_lock(void)
shorie 1:ea6d442bd68a 101 {
shorie 1:ea6d442bd68a 102
shorie 1:ea6d442bd68a 103 do {
shorie 1:ea6d442bd68a 104 i2c->write( addr, lock_status_address, sizeof(lock_status_address), true); // send address to read.
shorie 1:ea6d442bd68a 105 } while ( !(i2c->read(1) & 0x2) ); // read the PLL status.
shorie 1:ea6d442bd68a 106 }
shorie 1:ea6d442bd68a 107
shorie 1:ea6d442bd68a 108
shorie 1:ea6d442bd68a 109 #define DATA 2 /* data payload of register */
shorie 1:ea6d442bd68a 110 #define ADDL 1 /* lower address of register */
shorie 1:ea6d442bd68a 111 void Adau1361::start(void)
shorie 1:ea6d442bd68a 112 {
shorie 1:ea6d442bd68a 113
shorie 1:ea6d442bd68a 114 // then, start of configuration as register address order
shorie 1:ea6d442bd68a 115 send_command_table(init_PLL, sizeof(init_PLL)/3);
shorie 1:ea6d442bd68a 116
shorie 1:ea6d442bd68a 117
shorie 1:ea6d442bd68a 118 configure_pll();
shorie 1:ea6d442bd68a 119
shorie 1:ea6d442bd68a 120 // Set all registers.
shorie 1:ea6d442bd68a 121 send_command_table(init_Adau1361, sizeof(init_Adau1361)/3); // init Adau1361 as default state.
shorie 1:ea6d442bd68a 122
shorie 1:ea6d442bd68a 123 configure_board();
shorie 1:ea6d442bd68a 124
shorie 1:ea6d442bd68a 125 // set input gain
shorie 1:ea6d442bd68a 126 set_line_input_gain( 0, 0 ); // unmute
shorie 1:ea6d442bd68a 127 set_aux_input_gain( 0, 0, true ); // mute
shorie 1:ea6d442bd68a 128 set_mic_input_gain( 0, 0, true ); // mute
shorie 1:ea6d442bd68a 129 set_line_output_gain( 0, 0, true ); // mute
shorie 1:ea6d442bd68a 130 set_hp_output_gain( 0, 0, true ); // mute
shorie 1:ea6d442bd68a 131 }
shorie 1:ea6d442bd68a 132
shorie 1:ea6d442bd68a 133 #define SET_INPUT_GAIN( x ) ((x<<1)|1)
shorie 1:ea6d442bd68a 134
shorie 1:ea6d442bd68a 135 void Adau1361::set_line_input_gain(float left_gain, float right_gain, bool mute)
shorie 1:ea6d442bd68a 136 {
shorie 1:ea6d442bd68a 137 char data[3];
shorie 1:ea6d442bd68a 138 int left, right;
shorie 1:ea6d442bd68a 139
shorie 1:ea6d442bd68a 140
shorie 1:ea6d442bd68a 141 data[0] = 0x40; // Upper address of register
shorie 1:ea6d442bd68a 142
shorie 1:ea6d442bd68a 143 if ( mute )
shorie 1:ea6d442bd68a 144 {
shorie 1:ea6d442bd68a 145 data[ADDL] = 0x0a; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R4: mixer 1 enable
shorie 1:ea6d442bd68a 146 data[ADDL] = 0x0c; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R6: mixer 2 enable
shorie 1:ea6d442bd68a 147 }
shorie 1:ea6d442bd68a 148 else
shorie 1:ea6d442bd68a 149 {
shorie 1:ea6d442bd68a 150
shorie 1:ea6d442bd68a 151 // set left gain
shorie 1:ea6d442bd68a 152 left = (left_gain+15)/3 ; // See table 31 LINNG
shorie 1:ea6d442bd68a 153 left = max( left, 0 );
shorie 1:ea6d442bd68a 154 left = min( left, 7 );
shorie 1:ea6d442bd68a 155 data[DATA] = SET_INPUT_GAIN( left );
shorie 1:ea6d442bd68a 156
shorie 1:ea6d442bd68a 157 data[ADDL] = 0x0a; i2c->write( addr, data, 3 ); // R4: mixer 1 enable
shorie 1:ea6d442bd68a 158
shorie 1:ea6d442bd68a 159 // set right gain
shorie 1:ea6d442bd68a 160 right = (right_gain+15)/3 ; // See table 31 LINNG
shorie 1:ea6d442bd68a 161 right = max( right, 0 );
shorie 1:ea6d442bd68a 162 right = min( right, 7 );
shorie 1:ea6d442bd68a 163 data[DATA] = SET_INPUT_GAIN( right );
shorie 1:ea6d442bd68a 164
shorie 1:ea6d442bd68a 165 data[ADDL] = 0x0c; i2c->write( addr, data, 3 ); // R4: mixer 1 enable
shorie 1:ea6d442bd68a 166
shorie 1:ea6d442bd68a 167 }
shorie 1:ea6d442bd68a 168 }
shorie 1:ea6d442bd68a 169
shorie 1:ea6d442bd68a 170
shorie 1:ea6d442bd68a 171 void Adau1361::set_aux_input_gain(float left_gain, float right_gain, bool mute)
shorie 1:ea6d442bd68a 172 {
shorie 1:ea6d442bd68a 173 char data[3];
shorie 1:ea6d442bd68a 174 int left, right;
shorie 1:ea6d442bd68a 175
shorie 1:ea6d442bd68a 176
shorie 1:ea6d442bd68a 177 data[0] = 0x40; // Upper address of register
shorie 1:ea6d442bd68a 178
shorie 1:ea6d442bd68a 179 if ( mute )
shorie 1:ea6d442bd68a 180 {
shorie 1:ea6d442bd68a 181 data[ADDL] = 0x0b; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R5: mixer 1 L aux mute
shorie 1:ea6d442bd68a 182 data[ADDL] = 0x0d; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R7: mixer 2 R aux mute
shorie 1:ea6d442bd68a 183 }
shorie 1:ea6d442bd68a 184 else
shorie 1:ea6d442bd68a 185 {
shorie 1:ea6d442bd68a 186
shorie 1:ea6d442bd68a 187 // set left gain
shorie 1:ea6d442bd68a 188 left = (left_gain+15)/3 ; // See table 31 LINNG
shorie 1:ea6d442bd68a 189 left = max( left, 0 );
shorie 1:ea6d442bd68a 190 left = min( left, 7 );
shorie 1:ea6d442bd68a 191 data[DATA] = left ;
shorie 1:ea6d442bd68a 192
shorie 1:ea6d442bd68a 193 data[ADDL] = 0x0b; i2c->write( addr, data, 3 ); // R5: mixer 1 enable
shorie 1:ea6d442bd68a 194
shorie 1:ea6d442bd68a 195 // set right gain
shorie 1:ea6d442bd68a 196 right = (right_gain+15)/3 ; // See table 31 LINNG
shorie 1:ea6d442bd68a 197 right = max( right, 0 );
shorie 1:ea6d442bd68a 198 right = min( right, 7 );
shorie 1:ea6d442bd68a 199 data[DATA] = right;
shorie 1:ea6d442bd68a 200
shorie 1:ea6d442bd68a 201 data[ADDL] = 0x0d; i2c->write( addr, data, 3 ); // R4: mixer 1 enable
shorie 1:ea6d442bd68a 202
shorie 1:ea6d442bd68a 203 }
shorie 1:ea6d442bd68a 204 }
shorie 1:ea6d442bd68a 205
shorie 1:ea6d442bd68a 206
shorie 1:ea6d442bd68a 207 #define SET_LO_GAIN( x ) ((x<<2)|2)
shorie 1:ea6d442bd68a 208
shorie 1:ea6d442bd68a 209 void Adau1361::set_line_output_gain(float left_gain, float right_gain, bool mute)
shorie 1:ea6d442bd68a 210 {
shorie 1:ea6d442bd68a 211 char data[3];
shorie 1:ea6d442bd68a 212 int left, right;
shorie 1:ea6d442bd68a 213
shorie 1:ea6d442bd68a 214 data[0] = 0x40; // Upper address of register
shorie 1:ea6d442bd68a 215
shorie 1:ea6d442bd68a 216 if ( mute )
shorie 1:ea6d442bd68a 217 {
shorie 1:ea6d442bd68a 218 data[ADDL] = 0x25; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R31: LOUTVOL
shorie 1:ea6d442bd68a 219 data[ADDL] = 0x26; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R32: LOUTVOL
shorie 1:ea6d442bd68a 220 }
shorie 1:ea6d442bd68a 221 else
shorie 1:ea6d442bd68a 222 {
shorie 1:ea6d442bd68a 223 left = left_gain+57;
shorie 1:ea6d442bd68a 224 left = max( left, 0 );
shorie 1:ea6d442bd68a 225 left = min( left, 63 );
shorie 1:ea6d442bd68a 226
shorie 1:ea6d442bd68a 227 right = right_gain+57;
shorie 1:ea6d442bd68a 228 right = max( right, 0 );
shorie 1:ea6d442bd68a 229 right = min( right, 63 );
shorie 1:ea6d442bd68a 230
shorie 1:ea6d442bd68a 231 data[ADDL] = 0x25; data[DATA] = SET_LO_GAIN(left ); i2c->write( addr, data, 3 ); // R31: LOUTVOL
shorie 1:ea6d442bd68a 232 data[ADDL] = 0x26; data[DATA] = SET_LO_GAIN(right); i2c->write( addr, data, 3 ); // R32: LOUTVOL
shorie 1:ea6d442bd68a 233
shorie 1:ea6d442bd68a 234 }
shorie 1:ea6d442bd68a 235 }
shorie 1:ea6d442bd68a 236
shorie 1:ea6d442bd68a 237 #define SET_HP_GAIN( x ) ((x<<2)|3)
shorie 1:ea6d442bd68a 238
shorie 1:ea6d442bd68a 239 void Adau1361::set_hp_output_gain(float left_gain, float right_gain, bool mute)
shorie 1:ea6d442bd68a 240 {
shorie 1:ea6d442bd68a 241 char data[3];
shorie 1:ea6d442bd68a 242 int left, right;
shorie 1:ea6d442bd68a 243
shorie 1:ea6d442bd68a 244 data[0] = 0x40; // Upper address of register
shorie 1:ea6d442bd68a 245
shorie 1:ea6d442bd68a 246 if ( mute )
shorie 1:ea6d442bd68a 247 {
shorie 1:ea6d442bd68a 248 data[ADDL] = 0x23; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R29: LHPVOL
shorie 1:ea6d442bd68a 249 data[ADDL] = 0x24; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R30: LHPVOL
shorie 1:ea6d442bd68a 250 }
shorie 1:ea6d442bd68a 251 else
shorie 1:ea6d442bd68a 252 {
shorie 1:ea6d442bd68a 253 left = left_gain+57;
shorie 1:ea6d442bd68a 254 left = max( left, 0 );
shorie 1:ea6d442bd68a 255 left = min( left, 63 );
shorie 1:ea6d442bd68a 256
shorie 1:ea6d442bd68a 257 right = right_gain+57;
shorie 1:ea6d442bd68a 258 right = max( right, 0 );
shorie 1:ea6d442bd68a 259 right = min( right, 63 );
shorie 1:ea6d442bd68a 260
shorie 1:ea6d442bd68a 261 data[ADDL] = 0x23; data[DATA] = SET_HP_GAIN(left ); i2c->write( addr, data, 3 ); // R29: LHPVOL
shorie 1:ea6d442bd68a 262 data[ADDL] = 0x24; data[DATA] = SET_HP_GAIN(right); i2c->write( addr, data, 3 ); // R30: LHPVOL
shorie 1:ea6d442bd68a 263
shorie 1:ea6d442bd68a 264 }
shorie 1:ea6d442bd68a 265 }
shorie 1:ea6d442bd68a 266
shorie 1:ea6d442bd68a 267
shorie 1:ea6d442bd68a 268
shorie 1:ea6d442bd68a 269 }
shorie 1:ea6d442bd68a 270