First Publish. Works fine.
Dependents: unzen_sample_LPC4088_quickstart
unzen.cpp
00001 #include "algorithm" 00002 #include "limits.h" 00003 00004 #include "unzen.h" 00005 #include "unzen_hal.h" 00006 00007 namespace unzen 00008 { 00009 Framework::Framework () 00010 { 00011 // setup handle for the interrupt handler 00012 Framework::_fw = this; 00013 00014 // Clear all buffers 00015 _tx_int_buffer[0] = NULL; 00016 _tx_int_buffer[1] = NULL; 00017 _rx_int_buffer[0] = NULL; 00018 _rx_int_buffer[1] = NULL; 00019 00020 _tx_left_buffer = NULL; 00021 _tx_right_buffer = NULL; 00022 _rx_left_buffer = NULL; 00023 _rx_right_buffer = NULL; 00024 00025 // Initialize all buffer 00026 _buffer_index = 0; 00027 _sample_index = 0; 00028 00029 // Clear all callbacks 00030 _pre_interrupt_callback = NULL; 00031 _post_interrupt_callback = NULL; 00032 _pre_process_callback = NULL; 00033 _post_process_callback = NULL; 00034 00035 _process_callback = NULL; 00036 00037 00038 // Initialy block(buffer) size is 1. 00039 set_block_size( 1 ); 00040 00041 // Initialize I2S peripheral 00042 hal_i2s_setup(); 00043 00044 // Setup the interrupt for the I2S 00045 NVIC_SetVector(hal_get_i2s_irq_id(), (uint32_t)_i2s_irq_handler); 00046 set_i2s_irq_priority(hal_get_i2s_irq_priority_level()); 00047 NVIC_EnableIRQ(hal_get_i2s_irq_id()); 00048 00049 // Setup the interrupt for the process 00050 NVIC_SetVector(hal_get_process_irq_id(), (uint32_t)_process_irq_handler); 00051 set_process_irq_priority(hal_get_process_irq_priority_level()); 00052 NVIC_EnableIRQ(hal_get_process_irq_id()); 00053 00054 } 00055 00056 error_type Framework::set_block_size( unsigned int new_block_size ) 00057 { 00058 00059 delete [] _tx_int_buffer[0]; 00060 delete [] _tx_int_buffer[1]; 00061 delete [] _rx_int_buffer[0]; 00062 delete [] _rx_int_buffer[1]; 00063 00064 delete [] _tx_left_buffer; 00065 delete [] _tx_right_buffer; 00066 delete [] _rx_left_buffer; 00067 delete [] _rx_right_buffer; 00068 00069 _block_size = new_block_size; 00070 00071 _tx_int_buffer[0] = new int[ 2 * _block_size ]; 00072 _tx_int_buffer[1] = new int[ 2 * _block_size ]; 00073 _rx_int_buffer[0] = new int[ 2 * _block_size ]; 00074 _rx_int_buffer[1] = new int[ 2 * _block_size ]; 00075 00076 _tx_left_buffer = new float[ _block_size ]; 00077 _tx_right_buffer = new float[ _block_size ]; 00078 _rx_left_buffer = new float[ _block_size ]; 00079 _rx_right_buffer = new float[ _block_size ]; 00080 00081 // error check 00082 if ( _rx_int_buffer[0] == NULL | 00083 _rx_int_buffer[1] == NULL | 00084 _tx_int_buffer[0] == NULL | 00085 _tx_int_buffer[1] == NULL | 00086 _rx_right_buffer == NULL | 00087 _tx_right_buffer == NULL | 00088 _rx_left_buffer == NULL | 00089 _tx_left_buffer == NULL ) 00090 { // if error, release all 00091 delete [] _tx_int_buffer[0]; 00092 delete [] _tx_int_buffer[1]; 00093 delete [] _rx_int_buffer[0]; 00094 delete [] _rx_int_buffer[1]; 00095 00096 delete [] _tx_left_buffer; 00097 delete [] _tx_right_buffer; 00098 delete [] _rx_left_buffer; 00099 delete [] _rx_right_buffer; 00100 00101 _tx_int_buffer[0] = NULL; 00102 _tx_int_buffer[1] = NULL; 00103 _rx_int_buffer[0] = NULL; 00104 _rx_int_buffer[1] = NULL; 00105 00106 _tx_left_buffer = NULL; 00107 _tx_right_buffer = NULL; 00108 _rx_left_buffer = NULL; 00109 _rx_right_buffer = NULL; 00110 00111 return memory_allocation_error; 00112 } 00113 00114 // clear blocks 00115 for ( int i=0; i<_block_size*2; i++ ) 00116 { 00117 00118 _tx_int_buffer[0][i] = 0; 00119 _tx_int_buffer[1][i] = 0; 00120 _rx_int_buffer[0][i] = 0; 00121 _rx_int_buffer[1][i] = 0; 00122 00123 } 00124 // clear blocks 00125 for ( int i=0; i<_block_size ; i++ ) 00126 { 00127 00128 _tx_left_buffer[i] = 0; 00129 _tx_right_buffer[i] = 0; 00130 _rx_left_buffer[i] = 0; 00131 _rx_right_buffer[i] = 0; 00132 00133 } 00134 00135 return no_error; 00136 } 00137 00138 void Framework::start( 00139 void (* init_cb ) (unsigned int), 00140 void (* process_cb ) (float[], float[], float[], float[], unsigned int) 00141 ) 00142 { 00143 // if needed, call the initializer 00144 if ( init_cb ) 00145 init_cb( _block_size ); 00146 00147 // register the signal processing callback 00148 _process_callback = process_cb; 00149 00150 // synchronize with Word select signal, to process RX/TX as atomic timing. 00151 hal_i2s_pin_config_and_wait_ws(); 00152 hal_i2s_start(); 00153 } 00154 00155 void Framework::set_i2s_irq_priority( unsigned int pri ) 00156 { 00157 NVIC_SetPriority(hal_get_process_irq_id(), pri); // must be higher than PendSV of mbed-RTOS 00158 } 00159 00160 void Framework::set_process_irq_priority( unsigned int pri ) 00161 { 00162 NVIC_SetPriority(hal_get_i2s_irq_id(), pri); // must be higher than process IRQ 00163 } 00164 00165 void Framework::set_pre_interrupt_callback( void (* cb ) (void)) 00166 { 00167 _pre_interrupt_callback = cb; 00168 } 00169 00170 void Framework::set_post_interrupt_callback( void (* cb ) (void)) 00171 { 00172 _post_interrupt_callback = cb; 00173 } 00174 00175 void Framework::set_pre_process_callback( void (* cb ) (void)) 00176 { 00177 _pre_process_callback = cb; 00178 } 00179 00180 void Framework::set_post_process_callback( void (* cb ) (void)) 00181 { 00182 _post_process_callback = cb; 00183 } 00184 00185 void Framework::_do_i2s_irq(void) 00186 { 00187 // if needed, call pre-interrupt call back 00188 if ( _pre_interrupt_callback ) 00189 _pre_interrupt_callback(); 00190 00191 // irq is handled only when the buffer is correctly allocated 00192 if (_tx_left_buffer) 00193 { 00194 int sample; 00195 00196 // check how many data have to be transmimted per interrupt. 00197 for ( int i=0; i<hal_data_per_sample(); i++ ) 00198 { 00199 // copy received data to buffer 00200 hal_get_i2s_rx_data( sample ); 00201 _rx_int_buffer[_buffer_index][_sample_index] = sample; 00202 00203 // copy buffer data to transmit register 00204 sample = _tx_int_buffer[_buffer_index][_sample_index]; 00205 hal_put_i2s_tx_data( sample ); 00206 00207 // increment index 00208 _sample_index ++; 00209 } 00210 00211 // Implementation of the double buffer algorithm. 00212 // if buffer transfer is complete, swap the buffer 00213 if (_sample_index >= _block_size * 2) 00214 { 00215 // index for the signal processing 00216 _process_index = _buffer_index; 00217 00218 // swap buffer 00219 if ( _buffer_index == 0 ) 00220 _buffer_index = 1; 00221 else 00222 _buffer_index = 0; 00223 00224 // rewind sample index 00225 _sample_index = 0; 00226 00227 // Trigger interrupt for signal processing 00228 NVIC->STIR = hal_get_process_irq_id(); 00229 } 00230 } 00231 00232 // if needed, call post-interrupt call back 00233 if ( _post_interrupt_callback ) 00234 _post_interrupt_callback(); 00235 00236 } 00237 00238 void Framework::_do_process_irq(void) 00239 { 00240 // If needed, call the pre-process hook 00241 if ( _pre_process_callback ) 00242 _pre_process_callback(); 00243 00244 // Only when the process_call back is registered. 00245 if ( _process_callback ) 00246 { 00247 int j = 0; 00248 00249 // Format conversion. 00250 // -- premuted from LRLRLR... to LLL.., RRR... 00251 // -- convert from fixed point to floating point 00252 // -- scale down as range of [-1, 1) 00253 for ( int i=0; i<_block_size; i++ ) 00254 { 00255 _rx_left_buffer[i] = _rx_int_buffer[_process_index][j++]/ -(float)INT_MIN; 00256 _rx_right_buffer[i] = _rx_int_buffer[_process_index][j++]/ -(float)INT_MIN; 00257 } 00258 00259 _process_callback 00260 ( 00261 _rx_left_buffer, 00262 _rx_right_buffer, 00263 _tx_left_buffer, 00264 _tx_right_buffer, 00265 _block_size 00266 ); 00267 00268 // Format conversion. 00269 // -- premuted from LLL.., RRR... to LRLRLR... 00270 // -- convert from floating point to fixed point 00271 // -- scale up from range of [-1, 1) 00272 j = 0; 00273 for ( int i=0; i<_block_size; i++ ) 00274 { 00275 _tx_int_buffer[_process_index][j++] = _tx_left_buffer[i] * -(float)INT_MIN ; 00276 _tx_int_buffer[_process_index][j++] = _tx_right_buffer[i] * -(float)INT_MIN ; 00277 } 00278 00279 } 00280 00281 // if needed, call post-process callback 00282 if ( _post_process_callback ) 00283 _post_process_callback(); 00284 } 00285 00286 void Framework::_process_irq_handler() 00287 { 00288 Framework::_fw->_do_process_irq(); 00289 } 00290 00291 void Framework::_i2s_irq_handler() 00292 { 00293 Framework::_fw->_do_i2s_irq(); 00294 } 00295 00296 00297 Framework * Framework::_fw; 00298 00299 } 00300
Generated on Wed Jul 13 2022 06:48:06 by 1.7.2