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を使う方はここから読み始めると良いでしょう。
unzen.cpp@2:6613e62da521, 2016-05-03 (annotated)
- Committer:
- shorie
- Date:
- Tue May 03 01:10:32 2016 +0000
- Revision:
- 2:6613e62da521
- Parent:
- 1:9710fb328a08
- Child:
- 3:707608830793
started interrupt.
Who changed what in which revision?
User | Revision | Line number | New 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 | |
shorie | 0:5ac19c994288 | 180 | void framework::do_i2s_irq(void) |
shorie | 0:5ac19c994288 | 181 | { |
shorie | 2:6613e62da521 | 182 | // if needed, call pre-interrupt call back |
shorie | 0:5ac19c994288 | 183 | if ( pre_interrupt_callback ) |
shorie | 0:5ac19c994288 | 184 | pre_interrupt_callback(); |
shorie | 0:5ac19c994288 | 185 | |
shorie | 0:5ac19c994288 | 186 | // irq is handled only when the buffer is correctly allocated |
shorie | 0:5ac19c994288 | 187 | if (tx_left_buffer) |
shorie | 0:5ac19c994288 | 188 | { |
shorie | 0:5ac19c994288 | 189 | int sample; |
shorie | 2:6613e62da521 | 190 | |
shorie | 2:6613e62da521 | 191 | // check how many data have to be transmimted per interrupt. |
shorie | 2:6613e62da521 | 192 | for ( int i=0; i<hal_data_per_sample(); i++ ) |
shorie | 0:5ac19c994288 | 193 | { |
shorie | 2:6613e62da521 | 194 | // copy received data to buffer |
shorie | 2:6613e62da521 | 195 | hal_get_i2s_rx_data( sample ); |
shorie | 2:6613e62da521 | 196 | rx_int_buffer[buffer_index][sample_index] = sample; |
shorie | 2:6613e62da521 | 197 | |
shorie | 2:6613e62da521 | 198 | // copy buffer data to transmit register |
shorie | 2:6613e62da521 | 199 | sample = tx_int_buffer[buffer_index][sample_index]; |
shorie | 2:6613e62da521 | 200 | hal_put_i2s_tx_data( sample ); |
shorie | 2:6613e62da521 | 201 | |
shorie | 2:6613e62da521 | 202 | // increment index |
shorie | 2:6613e62da521 | 203 | sample_index ++; |
shorie | 0:5ac19c994288 | 204 | } |
shorie | 2:6613e62da521 | 205 | |
shorie | 0:5ac19c994288 | 206 | // Implementation of the double buffer algorithm. |
shorie | 0:5ac19c994288 | 207 | // if buffer transfer is complete, swap the buffer |
shorie | 2:6613e62da521 | 208 | if (sample_index > block_size * 2) |
shorie | 0:5ac19c994288 | 209 | { |
shorie | 0:5ac19c994288 | 210 | // index for the signal processing |
shorie | 0:5ac19c994288 | 211 | process_index = buffer_index; |
shorie | 2:6613e62da521 | 212 | |
shorie | 0:5ac19c994288 | 213 | // swap buffer |
shorie | 2:6613e62da521 | 214 | if ( buffer_index == 0 ) |
shorie | 2:6613e62da521 | 215 | buffer_index = 1; |
shorie | 2:6613e62da521 | 216 | else |
shorie | 2:6613e62da521 | 217 | buffer_index = 0; |
shorie | 0:5ac19c994288 | 218 | |
shorie | 2:6613e62da521 | 219 | // rewind sample index |
shorie | 2:6613e62da521 | 220 | sample_index = 0; |
shorie | 2:6613e62da521 | 221 | |
shorie | 2:6613e62da521 | 222 | // Trigger interrupt for signal processing |
shorie | 2:6613e62da521 | 223 | NVIC->STIR = hal_get_process_irq_id(); |
shorie | 0:5ac19c994288 | 224 | } |
shorie | 0:5ac19c994288 | 225 | } |
shorie | 0:5ac19c994288 | 226 | |
shorie | 2:6613e62da521 | 227 | // if needed, call post-interrupt call back |
shorie | 0:5ac19c994288 | 228 | if ( post_interrupt_callback ) |
shorie | 0:5ac19c994288 | 229 | post_interrupt_callback(); |
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 | 2:6613e62da521 | 269 | tx_int_buffer[process_index][j++] = tx_left_buffer[i] * -(float)INT_MIN ; |
shorie | 2:6613e62da521 | 270 | tx_int_buffer[process_index][j++] = tx_right_buffer[i] * -(float)INT_MIN ; |
shorie | 0:5ac19c994288 | 271 | } |
shorie | 0:5ac19c994288 | 272 | |
shorie | 0:5ac19c994288 | 273 | } |
shorie | 0:5ac19c994288 | 274 | |
shorie | 2:6613e62da521 | 275 | // if needed, call post-process callback |
shorie | 0:5ac19c994288 | 276 | if ( post_process_callback ) |
shorie | 0:5ac19c994288 | 277 | post_process_callback(); |
shorie | 0:5ac19c994288 | 278 | } |
shorie | 0:5ac19c994288 | 279 | |
shorie | 0:5ac19c994288 | 280 | void framework::process_irq_handler() |
shorie | 0:5ac19c994288 | 281 | { |
shorie | 1:9710fb328a08 | 282 | framework::get()->do_process_irq(); |
shorie | 0:5ac19c994288 | 283 | } |
shorie | 0:5ac19c994288 | 284 | |
shorie | 0:5ac19c994288 | 285 | void framework::i2s_irq_handler() |
shorie | 2:6613e62da521 | 286 | { |
shorie | 1:9710fb328a08 | 287 | framework::get()->do_i2s_irq(); |
shorie | 0:5ac19c994288 | 288 | } |
shorie | 1:9710fb328a08 | 289 | |
shorie | 2:6613e62da521 | 290 | |
shorie | 2:6613e62da521 | 291 | |
shorie | 2:6613e62da521 | 292 | |
shorie | 2:6613e62da521 | 293 | |
shorie | 2:6613e62da521 | 294 | umb_adau1361::umb_adau1361( I2C * controler, Fs_Type Fs, Addr_Type Addr ) |
shorie | 1:9710fb328a08 | 295 | { |
shorie | 1:9710fb328a08 | 296 | i2c = controler; |
shorie | 2:6613e62da521 | 297 | fs = Fs; |
shorie | 2:6613e62da521 | 298 | addr = Addr; |
shorie | 1:9710fb328a08 | 299 | } |
shorie | 0:5ac19c994288 | 300 | |
shorie | 1:9710fb328a08 | 301 | |
shorie | 2:6613e62da521 | 302 | #define DATA 2 /* data payload of register */ |
shorie | 2:6613e62da521 | 303 | #define ADDL 1 /* lower address of register */ |
shorie | 1:9710fb328a08 | 304 | void umb_adau1361::start(void) |
shorie | 1:9710fb328a08 | 305 | { |
shorie | 2:6613e62da521 | 306 | char data[8]; |
shorie | 2:6613e62da521 | 307 | |
shorie | 2:6613e62da521 | 308 | // **** Setup all ADAU-1361 register to reset state **** |
shorie | 2:6613e62da521 | 309 | |
shorie | 2:6613e62da521 | 310 | data[0] = 0x40; // Upper address of register |
shorie | 2:6613e62da521 | 311 | |
shorie | 2:6613e62da521 | 312 | // mute all at first |
shorie | 2:6613e62da521 | 313 | // may not able to write after reset, but do it avoid noise on warm start |
shorie | 2:6613e62da521 | 314 | for ( int i=0x23; i>0x27; i++ ) |
shorie | 2:6613e62da521 | 315 | data[ADDL] = i; data[DATA] = 0x02; i2c->write( addr, data, 3 ); // R29:Play HP left vol ... R33: play mono vol |
shorie | 2:6613e62da521 | 316 | |
shorie | 2:6613e62da521 | 317 | // then, start of configuration as register address order |
shorie | 2:6613e62da521 | 318 | data[ADDL] = 0x00; data[DATA] = 0x0F; i2c->write( addr, data, 3 ); // clock CTL. PLL input. Core clock enable. |
shorie | 2:6613e62da521 | 319 | |
shorie | 2:6613e62da521 | 320 | // set Fs ( clock in is 12MHz ) |
shorie | 2:6613e62da521 | 321 | if ( fs == Fs_441 ) |
shorie | 2:6613e62da521 | 322 | { |
shorie | 2:6613e62da521 | 323 | data[ADDL] = 0x02; |
shorie | 2:6613e62da521 | 324 | data[2] = 0x02; |
shorie | 2:6613e62da521 | 325 | data[3] = 0x71; |
shorie | 2:6613e62da521 | 326 | data[4] = 0x01; |
shorie | 2:6613e62da521 | 327 | data[5] = 0xDD; |
shorie | 2:6613e62da521 | 328 | data[6] = 0x19; |
shorie | 2:6613e62da521 | 329 | data[7] = 0x01; |
shorie | 2:6613e62da521 | 330 | i2c->write( addr, data, 8 ); |
shorie | 2:6613e62da521 | 331 | } |
shorie | 2:6613e62da521 | 332 | else if ( fs == Fs_48 || fs == Fs_96) |
shorie | 2:6613e62da521 | 333 | { |
shorie | 2:6613e62da521 | 334 | data[ADDL] = 0x02; |
shorie | 2:6613e62da521 | 335 | data[2] = 0x00; |
shorie | 2:6613e62da521 | 336 | data[3] = 0x7D; |
shorie | 2:6613e62da521 | 337 | data[4] = 0x00; |
shorie | 2:6613e62da521 | 338 | data[5] = 0x0C; |
shorie | 2:6613e62da521 | 339 | data[6] = 0x21; |
shorie | 2:6613e62da521 | 340 | data[7] = 0x01; |
shorie | 2:6613e62da521 | 341 | i2c->write( addr, data, 8 ); |
shorie | 2:6613e62da521 | 342 | } |
shorie | 2:6613e62da521 | 343 | |
shorie | 2:6613e62da521 | 344 | // Initialize all register as reset. |
shorie | 2:6613e62da521 | 345 | for ( int i=0x08; i>0x19; i++ ) |
shorie | 2:6613e62da521 | 346 | data[ADDL] = i; data[DATA] = 0x00; i2c->write( addr, data, 3 ); // R2:Dig Mic ... R18:Converter 1 |
shorie | 2:6613e62da521 | 347 | |
shorie | 2:6613e62da521 | 348 | data[ADDL] = 0x19; data[DATA] = 0x10; i2c->write( addr, data, 3 ); // R19:ADC Control |
shorie | 2:6613e62da521 | 349 | |
shorie | 2:6613e62da521 | 350 | for ( int i=0x1A; i>0x22; i++ ) |
shorie | 2:6613e62da521 | 351 | data[ADDL] = i; data[DATA] = 0x00; i2c->write( addr, data, 3 ); // R20:Left digital vol ... R28: play mixer mono |
shorie | 2:6613e62da521 | 352 | |
shorie | 2:6613e62da521 | 353 | for ( int i=0x23; i>0x27; i++ ) |
shorie | 2:6613e62da521 | 354 | data[ADDL] = i; data[DATA] = 0x02; i2c->write( addr, data, 3 ); // R29:Play HP left vol ... R33: play mono vol |
shorie | 2:6613e62da521 | 355 | |
shorie | 2:6613e62da521 | 356 | for ( int i=0x28; i>0x2c; i++ ) |
shorie | 2:6613e62da521 | 357 | data[ADDL] = i; data[DATA] = 0x00; i2c->write( addr, data, 3 ); // R34:play pop surpress ... R38: Dac ctl2 |
shorie | 2:6613e62da521 | 358 | |
shorie | 2:6613e62da521 | 359 | data[ADDL] = 0x2d; data[DATA] = 0xaa; i2c->write( addr, data, 3 ); // R39:serial control pad |
shorie | 2:6613e62da521 | 360 | data[ADDL] = 0x2f; data[DATA] = 0xaa; i2c->write( addr, data, 3 ); // R40:control pad 1 |
shorie | 2:6613e62da521 | 361 | data[ADDL] = 0x30; data[DATA] = 0x00; i2c->write( addr, data, 3 ); // R41:control pad 2 |
shorie | 2:6613e62da521 | 362 | data[ADDL] = 0x31; data[DATA] = 0x08; i2c->write( addr, data, 3 ); // R42:jack detect |
shorie | 2:6613e62da521 | 363 | data[ADDL] = 0x36; data[DATA] = 0x03; i2c->write( addr, data, 3 ); // R67:dejitter |
shorie | 2:6613e62da521 | 364 | |
shorie | 2:6613e62da521 | 365 | // **** Configuration for UMB-ADAU1361 **** |
shorie | 2:6613e62da521 | 366 | |
shorie | 2:6613e62da521 | 367 | // Additional clock setting for 96kHz |
shorie | 2:6613e62da521 | 368 | if ( fs == Fs_96 ) |
shorie | 2:6613e62da521 | 369 | { |
shorie | 2:6613e62da521 | 370 | data[ADDL] = 0x17; data[DATA] = 0x06; |
shorie | 2:6613e62da521 | 371 | i2c->write( addr, data, 3 ); // R17:Converter control, CONVSR = 6 |
shorie | 2:6613e62da521 | 372 | } |
shorie | 2:6613e62da521 | 373 | |
shorie | 2:6613e62da521 | 374 | |
shorie | 2:6613e62da521 | 375 | // set Master ( set clock and WS as output ) |
shorie | 2:6613e62da521 | 376 | data[ADDL] = 0x15; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R15:Serial Port control, MS = 6 |
shorie | 2:6613e62da521 | 377 | |
shorie | 2:6613e62da521 | 378 | // Enable ADC |
shorie | 2:6613e62da521 | 379 | // bot channel ADC ON, HPF on |
shorie | 2:6613e62da521 | 380 | data[ADDL] = 0x19; data[DATA] = 0x23; i2c->write( addr, data, 3 ); // R19:ADC Control |
shorie | 2:6613e62da521 | 381 | |
shorie | 2:6613e62da521 | 382 | // Enable DAC |
shorie | 2:6613e62da521 | 383 | // bot channel DAC ON |
shorie | 2:6613e62da521 | 384 | data[ADDL] = 0x2a; data[DATA] = 0x03; i2c->write( addr, data, 3 ); // R36:DAC Control |
shorie | 2:6613e62da521 | 385 | |
shorie | 2:6613e62da521 | 386 | // Left DAC mixer |
shorie | 2:6613e62da521 | 387 | // L DAC to L Mixer |
shorie | 2:6613e62da521 | 388 | data[ADDL] = 0x1C; data[DATA] = 0x21; i2c->write( addr, data, 3 ); // R22:MIXER 3 |
shorie | 2:6613e62da521 | 389 | |
shorie | 2:6613e62da521 | 390 | // Right DAC mixer |
shorie | 2:6613e62da521 | 391 | // R DAC to R Mixer |
shorie | 2:6613e62da521 | 392 | data[ADDL] = 0x1E; data[DATA] = 0x41; i2c->write( addr, data, 3 ); // R24:MIXER 4 |
shorie | 2:6613e62da521 | 393 | |
shorie | 2:6613e62da521 | 394 | // Left out mixer |
shorie | 2:6613e62da521 | 395 | // L out MIX5G3 and enable |
shorie | 2:6613e62da521 | 396 | data[ADDL] = 0x20; data[DATA] = 0x03; i2c->write( addr, data, 3 ); // R26:MIXER 5 |
shorie | 2:6613e62da521 | 397 | |
shorie | 2:6613e62da521 | 398 | // Right out mixer |
shorie | 2:6613e62da521 | 399 | // R out MIX6G4 and enable |
shorie | 2:6613e62da521 | 400 | data[ADDL] = 0x21; data[DATA] = 0x8; i2c->write( addr, data, 3 ); // R27:MIXER 6 |
shorie | 2:6613e62da521 | 401 | |
shorie | 2:6613e62da521 | 402 | // set input gain |
shorie | 2:6613e62da521 | 403 | set_line_input_gain( 0, 0 ); |
shorie | 1:9710fb328a08 | 404 | } |
shorie | 2:6613e62da521 | 405 | |
shorie | 2:6613e62da521 | 406 | #define SET_INPUT_GAIN( x ) ((x<<1)|1) |
shorie | 2:6613e62da521 | 407 | |
shorie | 2:6613e62da521 | 408 | void umb_adau1361::set_line_input_gain(float left_gain, float right_gain, bool mute) |
shorie | 2:6613e62da521 | 409 | { |
shorie | 2:6613e62da521 | 410 | char data[3]; |
shorie | 2:6613e62da521 | 411 | |
shorie | 2:6613e62da521 | 412 | // **** Setup all ADAU-1361 register to reset state **** |
shorie | 2:6613e62da521 | 413 | |
shorie | 2:6613e62da521 | 414 | data[0] = 0x40; // Upper address of register |
shorie | 2:6613e62da521 | 415 | |
shorie | 2:6613e62da521 | 416 | // mute all at first |
shorie | 2:6613e62da521 | 417 | if ( mute ) |
shorie | 2:6613e62da521 | 418 | { |
shorie | 2:6613e62da521 | 419 | data[ADDL] = 0x0a; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R4: mixer 1 enable |
shorie | 2:6613e62da521 | 420 | data[ADDL] = 0x0c; data[DATA] = 0x01; i2c->write( addr, data, 3 ); // R6: mixer 2 enable |
shorie | 2:6613e62da521 | 421 | } |
shorie | 2:6613e62da521 | 422 | else |
shorie | 2:6613e62da521 | 423 | { |
shorie | 2:6613e62da521 | 424 | int level; |
shorie | 2:6613e62da521 | 425 | |
shorie | 2:6613e62da521 | 426 | // set left gain |
shorie | 2:6613e62da521 | 427 | level = -15; |
shorie | 2:6613e62da521 | 428 | data[DATA] = SET_INPUT_GAIN( 7 ); |
shorie | 2:6613e62da521 | 429 | for ( int i =0; i <= 7; i++ ) |
shorie | 2:6613e62da521 | 430 | { |
shorie | 2:6613e62da521 | 431 | if ( level >= left_gain ) |
shorie | 2:6613e62da521 | 432 | { |
shorie | 2:6613e62da521 | 433 | data[DATA] = SET_INPUT_GAIN( i ); |
shorie | 2:6613e62da521 | 434 | break; |
shorie | 2:6613e62da521 | 435 | } |
shorie | 2:6613e62da521 | 436 | level += 3; |
shorie | 2:6613e62da521 | 437 | } |
shorie | 2:6613e62da521 | 438 | data[ADDL] = 0x0a; i2c->write( addr, data, 3 ); // R4: mixer 1 enable |
shorie | 2:6613e62da521 | 439 | |
shorie | 2:6613e62da521 | 440 | // set right gain |
shorie | 2:6613e62da521 | 441 | level = -15; |
shorie | 2:6613e62da521 | 442 | data[DATA] = SET_INPUT_GAIN( 7 ); |
shorie | 2:6613e62da521 | 443 | for ( int i =0; i <= 7; i++ ) |
shorie | 2:6613e62da521 | 444 | { |
shorie | 2:6613e62da521 | 445 | if ( level >= right_gain ) |
shorie | 2:6613e62da521 | 446 | { |
shorie | 2:6613e62da521 | 447 | data[DATA] = SET_INPUT_GAIN( i ); |
shorie | 2:6613e62da521 | 448 | break; |
shorie | 2:6613e62da521 | 449 | } |
shorie | 2:6613e62da521 | 450 | level += 3; |
shorie | 2:6613e62da521 | 451 | } |
shorie | 2:6613e62da521 | 452 | data[ADDL] = 0x0c; i2c->write( addr, data, 3 ); // R4: mixer 1 enable |
shorie | 2:6613e62da521 | 453 | |
shorie | 2:6613e62da521 | 454 | } |
shorie | 2:6613e62da521 | 455 | } |
shorie | 2:6613e62da521 | 456 | |
shorie | 2:6613e62da521 | 457 | |
shorie | 2:6613e62da521 | 458 | #define SET_HP_GAIN( x ) ((x<<2)|3) |
shorie | 2:6613e62da521 | 459 | |
shorie | 2:6613e62da521 | 460 | void umb_adau1361::set_line_output_gain(float left_gain, float right_gain, bool mute) |
shorie | 2:6613e62da521 | 461 | { |
shorie | 2:6613e62da521 | 462 | char data[3]; |
shorie | 2:6613e62da521 | 463 | int left, right; |
shorie | 2:6613e62da521 | 464 | |
shorie | 2:6613e62da521 | 465 | if ( mute ) |
shorie | 2:6613e62da521 | 466 | { |
shorie | 2:6613e62da521 | 467 | data[ADDL] = 0x25; data[DATA] = 0x01; i2c->write( addr, data, 1 ); // R31: LOUTVOL |
shorie | 2:6613e62da521 | 468 | data[ADDL] = 0x26; data[DATA] = 0x01; i2c->write( addr, data, 1 ); // R32: LOUTVOL |
shorie | 2:6613e62da521 | 469 | } |
shorie | 2:6613e62da521 | 470 | else |
shorie | 2:6613e62da521 | 471 | { |
shorie | 2:6613e62da521 | 472 | left = left_gain+57; |
shorie | 2:6613e62da521 | 473 | left = max( left, 0 ); |
shorie | 2:6613e62da521 | 474 | left = min( left, 63 ); |
shorie | 2:6613e62da521 | 475 | |
shorie | 2:6613e62da521 | 476 | right = right_gain+57; |
shorie | 2:6613e62da521 | 477 | right = max( right, 0 ); |
shorie | 2:6613e62da521 | 478 | right = min( right, 63 ); |
shorie | 2:6613e62da521 | 479 | |
shorie | 2:6613e62da521 | 480 | data[ADDL] = 0x25; data[DATA] = SET_HP_GAIN(left ); i2c->write( addr, data, 1 ); // R31: LOUTVOL |
shorie | 2:6613e62da521 | 481 | data[ADDL] = 0x26; data[DATA] = SET_HP_GAIN(right); i2c->write( addr, data, 1 ); // R32: LOUTVOL |
shorie | 2:6613e62da521 | 482 | |
shorie | 2:6613e62da521 | 483 | } |
shorie | 2:6613e62da521 | 484 | } |
shorie | 2:6613e62da521 | 485 | |
shorie | 2:6613e62da521 | 486 | void umb_adau1361::set_hp_output_gain(float left_gain, float right_gain, bool mute) |
shorie | 2:6613e62da521 | 487 | { |
shorie | 2:6613e62da521 | 488 | char data[3]; |
shorie | 2:6613e62da521 | 489 | int left, right; |
shorie | 2:6613e62da521 | 490 | |
shorie | 2:6613e62da521 | 491 | if ( mute ) |
shorie | 2:6613e62da521 | 492 | { |
shorie | 2:6613e62da521 | 493 | data[ADDL] = 0x23; data[DATA] = 0x01; i2c->write( addr, data, 1 ); // R29: LHPVOL |
shorie | 2:6613e62da521 | 494 | data[ADDL] = 0x24; data[DATA] = 0x01; i2c->write( addr, data, 1 ); // R30: LHPVOL |
shorie | 2:6613e62da521 | 495 | } |
shorie | 2:6613e62da521 | 496 | else |
shorie | 2:6613e62da521 | 497 | { |
shorie | 2:6613e62da521 | 498 | left = left_gain+57; |
shorie | 2:6613e62da521 | 499 | left = max( left, 0 ); |
shorie | 2:6613e62da521 | 500 | left = min( left, 63 ); |
shorie | 2:6613e62da521 | 501 | |
shorie | 2:6613e62da521 | 502 | right = right_gain+57; |
shorie | 2:6613e62da521 | 503 | right = max( right, 0 ); |
shorie | 2:6613e62da521 | 504 | right = min( right, 63 ); |
shorie | 2:6613e62da521 | 505 | |
shorie | 2:6613e62da521 | 506 | data[ADDL] = 0x23; data[DATA] = SET_HP_GAIN(left ); i2c->write( addr, data, 1 ); // R29: LHPVOL |
shorie | 2:6613e62da521 | 507 | data[ADDL] = 0x24; data[DATA] = SET_HP_GAIN(right); i2c->write( addr, data, 1 ); // R30: LHPVOL |
shorie | 2:6613e62da521 | 508 | |
shorie | 2:6613e62da521 | 509 | } |
shorie | 2:6613e62da521 | 510 | } |
shorie | 2:6613e62da521 | 511 | |
shorie | 0:5ac19c994288 | 512 | } |
shorie | 0:5ac19c994288 | 513 |