First Publish. Works fine.

Dependents:   unzen_sample_nucleo_f746 unzen_delay_sample_nucleo_f746 skeleton_unzen_nucleo_f746 ifmag_noise_canceller ... more

Nucleo F746ZG用のオーディオ・フレームワークです。フレームワーク地震の詳細は『雲仙』オーディオ・フレームワークを参照してください。

参考リンク

  • skeleton_unzen_nucleo_f746 Nucleo F746ZGおよびUI基板を使う場合のスケルトンプログラム。F746を使う方はここから読み始めると良いでしょう。
Committer:
shorie
Date:
Tue May 03 07:44:49 2016 +0000
Revision:
3:707608830793
Parent:
2:6613e62da521
Child:
4:d89a1e2b4b03
just before working

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shorie 2:6613e62da521 1 #include "algorithm"
shorie 2:6613e62da521 2 #include "limits.h"
shorie 2:6613e62da521 3
shorie 0:5ac19c994288 4 #include "unzen.h"
shorie 0:5ac19c994288 5 #include "unzen_hal.h"
shorie 0:5ac19c994288 6
shorie 0:5ac19c994288 7 namespace unzen
shorie 0:5ac19c994288 8 {
shorie 0:5ac19c994288 9 framework::framework()
shorie 0:5ac19c994288 10 {
shorie 2:6613e62da521 11
shorie 2:6613e62da521 12 // Clear all buffers
shorie 0:5ac19c994288 13 tx_int_buffer[0] = NULL;
shorie 0:5ac19c994288 14 tx_int_buffer[1] = NULL;
shorie 0:5ac19c994288 15 rx_int_buffer[0] = NULL;
shorie 0:5ac19c994288 16 rx_int_buffer[1] = NULL;
shorie 0:5ac19c994288 17
shorie 0:5ac19c994288 18 tx_left_buffer = NULL;
shorie 0:5ac19c994288 19 tx_right_buffer = NULL;
shorie 0:5ac19c994288 20 rx_left_buffer = NULL;
shorie 0:5ac19c994288 21 rx_right_buffer = NULL;
shorie 0:5ac19c994288 22
shorie 2:6613e62da521 23 // Initialize all buffer
shorie 0:5ac19c994288 24 buffer_index = 0;
shorie 2:6613e62da521 25 sample_index = 0;
shorie 0:5ac19c994288 26
shorie 2:6613e62da521 27 // Clear all callbacks
shorie 0:5ac19c994288 28 pre_interrupt_callback = NULL;
shorie 0:5ac19c994288 29 post_interrupt_callback = NULL;
shorie 0:5ac19c994288 30 pre_process_callback = NULL;
shorie 0:5ac19c994288 31 post_process_callback = NULL;
shorie 0:5ac19c994288 32
shorie 0:5ac19c994288 33 process_callback = NULL;
shorie 0:5ac19c994288 34
shorie 2:6613e62da521 35 // Initialy block(buffer) size is 1.
shorie 0:5ac19c994288 36 set_block_size( 1 );
shorie 0:5ac19c994288 37
shorie 2:6613e62da521 38 // Initialize I2S peripheral
shorie 0:5ac19c994288 39 hal_i2s_setup();
shorie 0:5ac19c994288 40
shorie 2:6613e62da521 41 // Setup the interrupt for the I2S
shorie 0:5ac19c994288 42 NVIC_SetVector(hal_get_i2s_irq_id(), (uint32_t)i2s_irq_handler);
shorie 2:6613e62da521 43 set_i2s_irq_priority(hal_get_i2s_irq_priority_level());
shorie 0:5ac19c994288 44 NVIC_EnableIRQ(hal_get_i2s_irq_id());
shorie 0:5ac19c994288 45
shorie 2:6613e62da521 46 // Setup the interrupt for the process
shorie 0:5ac19c994288 47 NVIC_SetVector(hal_get_process_irq_id(), (uint32_t)process_irq_handler);
shorie 2:6613e62da521 48 set_process_irq_priority(hal_get_process_irq_priority_level());
shorie 0:5ac19c994288 49 NVIC_EnableIRQ(hal_get_process_irq_id());
shorie 0:5ac19c994288 50
shorie 0:5ac19c994288 51 }
shorie 0:5ac19c994288 52
shorie 0:5ac19c994288 53 error_type framework::set_block_size( unsigned int new_block_size )
shorie 0:5ac19c994288 54 {
shorie 0:5ac19c994288 55
shorie 0:5ac19c994288 56 delete [] tx_int_buffer[0];
shorie 0:5ac19c994288 57 delete [] tx_int_buffer[1];
shorie 0:5ac19c994288 58 delete [] rx_int_buffer[0];
shorie 0:5ac19c994288 59 delete [] rx_int_buffer[1];
shorie 0:5ac19c994288 60
shorie 0:5ac19c994288 61 delete [] tx_left_buffer;
shorie 0:5ac19c994288 62 delete [] tx_right_buffer;
shorie 0:5ac19c994288 63 delete [] rx_left_buffer;
shorie 0:5ac19c994288 64 delete [] rx_right_buffer;
shorie 0:5ac19c994288 65
shorie 0:5ac19c994288 66 block_size = new_block_size;
shorie 0:5ac19c994288 67
shorie 0:5ac19c994288 68 tx_int_buffer[0] = new int[ 2 * block_size ];
shorie 0:5ac19c994288 69 tx_int_buffer[1] = new int[ 2 * block_size ];
shorie 0:5ac19c994288 70 rx_int_buffer[0] = new int[ 2 * block_size ];
shorie 0:5ac19c994288 71 rx_int_buffer[1] = new int[ 2 * block_size ];
shorie 0:5ac19c994288 72
shorie 0:5ac19c994288 73 tx_left_buffer = new float[ block_size ];
shorie 0:5ac19c994288 74 tx_right_buffer = new float[ block_size ];
shorie 0:5ac19c994288 75 rx_left_buffer = new float[ block_size ];
shorie 0:5ac19c994288 76 rx_right_buffer = new float[ block_size ];
shorie 0:5ac19c994288 77
shorie 0:5ac19c994288 78 // error check
shorie 0:5ac19c994288 79 if ( rx_int_buffer[0] == NULL |
shorie 0:5ac19c994288 80 rx_int_buffer[1] == NULL |
shorie 0:5ac19c994288 81 tx_int_buffer[0] == NULL |
shorie 0:5ac19c994288 82 tx_int_buffer[1] == NULL |
shorie 0:5ac19c994288 83 rx_right_buffer == NULL |
shorie 0:5ac19c994288 84 tx_right_buffer == NULL |
shorie 0:5ac19c994288 85 rx_left_buffer == NULL |
shorie 0:5ac19c994288 86 tx_left_buffer == NULL )
shorie 0:5ac19c994288 87 { // if error, release all
shorie 0:5ac19c994288 88 delete [] tx_int_buffer[0];
shorie 0:5ac19c994288 89 delete [] tx_int_buffer[1];
shorie 0:5ac19c994288 90 delete [] rx_int_buffer[0];
shorie 0:5ac19c994288 91 delete [] rx_int_buffer[1];
shorie 0:5ac19c994288 92
shorie 0:5ac19c994288 93 delete [] tx_left_buffer;
shorie 0:5ac19c994288 94 delete [] tx_right_buffer;
shorie 0:5ac19c994288 95 delete [] rx_left_buffer;
shorie 0:5ac19c994288 96 delete [] rx_right_buffer;
shorie 0:5ac19c994288 97
shorie 0:5ac19c994288 98 tx_int_buffer[0] = NULL;
shorie 0:5ac19c994288 99 tx_int_buffer[1] = NULL;
shorie 0:5ac19c994288 100 rx_int_buffer[0] = NULL;
shorie 0:5ac19c994288 101 rx_int_buffer[1] = NULL;
shorie 0:5ac19c994288 102
shorie 0:5ac19c994288 103 tx_left_buffer = NULL;
shorie 0:5ac19c994288 104 tx_right_buffer = NULL;
shorie 0:5ac19c994288 105 rx_left_buffer = NULL;
shorie 0:5ac19c994288 106 rx_right_buffer = NULL;
shorie 0:5ac19c994288 107
shorie 0:5ac19c994288 108 return memory_allocation_error;
shorie 0:5ac19c994288 109 }
shorie 0:5ac19c994288 110
shorie 0:5ac19c994288 111 // clear blocks
shorie 0:5ac19c994288 112 for ( int i=0; i<block_size*2; i++ )
shorie 0:5ac19c994288 113 {
shorie 0:5ac19c994288 114
shorie 0:5ac19c994288 115 tx_int_buffer[0][i] = 0;
shorie 0:5ac19c994288 116 tx_int_buffer[1][i] = 0;
shorie 0:5ac19c994288 117 rx_int_buffer[0][i] = 0;
shorie 0:5ac19c994288 118 rx_int_buffer[1][i] = 0;
shorie 0:5ac19c994288 119
shorie 0:5ac19c994288 120 }
shorie 0:5ac19c994288 121 // clear blocks
shorie 0:5ac19c994288 122 for ( int i=0; i<block_size ; i++ )
shorie 0:5ac19c994288 123 {
shorie 0:5ac19c994288 124
shorie 0:5ac19c994288 125 tx_left_buffer[i] = 0;
shorie 0:5ac19c994288 126 tx_right_buffer[i] = 0;
shorie 0:5ac19c994288 127 rx_left_buffer[i] = 0;
shorie 0:5ac19c994288 128 rx_right_buffer[i] = 0;
shorie 0:5ac19c994288 129
shorie 0:5ac19c994288 130 }
shorie 0:5ac19c994288 131
shorie 0:5ac19c994288 132 return no_error;
shorie 0:5ac19c994288 133 }
shorie 0:5ac19c994288 134
shorie 0:5ac19c994288 135 void framework::start()
shorie 0:5ac19c994288 136 {
shorie 2:6613e62da521 137 // synchronize with Word select signal, to process RX/TX as atomic timing.
shorie 1:9710fb328a08 138 hal_i2s_pin_config_and_wait_ws();
shorie 0:5ac19c994288 139 hal_i2s_start();
shorie 0:5ac19c994288 140 }
shorie 0:5ac19c994288 141
shorie 0:5ac19c994288 142 void framework::set_i2s_irq_priority( unsigned int pri )
shorie 0:5ac19c994288 143 {
shorie 0:5ac19c994288 144 NVIC_SetPriority(hal_get_process_irq_id(), pri); // must be higher than PendSV of mbed-RTOS
shorie 0:5ac19c994288 145
shorie 0:5ac19c994288 146 }
shorie 0:5ac19c994288 147
shorie 0:5ac19c994288 148 void framework::set_process_irq_priority( unsigned int pri )
shorie 0:5ac19c994288 149 {
shorie 0:5ac19c994288 150 NVIC_SetPriority(hal_get_i2s_irq_id(), pri); // must be higher than process IRQ
shorie 0:5ac19c994288 151
shorie 0:5ac19c994288 152 }
shorie 0:5ac19c994288 153
shorie 0:5ac19c994288 154 void framework::set_process_callback( void (* cb ) (float[], float[], float[], float[], unsigned int))
shorie 0:5ac19c994288 155 {
shorie 0:5ac19c994288 156 process_callback = cb;
shorie 0:5ac19c994288 157 }
shorie 0:5ac19c994288 158
shorie 0:5ac19c994288 159 void framework::set_pre_interrupt_callback( void (* cb ) (void))
shorie 0:5ac19c994288 160 {
shorie 0:5ac19c994288 161 pre_interrupt_callback = cb;
shorie 0:5ac19c994288 162 }
shorie 0:5ac19c994288 163
shorie 0:5ac19c994288 164 void framework::set_post_interrupt_callback( void (* cb ) (void))
shorie 0:5ac19c994288 165 {
shorie 0:5ac19c994288 166 post_interrupt_callback = cb;
shorie 0:5ac19c994288 167 }
shorie 0:5ac19c994288 168
shorie 0:5ac19c994288 169 void framework::set_pre_process_callback( void (* cb ) (void))
shorie 0:5ac19c994288 170 {
shorie 0:5ac19c994288 171 pre_process_callback = cb;
shorie 0:5ac19c994288 172 }
shorie 0:5ac19c994288 173
shorie 0:5ac19c994288 174 void framework::set_post_process_callback( void (* cb ) (void))
shorie 0:5ac19c994288 175 {
shorie 0:5ac19c994288 176 post_process_callback = cb;
shorie 0:5ac19c994288 177 }
shorie 0:5ac19c994288 178
shorie 0:5ac19c994288 179 void framework::do_i2s_irq(void)
shorie 0:5ac19c994288 180 {
shorie 2:6613e62da521 181 // if needed, call pre-interrupt call back
shorie 0:5ac19c994288 182 if ( pre_interrupt_callback )
shorie 0:5ac19c994288 183 pre_interrupt_callback();
shorie 0:5ac19c994288 184
shorie 0:5ac19c994288 185 // irq is handled only when the buffer is correctly allocated
shorie 0:5ac19c994288 186 if (tx_left_buffer)
shorie 0:5ac19c994288 187 {
shorie 0:5ac19c994288 188 int sample;
shorie 2:6613e62da521 189
shorie 2:6613e62da521 190 // check how many data have to be transmimted per interrupt.
shorie 2:6613e62da521 191 for ( int i=0; i<hal_data_per_sample(); i++ )
shorie 0:5ac19c994288 192 {
shorie 2:6613e62da521 193 // copy received data to buffer
shorie 2:6613e62da521 194 hal_get_i2s_rx_data( sample );
shorie 2:6613e62da521 195 rx_int_buffer[buffer_index][sample_index] = sample;
shorie 2:6613e62da521 196
shorie 2:6613e62da521 197 // copy buffer data to transmit register
shorie 2:6613e62da521 198 sample = tx_int_buffer[buffer_index][sample_index];
shorie 2:6613e62da521 199 hal_put_i2s_tx_data( sample );
shorie 2:6613e62da521 200
shorie 2:6613e62da521 201 // increment index
shorie 2:6613e62da521 202 sample_index ++;
shorie 0:5ac19c994288 203 }
shorie 2:6613e62da521 204
shorie 0:5ac19c994288 205 // Implementation of the double buffer algorithm.
shorie 0:5ac19c994288 206 // if buffer transfer is complete, swap the buffer
shorie 3:707608830793 207 if (sample_index >= block_size * 2)
shorie 0:5ac19c994288 208 {
shorie 0:5ac19c994288 209 // index for the signal processing
shorie 0:5ac19c994288 210 process_index = buffer_index;
shorie 2:6613e62da521 211
shorie 0:5ac19c994288 212 // swap buffer
shorie 2:6613e62da521 213 if ( buffer_index == 0 )
shorie 2:6613e62da521 214 buffer_index = 1;
shorie 2:6613e62da521 215 else
shorie 2:6613e62da521 216 buffer_index = 0;
shorie 0:5ac19c994288 217
shorie 2:6613e62da521 218 // rewind sample index
shorie 2:6613e62da521 219 sample_index = 0;
shorie 2:6613e62da521 220
shorie 2:6613e62da521 221 // Trigger interrupt for signal processing
shorie 2:6613e62da521 222 NVIC->STIR = hal_get_process_irq_id();
shorie 0:5ac19c994288 223 }
shorie 0:5ac19c994288 224 }
shorie 0:5ac19c994288 225
shorie 2:6613e62da521 226 // if needed, call post-interrupt call back
shorie 0:5ac19c994288 227 if ( post_interrupt_callback )
shorie 0:5ac19c994288 228 post_interrupt_callback();
shorie 3:707608830793 229
shorie 0:5ac19c994288 230 }
shorie 0:5ac19c994288 231
shorie 0:5ac19c994288 232 void framework::do_process_irq(void)
shorie 0:5ac19c994288 233 {
shorie 2:6613e62da521 234 // If needed, call the pre-process hook
shorie 0:5ac19c994288 235 if ( pre_process_callback )
shorie 0:5ac19c994288 236 pre_process_callback();
shorie 0:5ac19c994288 237
shorie 2:6613e62da521 238 // Only when the process_call back is registered.
shorie 0:5ac19c994288 239 if ( process_callback )
shorie 0:5ac19c994288 240 {
shorie 0:5ac19c994288 241 int j = 0;
shorie 0:5ac19c994288 242
shorie 2:6613e62da521 243 // Format conversion.
shorie 2:6613e62da521 244 // -- premuted from LRLRLR... to LLL.., RRR...
shorie 2:6613e62da521 245 // -- convert from fixed point to floating point
shorie 2:6613e62da521 246 // -- scale down as range of [-1, 1)
shorie 0:5ac19c994288 247 for ( int i=0; i<block_size; i++ )
shorie 0:5ac19c994288 248 {
shorie 0:5ac19c994288 249 rx_left_buffer[i] = rx_int_buffer[process_index][j++]/ -(float)INT_MIN;
shorie 0:5ac19c994288 250 rx_right_buffer[i] = rx_int_buffer[process_index][j++]/ -(float)INT_MIN;
shorie 0:5ac19c994288 251 }
shorie 0:5ac19c994288 252
shorie 1:9710fb328a08 253 process_callback
shorie 1:9710fb328a08 254 (
shorie 0:5ac19c994288 255 rx_left_buffer,
shorie 0:5ac19c994288 256 rx_right_buffer,
shorie 0:5ac19c994288 257 tx_left_buffer,
shorie 0:5ac19c994288 258 tx_right_buffer,
shorie 0:5ac19c994288 259 block_size
shorie 1:9710fb328a08 260 );
shorie 0:5ac19c994288 261
shorie 2:6613e62da521 262 // Format conversion.
shorie 2:6613e62da521 263 // -- premuted from LLL.., RRR... to LRLRLR...
shorie 2:6613e62da521 264 // -- convert from floating point to fixed point
shorie 2:6613e62da521 265 // -- scale up from range of [-1, 1)
shorie 0:5ac19c994288 266 j = 0;
shorie 0:5ac19c994288 267 for ( int i=0; i<block_size; i++ )
shorie 0:5ac19c994288 268 {
shorie 3:707608830793 269 // tx_int_buffer[process_index][j++] = tx_left_buffer[i] * -(float)INT_MIN ;
shorie 3:707608830793 270 // tx_int_buffer[process_index][j++] = tx_right_buffer[i] * -(float)INT_MIN ;
shorie 3:707608830793 271 tx_int_buffer[process_index][j++] = i << 26;
shorie 3:707608830793 272 tx_int_buffer[process_index][j++] = i << 26 ;
shorie 0:5ac19c994288 273 }
shorie 0:5ac19c994288 274
shorie 0:5ac19c994288 275 }
shorie 0:5ac19c994288 276
shorie 2:6613e62da521 277 // if needed, call post-process callback
shorie 0:5ac19c994288 278 if ( post_process_callback )
shorie 0:5ac19c994288 279 post_process_callback();
shorie 0:5ac19c994288 280 }
shorie 0:5ac19c994288 281
shorie 0:5ac19c994288 282 void framework::process_irq_handler()
shorie 0:5ac19c994288 283 {
shorie 1:9710fb328a08 284 framework::get()->do_process_irq();
shorie 0:5ac19c994288 285 }
shorie 0:5ac19c994288 286
shorie 0:5ac19c994288 287 void framework::i2s_irq_handler()
shorie 2:6613e62da521 288 {
shorie 1:9710fb328a08 289 framework::get()->do_i2s_irq();
shorie 0:5ac19c994288 290 }
shorie 1:9710fb328a08 291
shorie 2:6613e62da521 292
shorie 2:6613e62da521 293
shorie 2:6613e62da521 294
shorie 2:6613e62da521 295
shorie 2:6613e62da521 296 umb_adau1361::umb_adau1361( I2C * controler, Fs_Type Fs, Addr_Type Addr )
shorie 1:9710fb328a08 297 {
shorie 1:9710fb328a08 298 i2c = controler;
shorie 2:6613e62da521 299 fs = Fs;
shorie 2:6613e62da521 300 addr = Addr;
shorie 1:9710fb328a08 301 }
shorie 0:5ac19c994288 302
shorie 1:9710fb328a08 303
shorie 2:6613e62da521 304 #define DATA 2 /* data payload of register */
shorie 2:6613e62da521 305 #define ADDL 1 /* lower address of register */
shorie 1:9710fb328a08 306 void umb_adau1361::start(void)
shorie 1:9710fb328a08 307 {
shorie 2:6613e62da521 308 char data[8];
shorie 2:6613e62da521 309
shorie 2:6613e62da521 310 // **** Setup all ADAU-1361 register to reset state ****
shorie 2:6613e62da521 311
shorie 2:6613e62da521 312 data[0] = 0x40; // Upper address of register
shorie 2:6613e62da521 313
shorie 2:6613e62da521 314 // mute all at first
shorie 2:6613e62da521 315 // may not able to write after reset, but do it avoid noise on warm start
shorie 2:6613e62da521 316 for ( int i=0x23; i>0x27; i++ )
shorie 2:6613e62da521 317 data[ADDL] = i; data[DATA] = 0x02; i2c->write( addr, data, 3 ); // R29:Play HP left vol ... R33: play mono vol
shorie 2:6613e62da521 318
shorie 2:6613e62da521 319 // then, start of configuration as register address order
shorie 2:6613e62da521 320 data[ADDL] = 0x00; data[DATA] = 0x0F; i2c->write( addr, data, 3 ); // clock CTL. PLL input. Core clock enable.
shorie 2:6613e62da521 321
shorie 2:6613e62da521 322 // set Fs ( clock in is 12MHz )
shorie 2:6613e62da521 323 if ( fs == Fs_441 )
shorie 2:6613e62da521 324 {
shorie 2:6613e62da521 325 data[ADDL] = 0x02;
shorie 2:6613e62da521 326 data[2] = 0x02;
shorie 2:6613e62da521 327 data[3] = 0x71;
shorie 2:6613e62da521 328 data[4] = 0x01;
shorie 2:6613e62da521 329 data[5] = 0xDD;
shorie 2:6613e62da521 330 data[6] = 0x19;
shorie 2:6613e62da521 331 data[7] = 0x01;
shorie 2:6613e62da521 332 i2c->write( addr, data, 8 );
shorie 2:6613e62da521 333 }
shorie 2:6613e62da521 334 else if ( fs == Fs_48 || fs == Fs_96)
shorie 2:6613e62da521 335 {
shorie 2:6613e62da521 336 data[ADDL] = 0x02;
shorie 2:6613e62da521 337 data[2] = 0x00;
shorie 2:6613e62da521 338 data[3] = 0x7D;
shorie 2:6613e62da521 339 data[4] = 0x00;
shorie 2:6613e62da521 340 data[5] = 0x0C;
shorie 2:6613e62da521 341 data[6] = 0x21;
shorie 2:6613e62da521 342 data[7] = 0x01;
shorie 2:6613e62da521 343 i2c->write( addr, data, 8 );
shorie 2:6613e62da521 344 }
shorie 2:6613e62da521 345
shorie 2:6613e62da521 346 // Initialize all register as reset.
shorie 2:6613e62da521 347 for ( int i=0x08; i>0x19; i++ )
shorie 2:6613e62da521 348 data[ADDL] = i; data[DATA] = 0x00; i2c->write( addr, data, 3 ); // R2:Dig Mic ... R18:Converter 1
shorie 2:6613e62da521 349
shorie 2:6613e62da521 350 data[ADDL] = 0x19; data[DATA] = 0x10; i2c->write( addr, data, 3 ); // R19:ADC Control
shorie 2:6613e62da521 351
shorie 2:6613e62da521 352 for ( int i=0x1A; i>0x22; i++ )
shorie 2:6613e62da521 353 data[ADDL] = i; data[DATA] = 0x00; i2c->write( addr, data, 3 ); // R20:Left digital vol ... R28: play mixer mono
shorie 2:6613e62da521 354
shorie 2:6613e62da521 355 for ( int i=0x23; i>0x27; i++ )
shorie 2:6613e62da521 356 data[ADDL] = i; data[DATA] = 0x02; i2c->write( addr, data, 3 ); // R29:Play HP left vol ... R33: play mono vol
shorie 2:6613e62da521 357
shorie 2:6613e62da521 358 for ( int i=0x28; i>0x2c; i++ )
shorie 2:6613e62da521 359 data[ADDL] = i; data[DATA] = 0x00; i2c->write( addr, data, 3 ); // R34:play pop surpress ... R38: Dac ctl2
shorie 2:6613e62da521 360
shorie 2:6613e62da521 361 data[ADDL] = 0x2d; data[DATA] = 0xaa; i2c->write( addr, data, 3 ); // R39:serial control pad
shorie 2:6613e62da521 362 data[ADDL] = 0x2f; data[DATA] = 0xaa; i2c->write( addr, data, 3 ); // R40:control pad 1
shorie 2:6613e62da521 363 data[ADDL] = 0x30; data[DATA] = 0x00; i2c->write( addr, data, 3 ); // R41:control pad 2
shorie 2:6613e62da521 364 data[ADDL] = 0x31; data[DATA] = 0x08; i2c->write( addr, data, 3 ); // R42:jack detect
shorie 2:6613e62da521 365 data[ADDL] = 0x36; data[DATA] = 0x03; i2c->write( addr, data, 3 ); // R67:dejitter
shorie 2:6613e62da521 366
shorie 2:6613e62da521 367 // **** Configuration for UMB-ADAU1361 ****
shorie 2:6613e62da521 368
shorie 2:6613e62da521 369 // Additional clock setting for 96kHz
shorie 3:707608830793 370 if ( fs == Fs_48 )
shorie 3:707608830793 371 {
shorie 3:707608830793 372 data[ADDL] = 0x17; data[DATA] = 0x00;
shorie 3:707608830793 373 i2c->write( addr, data, 3 ); // R17:Converter control, CONVSR = 0
shorie 3:707608830793 374 }
shorie 2:6613e62da521 375 if ( fs == Fs_96 )
shorie 2:6613e62da521 376 {
shorie 2:6613e62da521 377 data[ADDL] = 0x17; data[DATA] = 0x06;
shorie 2:6613e62da521 378 i2c->write( addr, data, 3 ); // R17:Converter control, CONVSR = 6
shorie 2:6613e62da521 379 }
shorie 3:707608830793 380 if ( fs == Fs_32 )
shorie 3:707608830793 381 {
shorie 3:707608830793 382 data[ADDL] = 0x17; data[DATA] = 0x05;
shorie 3:707608830793 383 i2c->write( addr, data, 3 ); // R17:Converter control, CONVSR = 5
shorie 3:707608830793 384 }
shorie 2:6613e62da521 385
shorie 2:6613e62da521 386
shorie 2:6613e62da521 387 // set Master ( set clock and WS as output )
shorie 2:6613e62da521 388 data[ADDL] = 0x15; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R15:Serial Port control, MS = 6
shorie 2:6613e62da521 389
shorie 2:6613e62da521 390 // Enable ADC
shorie 2:6613e62da521 391 // bot channel ADC ON, HPF on
shorie 2:6613e62da521 392 data[ADDL] = 0x19; data[DATA] = 0x23; i2c->write( addr, data, 3 ); // R19:ADC Control
shorie 2:6613e62da521 393
shorie 2:6613e62da521 394 // Enable DAC
shorie 2:6613e62da521 395 // bot channel DAC ON
shorie 2:6613e62da521 396 data[ADDL] = 0x2a; data[DATA] = 0x03; i2c->write( addr, data, 3 ); // R36:DAC Control
shorie 2:6613e62da521 397
shorie 2:6613e62da521 398 // Left DAC mixer
shorie 2:6613e62da521 399 // L DAC to L Mixer
shorie 2:6613e62da521 400 data[ADDL] = 0x1C; data[DATA] = 0x21; i2c->write( addr, data, 3 ); // R22:MIXER 3
shorie 2:6613e62da521 401
shorie 2:6613e62da521 402 // Right DAC mixer
shorie 2:6613e62da521 403 // R DAC to R Mixer
shorie 2:6613e62da521 404 data[ADDL] = 0x1E; data[DATA] = 0x41; i2c->write( addr, data, 3 ); // R24:MIXER 4
shorie 2:6613e62da521 405
shorie 2:6613e62da521 406 // Left out mixer
shorie 2:6613e62da521 407 // L out MIX5G3 and enable
shorie 2:6613e62da521 408 data[ADDL] = 0x20; data[DATA] = 0x03; i2c->write( addr, data, 3 ); // R26:MIXER 5
shorie 2:6613e62da521 409
shorie 2:6613e62da521 410 // Right out mixer
shorie 2:6613e62da521 411 // R out MIX6G4 and enable
shorie 3:707608830793 412 data[ADDL] = 0x21; data[DATA] = 0x9; i2c->write( addr, data, 3 ); // R27:MIXER 6
shorie 2:6613e62da521 413
shorie 2:6613e62da521 414 // set input gain
shorie 3:707608830793 415 set_line_input_gain( 0, 0 ); // unmute
shorie 3:707608830793 416 set_line_output_gain( 0, 0, true ); // unmute
shorie 3:707608830793 417 set_hp_output_gain( 0, 0, true ); // unmute
shorie 1:9710fb328a08 418 }
shorie 2:6613e62da521 419
shorie 2:6613e62da521 420 #define SET_INPUT_GAIN( x ) ((x<<1)|1)
shorie 2:6613e62da521 421
shorie 2:6613e62da521 422 void umb_adau1361::set_line_input_gain(float left_gain, float right_gain, bool mute)
shorie 2:6613e62da521 423 {
shorie 2:6613e62da521 424 char data[3];
shorie 2:6613e62da521 425
shorie 2:6613e62da521 426 // **** Setup all ADAU-1361 register to reset state ****
shorie 2:6613e62da521 427
shorie 2:6613e62da521 428 data[0] = 0x40; // Upper address of register
shorie 2:6613e62da521 429
shorie 2:6613e62da521 430 // mute all at first
shorie 2:6613e62da521 431 if ( mute )
shorie 2:6613e62da521 432 {
shorie 2:6613e62da521 433 data[ADDL] = 0x0a; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R4: mixer 1 enable
shorie 2:6613e62da521 434 data[ADDL] = 0x0c; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R6: mixer 2 enable
shorie 2:6613e62da521 435 }
shorie 2:6613e62da521 436 else
shorie 2:6613e62da521 437 {
shorie 2:6613e62da521 438 int level;
shorie 2:6613e62da521 439
shorie 2:6613e62da521 440 // set left gain
shorie 3:707608830793 441 level = (left_gain+15)/3 ; // See table 31 LINNG
shorie 3:707608830793 442 level = max( level, 0 );
shorie 3:707608830793 443 level = min( level, 7 );
shorie 3:707608830793 444 data[DATA] = SET_INPUT_GAIN( level );
shorie 3:707608830793 445
shorie 2:6613e62da521 446 data[ADDL] = 0x0a; i2c->write( addr, data, 3 ); // R4: mixer 1 enable
shorie 2:6613e62da521 447
shorie 2:6613e62da521 448 // set right gain
shorie 3:707608830793 449 level = (right_gain+15)/3 ; // See table 31 LINNG
shorie 3:707608830793 450 level = max( level, 0 );
shorie 3:707608830793 451 level = min( level, 7 );
shorie 3:707608830793 452 data[DATA] = SET_INPUT_GAIN( level );
shorie 3:707608830793 453
shorie 2:6613e62da521 454 data[ADDL] = 0x0c; i2c->write( addr, data, 3 ); // R4: mixer 1 enable
shorie 2:6613e62da521 455
shorie 2:6613e62da521 456 }
shorie 2:6613e62da521 457 }
shorie 2:6613e62da521 458
shorie 2:6613e62da521 459
shorie 3:707608830793 460 #define SET_LO_GAIN( x ) ((x<<2)|2)
shorie 2:6613e62da521 461
shorie 2:6613e62da521 462 void umb_adau1361::set_line_output_gain(float left_gain, float right_gain, bool mute)
shorie 2:6613e62da521 463 {
shorie 2:6613e62da521 464 char data[3];
shorie 2:6613e62da521 465 int left, right;
shorie 2:6613e62da521 466
shorie 2:6613e62da521 467 if ( mute )
shorie 2:6613e62da521 468 {
shorie 3:707608830793 469 data[ADDL] = 0x25; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R31: LOUTVOL
shorie 3:707608830793 470 data[ADDL] = 0x26; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R32: LOUTVOL
shorie 2:6613e62da521 471 }
shorie 2:6613e62da521 472 else
shorie 2:6613e62da521 473 {
shorie 2:6613e62da521 474 left = left_gain+57;
shorie 2:6613e62da521 475 left = max( left, 0 );
shorie 2:6613e62da521 476 left = min( left, 63 );
shorie 2:6613e62da521 477
shorie 2:6613e62da521 478 right = right_gain+57;
shorie 2:6613e62da521 479 right = max( right, 0 );
shorie 2:6613e62da521 480 right = min( right, 63 );
shorie 2:6613e62da521 481
shorie 3:707608830793 482 data[ADDL] = 0x25; data[DATA] = SET_LO_GAIN(left ); i2c->write( addr, data, 3 ); // R31: LOUTVOL
shorie 3:707608830793 483 data[ADDL] = 0x26; data[DATA] = SET_LO_GAIN(right); i2c->write( addr, data, 3 ); // R32: LOUTVOL
shorie 2:6613e62da521 484
shorie 2:6613e62da521 485 }
shorie 2:6613e62da521 486 }
shorie 2:6613e62da521 487
shorie 3:707608830793 488 #define SET_HP_GAIN( x ) ((x<<2)|3)
shorie 3:707608830793 489
shorie 2:6613e62da521 490 void umb_adau1361::set_hp_output_gain(float left_gain, float right_gain, bool mute)
shorie 2:6613e62da521 491 {
shorie 2:6613e62da521 492 char data[3];
shorie 2:6613e62da521 493 int left, right;
shorie 2:6613e62da521 494
shorie 2:6613e62da521 495 if ( mute )
shorie 2:6613e62da521 496 {
shorie 3:707608830793 497 data[ADDL] = 0x23; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R29: LHPVOL
shorie 3:707608830793 498 data[ADDL] = 0x24; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R30: LHPVOL
shorie 2:6613e62da521 499 }
shorie 2:6613e62da521 500 else
shorie 2:6613e62da521 501 {
shorie 2:6613e62da521 502 left = left_gain+57;
shorie 2:6613e62da521 503 left = max( left, 0 );
shorie 2:6613e62da521 504 left = min( left, 63 );
shorie 2:6613e62da521 505
shorie 2:6613e62da521 506 right = right_gain+57;
shorie 2:6613e62da521 507 right = max( right, 0 );
shorie 2:6613e62da521 508 right = min( right, 63 );
shorie 2:6613e62da521 509
shorie 3:707608830793 510 data[ADDL] = 0x23; data[DATA] = SET_HP_GAIN(left ); i2c->write( addr, data, 3 ); // R29: LHPVOL
shorie 3:707608830793 511 data[ADDL] = 0x24; data[DATA] = SET_HP_GAIN(right); i2c->write( addr, data, 3 ); // R30: LHPVOL & HP MODE
shorie 2:6613e62da521 512
shorie 2:6613e62da521 513 }
shorie 2:6613e62da521 514 }
shorie 2:6613e62da521 515
shorie 0:5ac19c994288 516 }
shorie 0:5ac19c994288 517