First Publish. Works fine.
Dependents: unzen_sample_LPC4088_quickstart
unzen.cpp@10:45cbff9ee6e4, 2016-05-08 (annotated)
- Committer:
- shorie
- Date:
- Sun May 08 09:52:36 2016 +0000
- Revision:
- 10:45cbff9ee6e4
- Parent:
- 9:2da6ce640691
- Child:
- 11:5f91f55065c1
Refactored naming conventions
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 | 10:45cbff9ee6e4 | 13 | _tx_int_buffer[0] = NULL; |
shorie | 10:45cbff9ee6e4 | 14 | _tx_int_buffer[1] = NULL; |
shorie | 10:45cbff9ee6e4 | 15 | _rx_int_buffer[0] = NULL; |
shorie | 10:45cbff9ee6e4 | 16 | _rx_int_buffer[1] = NULL; |
shorie | 0:5ac19c994288 | 17 | |
shorie | 10:45cbff9ee6e4 | 18 | _tx_left_buffer = NULL; |
shorie | 10:45cbff9ee6e4 | 19 | _tx_right_buffer = NULL; |
shorie | 10:45cbff9ee6e4 | 20 | _rx_left_buffer = NULL; |
shorie | 10:45cbff9ee6e4 | 21 | _rx_right_buffer = NULL; |
shorie | 0:5ac19c994288 | 22 | |
shorie | 2:6613e62da521 | 23 | // Initialize all buffer |
shorie | 10:45cbff9ee6e4 | 24 | _buffer_index = 0; |
shorie | 10:45cbff9ee6e4 | 25 | _sample_index = 0; |
shorie | 0:5ac19c994288 | 26 | |
shorie | 2:6613e62da521 | 27 | // Clear all callbacks |
shorie | 10:45cbff9ee6e4 | 28 | _pre_interrupt_callback = NULL; |
shorie | 10:45cbff9ee6e4 | 29 | _post_interrupt_callback = NULL; |
shorie | 10:45cbff9ee6e4 | 30 | _pre_process_callback = NULL; |
shorie | 10:45cbff9ee6e4 | 31 | _post_process_callback = NULL; |
shorie | 0:5ac19c994288 | 32 | |
shorie | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 56 | delete [] _tx_int_buffer[0]; |
shorie | 10:45cbff9ee6e4 | 57 | delete [] _tx_int_buffer[1]; |
shorie | 10:45cbff9ee6e4 | 58 | delete [] _rx_int_buffer[0]; |
shorie | 10:45cbff9ee6e4 | 59 | delete [] _rx_int_buffer[1]; |
shorie | 0:5ac19c994288 | 60 | |
shorie | 10:45cbff9ee6e4 | 61 | delete [] _tx_left_buffer; |
shorie | 10:45cbff9ee6e4 | 62 | delete [] _tx_right_buffer; |
shorie | 10:45cbff9ee6e4 | 63 | delete [] _rx_left_buffer; |
shorie | 10:45cbff9ee6e4 | 64 | delete [] _rx_right_buffer; |
shorie | 0:5ac19c994288 | 65 | |
shorie | 10:45cbff9ee6e4 | 66 | _block_size = new_block_size; |
shorie | 0:5ac19c994288 | 67 | |
shorie | 10:45cbff9ee6e4 | 68 | _tx_int_buffer[0] = new int[ 2 * _block_size ]; |
shorie | 10:45cbff9ee6e4 | 69 | _tx_int_buffer[1] = new int[ 2 * _block_size ]; |
shorie | 10:45cbff9ee6e4 | 70 | _rx_int_buffer[0] = new int[ 2 * _block_size ]; |
shorie | 10:45cbff9ee6e4 | 71 | _rx_int_buffer[1] = new int[ 2 * _block_size ]; |
shorie | 0:5ac19c994288 | 72 | |
shorie | 10:45cbff9ee6e4 | 73 | _tx_left_buffer = new float[ _block_size ]; |
shorie | 10:45cbff9ee6e4 | 74 | _tx_right_buffer = new float[ _block_size ]; |
shorie | 10:45cbff9ee6e4 | 75 | _rx_left_buffer = new float[ _block_size ]; |
shorie | 10:45cbff9ee6e4 | 76 | _rx_right_buffer = new float[ _block_size ]; |
shorie | 0:5ac19c994288 | 77 | |
shorie | 0:5ac19c994288 | 78 | // error check |
shorie | 10:45cbff9ee6e4 | 79 | if ( _rx_int_buffer[0] == NULL | |
shorie | 10:45cbff9ee6e4 | 80 | _rx_int_buffer[1] == NULL | |
shorie | 10:45cbff9ee6e4 | 81 | _tx_int_buffer[0] == NULL | |
shorie | 10:45cbff9ee6e4 | 82 | _tx_int_buffer[1] == NULL | |
shorie | 10:45cbff9ee6e4 | 83 | _rx_right_buffer == NULL | |
shorie | 10:45cbff9ee6e4 | 84 | _tx_right_buffer == NULL | |
shorie | 10:45cbff9ee6e4 | 85 | _rx_left_buffer == NULL | |
shorie | 10:45cbff9ee6e4 | 86 | _tx_left_buffer == NULL ) |
shorie | 0:5ac19c994288 | 87 | { // if error, release all |
shorie | 10:45cbff9ee6e4 | 88 | delete [] _tx_int_buffer[0]; |
shorie | 10:45cbff9ee6e4 | 89 | delete [] _tx_int_buffer[1]; |
shorie | 10:45cbff9ee6e4 | 90 | delete [] _rx_int_buffer[0]; |
shorie | 10:45cbff9ee6e4 | 91 | delete [] _rx_int_buffer[1]; |
shorie | 0:5ac19c994288 | 92 | |
shorie | 10:45cbff9ee6e4 | 93 | delete [] _tx_left_buffer; |
shorie | 10:45cbff9ee6e4 | 94 | delete [] _tx_right_buffer; |
shorie | 10:45cbff9ee6e4 | 95 | delete [] _rx_left_buffer; |
shorie | 10:45cbff9ee6e4 | 96 | delete [] _rx_right_buffer; |
shorie | 0:5ac19c994288 | 97 | |
shorie | 10:45cbff9ee6e4 | 98 | _tx_int_buffer[0] = NULL; |
shorie | 10:45cbff9ee6e4 | 99 | _tx_int_buffer[1] = NULL; |
shorie | 10:45cbff9ee6e4 | 100 | _rx_int_buffer[0] = NULL; |
shorie | 10:45cbff9ee6e4 | 101 | _rx_int_buffer[1] = NULL; |
shorie | 0:5ac19c994288 | 102 | |
shorie | 10:45cbff9ee6e4 | 103 | _tx_left_buffer = NULL; |
shorie | 10:45cbff9ee6e4 | 104 | _tx_right_buffer = NULL; |
shorie | 10:45cbff9ee6e4 | 105 | _rx_left_buffer = NULL; |
shorie | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 112 | for ( int i=0; i<_block_size*2; i++ ) |
shorie | 0:5ac19c994288 | 113 | { |
shorie | 0:5ac19c994288 | 114 | |
shorie | 10:45cbff9ee6e4 | 115 | _tx_int_buffer[0][i] = 0; |
shorie | 10:45cbff9ee6e4 | 116 | _tx_int_buffer[1][i] = 0; |
shorie | 10:45cbff9ee6e4 | 117 | _rx_int_buffer[0][i] = 0; |
shorie | 10:45cbff9ee6e4 | 118 | _rx_int_buffer[1][i] = 0; |
shorie | 0:5ac19c994288 | 119 | |
shorie | 0:5ac19c994288 | 120 | } |
shorie | 0:5ac19c994288 | 121 | // clear blocks |
shorie | 10:45cbff9ee6e4 | 122 | for ( int i=0; i<_block_size ; i++ ) |
shorie | 0:5ac19c994288 | 123 | { |
shorie | 0:5ac19c994288 | 124 | |
shorie | 10:45cbff9ee6e4 | 125 | _tx_left_buffer[i] = 0; |
shorie | 10:45cbff9ee6e4 | 126 | _tx_right_buffer[i] = 0; |
shorie | 10:45cbff9ee6e4 | 127 | _rx_left_buffer[i] = 0; |
shorie | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 176 | _post_process_callback = cb; |
shorie | 0:5ac19c994288 | 177 | } |
shorie | 0:5ac19c994288 | 178 | |
shorie | 10:45cbff9ee6e4 | 179 | void framework::_do_i2s_irq(void) |
shorie | 0:5ac19c994288 | 180 | { |
shorie | 2:6613e62da521 | 181 | // if needed, call pre-interrupt call back |
shorie | 10:45cbff9ee6e4 | 182 | if ( _pre_interrupt_callback ) |
shorie | 10:45cbff9ee6e4 | 183 | _pre_interrupt_callback(); |
shorie | 0:5ac19c994288 | 184 | |
shorie | 0:5ac19c994288 | 185 | // irq is handled only when the buffer is correctly allocated |
shorie | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 195 | _rx_int_buffer[_buffer_index][_sample_index] = sample; |
shorie | 2:6613e62da521 | 196 | |
shorie | 2:6613e62da521 | 197 | // copy buffer data to transmit register |
shorie | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 207 | if (_sample_index >= _block_size * 2) |
shorie | 0:5ac19c994288 | 208 | { |
shorie | 0:5ac19c994288 | 209 | // index for the signal processing |
shorie | 10:45cbff9ee6e4 | 210 | _process_index = _buffer_index; |
shorie | 2:6613e62da521 | 211 | |
shorie | 0:5ac19c994288 | 212 | // swap buffer |
shorie | 10:45cbff9ee6e4 | 213 | if ( _buffer_index == 0 ) |
shorie | 10:45cbff9ee6e4 | 214 | _buffer_index = 1; |
shorie | 2:6613e62da521 | 215 | else |
shorie | 10:45cbff9ee6e4 | 216 | _buffer_index = 0; |
shorie | 0:5ac19c994288 | 217 | |
shorie | 2:6613e62da521 | 218 | // rewind sample index |
shorie | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 227 | if ( _post_interrupt_callback ) |
shorie | 10:45cbff9ee6e4 | 228 | _post_interrupt_callback(); |
shorie | 3:707608830793 | 229 | |
shorie | 0:5ac19c994288 | 230 | } |
shorie | 0:5ac19c994288 | 231 | |
shorie | 10:45cbff9ee6e4 | 232 | void framework::_do_process_irq(void) |
shorie | 0:5ac19c994288 | 233 | { |
shorie | 2:6613e62da521 | 234 | // If needed, call the pre-process hook |
shorie | 10:45cbff9ee6e4 | 235 | if ( _pre_process_callback ) |
shorie | 10:45cbff9ee6e4 | 236 | _pre_process_callback(); |
shorie | 0:5ac19c994288 | 237 | |
shorie | 2:6613e62da521 | 238 | // Only when the process_call back is registered. |
shorie | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 247 | for ( int i=0; i<_block_size; i++ ) |
shorie | 0:5ac19c994288 | 248 | { |
shorie | 10:45cbff9ee6e4 | 249 | _rx_left_buffer[i] = _rx_int_buffer[_process_index][j++]/ -(float)INT_MIN; |
shorie | 10:45cbff9ee6e4 | 250 | _rx_right_buffer[i] = _rx_int_buffer[_process_index][j++]/ -(float)INT_MIN; |
shorie | 0:5ac19c994288 | 251 | } |
shorie | 0:5ac19c994288 | 252 | |
shorie | 10:45cbff9ee6e4 | 253 | _process_callback |
shorie | 10:45cbff9ee6e4 | 254 | ( |
shorie | 10:45cbff9ee6e4 | 255 | _rx_left_buffer, |
shorie | 10:45cbff9ee6e4 | 256 | _rx_right_buffer, |
shorie | 10:45cbff9ee6e4 | 257 | _tx_left_buffer, |
shorie | 10:45cbff9ee6e4 | 258 | _tx_right_buffer, |
shorie | 10:45cbff9ee6e4 | 259 | _block_size |
shorie | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 267 | for ( int i=0; i<_block_size; i++ ) |
shorie | 0:5ac19c994288 | 268 | { |
shorie | 10:45cbff9ee6e4 | 269 | _tx_int_buffer[_process_index][j++] = _tx_left_buffer[i] * -(float)INT_MIN ; |
shorie | 10:45cbff9ee6e4 | 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 | 10:45cbff9ee6e4 | 276 | if ( _post_process_callback ) |
shorie | 10:45cbff9ee6e4 | 277 | _post_process_callback(); |
shorie | 0:5ac19c994288 | 278 | } |
shorie | 0:5ac19c994288 | 279 | |
shorie | 10:45cbff9ee6e4 | 280 | void framework::_process_irq_handler() |
shorie | 0:5ac19c994288 | 281 | { |
shorie | 10:45cbff9ee6e4 | 282 | framework::get()->_do_process_irq(); |
shorie | 0:5ac19c994288 | 283 | } |
shorie | 0:5ac19c994288 | 284 | |
shorie | 10:45cbff9ee6e4 | 285 | void framework::_i2s_irq_handler() |
shorie | 2:6613e62da521 | 286 | { |
shorie | 10:45cbff9ee6e4 | 287 | framework::get()->_do_i2s_irq(); |
shorie | 0:5ac19c994288 | 288 | } |
shorie | 1:9710fb328a08 | 289 | |
shorie | 2:6613e62da521 | 290 | |
shorie | 2:6613e62da521 | 291 | |
shorie | 5:1cbfb7a9cd0c | 292 | |
shorie | 0:5ac19c994288 | 293 | } |
shorie | 0:5ac19c994288 | 294 |