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 Apr 12 05:51:45 2016 +0000
Revision:
1:9710fb328a08
Parent:
0:5ac19c994288
Child:
2:6613e62da521
added umb-adau1361 support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shorie 0:5ac19c994288 1 #include "unzen.h"
shorie 0:5ac19c994288 2 #include "limits.h"
shorie 0:5ac19c994288 3 #include "unzen_hal.h"
shorie 0:5ac19c994288 4
shorie 0:5ac19c994288 5 namespace unzen
shorie 0:5ac19c994288 6 {
shorie 0:5ac19c994288 7 framework::framework()
shorie 0:5ac19c994288 8 {
shorie 0:5ac19c994288 9
shorie 0:5ac19c994288 10 tx_int_buffer[0] = NULL;
shorie 0:5ac19c994288 11 tx_int_buffer[1] = NULL;
shorie 0:5ac19c994288 12 rx_int_buffer[0] = NULL;
shorie 0:5ac19c994288 13 rx_int_buffer[1] = NULL;
shorie 0:5ac19c994288 14
shorie 0:5ac19c994288 15 tx_left_buffer = NULL;
shorie 0:5ac19c994288 16 tx_right_buffer = NULL;
shorie 0:5ac19c994288 17 rx_left_buffer = NULL;
shorie 0:5ac19c994288 18 rx_right_buffer = NULL;
shorie 0:5ac19c994288 19
shorie 0:5ac19c994288 20 buffer_index = 0;
shorie 0:5ac19c994288 21 tx_sample_index = 0;
shorie 0:5ac19c994288 22 rx_sample_index = 0;
shorie 0:5ac19c994288 23
shorie 0:5ac19c994288 24 pre_interrupt_callback = NULL;
shorie 0:5ac19c994288 25 post_interrupt_callback = NULL;
shorie 0:5ac19c994288 26 pre_process_callback = NULL;
shorie 0:5ac19c994288 27 post_process_callback = NULL;
shorie 0:5ac19c994288 28
shorie 0:5ac19c994288 29 process_callback = NULL;
shorie 0:5ac19c994288 30
shorie 0:5ac19c994288 31 set_block_size( 1 );
shorie 0:5ac19c994288 32
shorie 0:5ac19c994288 33 hal_i2s_setup();
shorie 0:5ac19c994288 34
shorie 0:5ac19c994288 35 NVIC_SetVector(hal_get_i2s_irq_id(), (uint32_t)i2s_irq_handler);
shorie 0:5ac19c994288 36 NVIC_EnableIRQ(hal_get_i2s_irq_id());
shorie 0:5ac19c994288 37
shorie 0:5ac19c994288 38 NVIC_SetVector(hal_get_process_irq_id(), (uint32_t)process_irq_handler);
shorie 0:5ac19c994288 39 NVIC_EnableIRQ(hal_get_process_irq_id());
shorie 0:5ac19c994288 40
shorie 0:5ac19c994288 41 // to enable block processing, I2S IRQ priority must be higher than process IRQ
shorie 0:5ac19c994288 42 set_i2s_irq_priority(hal_get_lowest_priority_level() - 1);
shorie 0:5ac19c994288 43 set_process_irq_priority(hal_get_lowest_priority_level() - 2);
shorie 0:5ac19c994288 44
shorie 0:5ac19c994288 45 }
shorie 0:5ac19c994288 46
shorie 0:5ac19c994288 47 error_type framework::set_block_size( unsigned int new_block_size )
shorie 0:5ac19c994288 48 {
shorie 0:5ac19c994288 49
shorie 0:5ac19c994288 50 delete [] tx_int_buffer[0];
shorie 0:5ac19c994288 51 delete [] tx_int_buffer[1];
shorie 0:5ac19c994288 52 delete [] rx_int_buffer[0];
shorie 0:5ac19c994288 53 delete [] rx_int_buffer[1];
shorie 0:5ac19c994288 54
shorie 0:5ac19c994288 55 delete [] tx_left_buffer;
shorie 0:5ac19c994288 56 delete [] tx_right_buffer;
shorie 0:5ac19c994288 57 delete [] rx_left_buffer;
shorie 0:5ac19c994288 58 delete [] rx_right_buffer;
shorie 0:5ac19c994288 59
shorie 0:5ac19c994288 60 block_size = new_block_size;
shorie 0:5ac19c994288 61
shorie 0:5ac19c994288 62 tx_int_buffer[0] = new int[ 2 * block_size ];
shorie 0:5ac19c994288 63 tx_int_buffer[1] = new int[ 2 * block_size ];
shorie 0:5ac19c994288 64 rx_int_buffer[0] = new int[ 2 * block_size ];
shorie 0:5ac19c994288 65 rx_int_buffer[1] = new int[ 2 * block_size ];
shorie 0:5ac19c994288 66
shorie 0:5ac19c994288 67 tx_left_buffer = new float[ block_size ];
shorie 0:5ac19c994288 68 tx_right_buffer = new float[ block_size ];
shorie 0:5ac19c994288 69 rx_left_buffer = new float[ block_size ];
shorie 0:5ac19c994288 70 rx_right_buffer = new float[ block_size ];
shorie 0:5ac19c994288 71
shorie 0:5ac19c994288 72 // error check
shorie 0:5ac19c994288 73 if ( rx_int_buffer[0] == NULL |
shorie 0:5ac19c994288 74 rx_int_buffer[1] == NULL |
shorie 0:5ac19c994288 75 tx_int_buffer[0] == NULL |
shorie 0:5ac19c994288 76 tx_int_buffer[1] == NULL |
shorie 0:5ac19c994288 77 rx_right_buffer == NULL |
shorie 0:5ac19c994288 78 tx_right_buffer == NULL |
shorie 0:5ac19c994288 79 rx_left_buffer == NULL |
shorie 0:5ac19c994288 80 tx_left_buffer == NULL )
shorie 0:5ac19c994288 81 { // if error, release all
shorie 0:5ac19c994288 82 delete [] tx_int_buffer[0];
shorie 0:5ac19c994288 83 delete [] tx_int_buffer[1];
shorie 0:5ac19c994288 84 delete [] rx_int_buffer[0];
shorie 0:5ac19c994288 85 delete [] rx_int_buffer[1];
shorie 0:5ac19c994288 86
shorie 0:5ac19c994288 87 delete [] tx_left_buffer;
shorie 0:5ac19c994288 88 delete [] tx_right_buffer;
shorie 0:5ac19c994288 89 delete [] rx_left_buffer;
shorie 0:5ac19c994288 90 delete [] rx_right_buffer;
shorie 0:5ac19c994288 91
shorie 0:5ac19c994288 92 tx_int_buffer[0] = NULL;
shorie 0:5ac19c994288 93 tx_int_buffer[1] = NULL;
shorie 0:5ac19c994288 94 rx_int_buffer[0] = NULL;
shorie 0:5ac19c994288 95 rx_int_buffer[1] = NULL;
shorie 0:5ac19c994288 96
shorie 0:5ac19c994288 97 tx_left_buffer = NULL;
shorie 0:5ac19c994288 98 tx_right_buffer = NULL;
shorie 0:5ac19c994288 99 rx_left_buffer = NULL;
shorie 0:5ac19c994288 100 rx_right_buffer = NULL;
shorie 0:5ac19c994288 101
shorie 0:5ac19c994288 102 return memory_allocation_error;
shorie 0:5ac19c994288 103 }
shorie 0:5ac19c994288 104
shorie 0:5ac19c994288 105 // clear blocks
shorie 0:5ac19c994288 106 for ( int i=0; i<block_size*2; i++ )
shorie 0:5ac19c994288 107 {
shorie 0:5ac19c994288 108
shorie 0:5ac19c994288 109 tx_int_buffer[0][i] = 0;
shorie 0:5ac19c994288 110 tx_int_buffer[1][i] = 0;
shorie 0:5ac19c994288 111 rx_int_buffer[0][i] = 0;
shorie 0:5ac19c994288 112 rx_int_buffer[1][i] = 0;
shorie 0:5ac19c994288 113
shorie 0:5ac19c994288 114 }
shorie 0:5ac19c994288 115 // clear blocks
shorie 0:5ac19c994288 116 for ( int i=0; i<block_size ; i++ )
shorie 0:5ac19c994288 117 {
shorie 0:5ac19c994288 118
shorie 0:5ac19c994288 119 tx_left_buffer[i] = 0;
shorie 0:5ac19c994288 120 tx_right_buffer[i] = 0;
shorie 0:5ac19c994288 121 rx_left_buffer[i] = 0;
shorie 0:5ac19c994288 122 rx_right_buffer[i] = 0;
shorie 0:5ac19c994288 123
shorie 0:5ac19c994288 124 }
shorie 0:5ac19c994288 125
shorie 0:5ac19c994288 126 return no_error;
shorie 0:5ac19c994288 127 }
shorie 0:5ac19c994288 128
shorie 0:5ac19c994288 129 void framework::start()
shorie 0:5ac19c994288 130 {
shorie 1:9710fb328a08 131 hal_i2s_pin_config_and_wait_ws();
shorie 0:5ac19c994288 132 hal_i2s_start();
shorie 0:5ac19c994288 133 }
shorie 0:5ac19c994288 134
shorie 0:5ac19c994288 135 void framework::set_i2s_irq_priority( unsigned int pri )
shorie 0:5ac19c994288 136 {
shorie 0:5ac19c994288 137 NVIC_SetPriority(hal_get_process_irq_id(), pri); // must be higher than PendSV of mbed-RTOS
shorie 0:5ac19c994288 138
shorie 0:5ac19c994288 139 }
shorie 0:5ac19c994288 140
shorie 0:5ac19c994288 141 void framework::set_process_irq_priority( unsigned int pri )
shorie 0:5ac19c994288 142 {
shorie 0:5ac19c994288 143 NVIC_SetPriority(hal_get_i2s_irq_id(), pri); // must be higher than process IRQ
shorie 0:5ac19c994288 144
shorie 0:5ac19c994288 145 }
shorie 0:5ac19c994288 146
shorie 0:5ac19c994288 147 void framework::set_process_callback( void (* cb ) (float[], float[], float[], float[], unsigned int))
shorie 0:5ac19c994288 148 {
shorie 0:5ac19c994288 149 process_callback = cb;
shorie 0:5ac19c994288 150 }
shorie 0:5ac19c994288 151
shorie 0:5ac19c994288 152 void framework::set_pre_interrupt_callback( void (* cb ) (void))
shorie 0:5ac19c994288 153 {
shorie 0:5ac19c994288 154 pre_interrupt_callback = cb;
shorie 0:5ac19c994288 155 }
shorie 0:5ac19c994288 156
shorie 0:5ac19c994288 157 void framework::set_post_interrupt_callback( void (* cb ) (void))
shorie 0:5ac19c994288 158 {
shorie 0:5ac19c994288 159 post_interrupt_callback = cb;
shorie 0:5ac19c994288 160 }
shorie 0:5ac19c994288 161
shorie 0:5ac19c994288 162 void framework::set_pre_process_callback( void (* cb ) (void))
shorie 0:5ac19c994288 163 {
shorie 0:5ac19c994288 164 pre_process_callback = cb;
shorie 0:5ac19c994288 165 }
shorie 0:5ac19c994288 166
shorie 0:5ac19c994288 167 void framework::set_post_process_callback( void (* cb ) (void))
shorie 0:5ac19c994288 168 {
shorie 0:5ac19c994288 169 post_process_callback = cb;
shorie 0:5ac19c994288 170 }
shorie 0:5ac19c994288 171
shorie 0:5ac19c994288 172
shorie 0:5ac19c994288 173 void framework::do_i2s_irq(void)
shorie 0:5ac19c994288 174 {
shorie 0:5ac19c994288 175 if ( pre_interrupt_callback )
shorie 0:5ac19c994288 176 pre_interrupt_callback();
shorie 0:5ac19c994288 177
shorie 0:5ac19c994288 178 // irq is handled only when the buffer is correctly allocated
shorie 0:5ac19c994288 179 if (tx_left_buffer)
shorie 0:5ac19c994288 180 {
shorie 0:5ac19c994288 181 int sample;
shorie 0:5ac19c994288 182 // check how many data have to be transmimt per interrupt.
shorie 0:5ac19c994288 183 if ( hal_data_per_sample() >0 ) // In case single or multiple word per interrupt
shorie 0:5ac19c994288 184 {
shorie 0:5ac19c994288 185 for ( int i=0; i>hal_data_per_sample(); i++ )
shorie 0:5ac19c994288 186 {
shorie 0:5ac19c994288 187 // copy received data to buffer
shorie 0:5ac19c994288 188 hal_get_i2s_rx_data( sample );
shorie 0:5ac19c994288 189 rx_int_buffer[buffer_index][rx_sample_index++] = sample;
shorie 0:5ac19c994288 190 // copy buffer data to transmit register
shorie 0:5ac19c994288 191 hal_set_i2s_tx_data( tx_int_buffer[buffer_index][rx_sample_index++] );
shorie 0:5ac19c994288 192 }
shorie 0:5ac19c994288 193 }
shorie 0:5ac19c994288 194 else // if the hal_data_per_smple() is 0, the data have to push multiple time.
shorie 0:5ac19c994288 195 {
shorie 0:5ac19c994288 196 if ( hal_get_i2s_rx_data( sample ) )
shorie 0:5ac19c994288 197 {
shorie 0:5ac19c994288 198 // data have to be pushed to buffer only when the hal_get_i2s_rx_data() returns non-zero
shorie 0:5ac19c994288 199 rx_int_buffer[buffer_index][rx_sample_index++] = sample;
shorie 0:5ac19c994288 200 }
shorie 0:5ac19c994288 201 if ( hal_set_i2s_tx_data( tx_int_buffer[buffer_index][tx_sample_index] ))
shorie 0:5ac19c994288 202 // pointer can be updated only when hal_set_i2s_tx_data() returns non_zero.
shorie 0:5ac19c994288 203 tx_sample_index ++;
shorie 0:5ac19c994288 204
shorie 0:5ac19c994288 205 }
shorie 0:5ac19c994288 206 // Implementation of the double buffer algorithm.
shorie 0:5ac19c994288 207 // if buffer transfer is complete, swap the buffer
shorie 0:5ac19c994288 208 if (rx_sample_index > block_size * 2 & rx_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 0:5ac19c994288 212 // swap buffer
shorie 0:5ac19c994288 213 buffer_index = 1 - buffer_index ; // reverse 1 <-> 0
shorie 0:5ac19c994288 214 tx_sample_index = 0;
shorie 0:5ac19c994288 215 rx_sample_index = 0;
shorie 0:5ac19c994288 216
shorie 0:5ac19c994288 217 NVIC->STIR = hal_get_process_irq_id(); // Trigger interrupt for signal processing
shorie 0:5ac19c994288 218 }
shorie 0:5ac19c994288 219 }
shorie 0:5ac19c994288 220
shorie 0:5ac19c994288 221 if ( post_interrupt_callback )
shorie 0:5ac19c994288 222 post_interrupt_callback();
shorie 0:5ac19c994288 223 }
shorie 0:5ac19c994288 224
shorie 0:5ac19c994288 225 void framework::do_process_irq(void)
shorie 0:5ac19c994288 226 {
shorie 0:5ac19c994288 227 if ( pre_process_callback )
shorie 0:5ac19c994288 228 pre_process_callback();
shorie 0:5ac19c994288 229
shorie 0:5ac19c994288 230 if ( process_callback )
shorie 0:5ac19c994288 231 {
shorie 0:5ac19c994288 232 int j = 0;
shorie 0:5ac19c994288 233
shorie 0:5ac19c994288 234 // convert from fixed point to floating point
shorie 0:5ac19c994288 235 // also scale down
shorie 0:5ac19c994288 236 for ( int i=0; i<block_size; i++ )
shorie 0:5ac19c994288 237 {
shorie 0:5ac19c994288 238 rx_left_buffer[i] = rx_int_buffer[process_index][j++]/ -(float)INT_MIN;
shorie 0:5ac19c994288 239 rx_right_buffer[i] = rx_int_buffer[process_index][j++]/ -(float)INT_MIN;
shorie 0:5ac19c994288 240 }
shorie 0:5ac19c994288 241
shorie 1:9710fb328a08 242 process_callback
shorie 1:9710fb328a08 243 (
shorie 0:5ac19c994288 244 rx_left_buffer,
shorie 0:5ac19c994288 245 rx_right_buffer,
shorie 0:5ac19c994288 246 tx_left_buffer,
shorie 0:5ac19c994288 247 tx_right_buffer,
shorie 0:5ac19c994288 248 block_size
shorie 1:9710fb328a08 249 );
shorie 0:5ac19c994288 250
shorie 0:5ac19c994288 251 // convert from floating point to fixed point
shorie 0:5ac19c994288 252 // also scale up
shorie 0:5ac19c994288 253 j = 0;
shorie 0:5ac19c994288 254 for ( int i=0; i<block_size; i++ )
shorie 0:5ac19c994288 255 {
shorie 0:5ac19c994288 256 tx_int_buffer[process_index][j++] = - tx_left_buffer[i] * INT_MIN ;
shorie 0:5ac19c994288 257 tx_int_buffer[process_index][j++] = - tx_right_buffer[i] * INT_MIN ;
shorie 0:5ac19c994288 258 }
shorie 0:5ac19c994288 259
shorie 0:5ac19c994288 260 }
shorie 0:5ac19c994288 261
shorie 0:5ac19c994288 262 if ( post_process_callback )
shorie 0:5ac19c994288 263 post_process_callback();
shorie 0:5ac19c994288 264 }
shorie 0:5ac19c994288 265
shorie 0:5ac19c994288 266 void framework::process_irq_handler()
shorie 0:5ac19c994288 267 {
shorie 1:9710fb328a08 268 framework::get()->do_process_irq();
shorie 0:5ac19c994288 269 }
shorie 0:5ac19c994288 270
shorie 0:5ac19c994288 271 void framework::i2s_irq_handler()
shorie 0:5ac19c994288 272 {
shorie 1:9710fb328a08 273 framework::get()->do_i2s_irq();
shorie 0:5ac19c994288 274 }
shorie 1:9710fb328a08 275
shorie 1:9710fb328a08 276 umb_adau1361::umb_adau1361( I2C *controler )
shorie 1:9710fb328a08 277 {
shorie 1:9710fb328a08 278 i2c = controler;
shorie 1:9710fb328a08 279 }
shorie 0:5ac19c994288 280
shorie 1:9710fb328a08 281
shorie 1:9710fb328a08 282 void umb_adau1361::start(void)
shorie 1:9710fb328a08 283 {
shorie 1:9710fb328a08 284 }
shorie 0:5ac19c994288 285 }
shorie 0:5ac19c994288 286