First Publish. Works fine.

Dependents:   unzen_sample_lpcxpresso_4337_callbacks

Committer:
shorie
Date:
Sat Jun 11 04:53:08 2016 +0000
Revision:
17:3db85c854f56
Parent:
16:5e682712d3de
Fixed comment for sample

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shorie 0:5ac19c994288 1 /**
shorie 0:5ac19c994288 2 * \brief header file for the unzen audio frame work
shorie 0:5ac19c994288 3 * \arthur SeiichiHorie
shorie 0:5ac19c994288 4 * \date 6/Apr/2016
shorie 0:5ac19c994288 5 */
shorie 0:5ac19c994288 6
shorie 0:5ac19c994288 7 #ifndef _unzen_h_
shorie 0:5ac19c994288 8 #define _unzen_h_
shorie 0:5ac19c994288 9
shorie 0:5ac19c994288 10 #include "mbed.h"
shorie 0:5ac19c994288 11 /**
shorie 0:5ac19c994288 12 \brief audio framework name space.
shorie 0:5ac19c994288 13 */
shorie 0:5ac19c994288 14 namespace unzen
shorie 0:5ac19c994288 15 {
shorie 0:5ac19c994288 16 /**
shorie 0:5ac19c994288 17 \brief error status type.
shorie 0:5ac19c994288 18 */
shorie 0:5ac19c994288 19 enum error_type {
shorie 0:5ac19c994288 20 no_error,
shorie 0:5ac19c994288 21 memory_allocation_error
shorie 0:5ac19c994288 22 };
shorie 0:5ac19c994288 23
shorie 0:5ac19c994288 24 /**
shorie 13:845ba6aa3449 25 \brief adio frame work. Create a object and execute the \ref Framework::start() method.
shorie 13:845ba6aa3449 26
shorie 13:845ba6aa3449 27 example :
shorie 13:845ba6aa3449 28 \code
shorie 13:845ba6aa3449 29 #include "unzen.h" // audio framework include file
shorie 13:845ba6aa3449 30 #include "umb_adau1361a.h" // audio codec contoler include file
shorie 13:845ba6aa3449 31 #include "mbed.h"
shorie 13:845ba6aa3449 32
shorie 13:845ba6aa3449 33 #define CODEC_I2C_ADDR 0x38
shorie 13:845ba6aa3449 34
shorie 13:845ba6aa3449 35 DigitalOut myled1(LED1);
shorie 13:845ba6aa3449 36
shorie 13:845ba6aa3449 37
shorie 13:845ba6aa3449 38 // customer signal processing initialization call back.
shorie 13:845ba6aa3449 39 void init_callback(
shorie 13:845ba6aa3449 40 unsigned int block_size // block size [sample]
shorie 13:845ba6aa3449 41 )
shorie 13:845ba6aa3449 42 {
shorie 13:845ba6aa3449 43 // place initialization code here
shorie 13:845ba6aa3449 44 }
shorie 13:845ba6aa3449 45
shorie 13:845ba6aa3449 46
shorie 13:845ba6aa3449 47 // customer signal processing call back.
shorie 13:845ba6aa3449 48 void process_callback(
shorie 13:845ba6aa3449 49 float rx_left_buffer[], // array of the left input samples
shorie 13:845ba6aa3449 50 float rx_right_buffer[], // array of the right input samples
shorie 13:845ba6aa3449 51 float tx_left_buffer[], // place to write the left output samples
shorie 13:845ba6aa3449 52 float tx_right_buffer[], // place to write the left output samples
shorie 13:845ba6aa3449 53 unsigned int block_size // block size [sample]
shorie 13:845ba6aa3449 54 )
shorie 13:845ba6aa3449 55 {
shorie 13:845ba6aa3449 56 // Sample processing
shorie 13:845ba6aa3449 57 for ( int i=0; i<block_size; i++) // for all sample
shorie 13:845ba6aa3449 58 {
shorie 13:845ba6aa3449 59 tx_left_buffer[i] = rx_left_buffer[i]; // copy from input to output
shorie 13:845ba6aa3449 60 tx_right_buffer[i] = rx_right_buffer[i];
shorie 13:845ba6aa3449 61
shorie 13:845ba6aa3449 62 }
shorie 13:845ba6aa3449 63 }
shorie 13:845ba6aa3449 64
shorie 13:845ba6aa3449 65
shorie 13:845ba6aa3449 66
shorie 13:845ba6aa3449 67 int main()
shorie 13:845ba6aa3449 68 {
shorie 13:845ba6aa3449 69 // I2C is essential to talk with ADAU1361
shorie 13:845ba6aa3449 70 I2C i2c(SDA, SCL);
shorie 13:845ba6aa3449 71
shorie 13:845ba6aa3449 72 // create an audio codec contoler
shorie 16:5e682712d3de 73 shimabara::UMB_ADAU1361A codec(shimabara::Fs_32, i2c, CODEC_I2C_ADDR ); // Default Fs is 48kHz
shorie 16:5e682712d3de 74 // shimabara::UMB_ADAU1361A codec(shimabara::Fs_441, i2c, CODEC_I2C_ADDR );
shorie 16:5e682712d3de 75 // shimabara::UMB_ADAU1361A codec(shimabara::Fs_48, i2c, CODEC_I2C_ADDR );
shorie 16:5e682712d3de 76 // shimabara::UMB_ADAU1361A codec(shimabara::Fs_96, i2c, CODEC_I2C_ADDR );
shorie 13:845ba6aa3449 77
shorie 13:845ba6aa3449 78 // create an audio framework by singlton pattern
shorie 13:845ba6aa3449 79 unzen::Framework audio;
shorie 13:845ba6aa3449 80
shorie 17:3db85c854f56 81 // Set I3C clock to 100kHz
shorie 17:3db85c854f56 82 i2c.frequency( 100000 );
shorie 13:845ba6aa3449 83
shorie 13:845ba6aa3449 84
shorie 13:845ba6aa3449 85 // Configure the optional block size of signal processing. By default, it is 1[Sample]
shorie 13:845ba6aa3449 86 // audio.set_block_size(16);
shorie 13:845ba6aa3449 87
shorie 13:845ba6aa3449 88
shorie 13:845ba6aa3449 89 // Start the ADAU1361. Audio codec starts to generate the I2C signals
shorie 13:845ba6aa3449 90 codec.start();
shorie 13:845ba6aa3449 91
shorie 13:845ba6aa3449 92 // Start the audio framework on ARM processor.
shorie 13:845ba6aa3449 93 audio.start( init_callback, process_callback); // path the initializaiton and process call back to framework
shorie 13:845ba6aa3449 94
shorie 13:845ba6aa3449 95
shorie 13:845ba6aa3449 96 // periodically changing gain for test
shorie 13:845ba6aa3449 97 while(1)
shorie 13:845ba6aa3449 98 {
shorie 13:845ba6aa3449 99 for ( int i=-15; i<4; i++ )
shorie 13:845ba6aa3449 100 {
shorie 13:845ba6aa3449 101 codec.set_hp_output_gain( i, i );
shorie 13:845ba6aa3449 102 codec.set_line_output_gain( i, i );
shorie 13:845ba6aa3449 103 myled1 = 1;
shorie 13:845ba6aa3449 104 wait(0.2);
shorie 13:845ba6aa3449 105 myled1 = 0;
shorie 13:845ba6aa3449 106 wait(0.2);
shorie 13:845ba6aa3449 107 }
shorie 13:845ba6aa3449 108 }
shorie 13:845ba6aa3449 109 }
shorie 13:845ba6aa3449 110
shorie 13:845ba6aa3449 111
shorie 13:845ba6aa3449 112 \endcode
shorie 0:5ac19c994288 113 */
shorie 11:5f91f55065c1 114 class Framework
shorie 0:5ac19c994288 115 {
shorie 12:5e73a102d809 116 public:
shorie 0:5ac19c994288 117 /**
shorie 0:5ac19c994288 118 \constructor
shorie 0:5ac19c994288 119 \details
shorie 0:5ac19c994288 120 initialize the internal variables and set up all interrrupt / I2S related peripheral.
shorie 0:5ac19c994288 121 If needed, power up the peripheral, assign the clock and pins.
shorie 0:5ac19c994288 122 At the end of this constructor, the audio framework is ready to run, but still paused.
shorie 0:5ac19c994288 123 To start the real processing, call the \ref start method.
shorie 0:5ac19c994288 124
shorie 0:5ac19c994288 125 Note that this constructor set the block size ( interval count which audio processing
shorie 0:5ac19c994288 126 call back is called )
shorie 0:5ac19c994288 127 as 1. If it is needed to use other value, call \ref set_brock_size() method.
shorie 0:5ac19c994288 128 */
shorie 11:5f91f55065c1 129 Framework(void);
shorie 0:5ac19c994288 130
shorie 0:5ac19c994288 131 /**
shorie 0:5ac19c994288 132 \brief set the interval interrupt count for each time call back is called.
shorie 0:5ac19c994288 133 \param block_size An integer parameter > 1. If set to n, for each n interrupts, the audio call back is called.
shorie 0:5ac19c994288 134 \returns show the error status
shorie 0:5ac19c994288 135 \details
shorie 0:5ac19c994288 136 This method re-allocate the internal buffer. Then, the memory allocation error could occur. To detect the
shorie 0:5ac19c994288 137 memory allocation error, use \ref get_error() method.
shorie 0:5ac19c994288 138 */
shorie 0:5ac19c994288 139 error_type set_block_size( unsigned int new_block_size );
shorie 0:5ac19c994288 140
shorie 0:5ac19c994288 141 /**
shorie 0:5ac19c994288 142 \brief the real audio signal transfer. Trigger the I2S interrupt and call the call back.
shorie 12:5e73a102d809 143 \param init_cb initializer call back for signal processing. This is invoked only once before processing. Can be NUL
shorie 12:5e73a102d809 144 \param process_cb The call back function
shorie 0:5ac19c994288 145 \details
shorie 12:5e73a102d809 146 Set the call back function, then start the transer on I2S
shorie 12:5e73a102d809 147
shorie 12:5e73a102d809 148 Before the real data transaction on I2S, this method call init_cb(int) call back. The
shorie 12:5e73a102d809 149 parameter is block size (>0) which is set by set_block_size() method. If the init_cb is NUL,
shorie 12:5e73a102d809 150 this part is skipped.
shorie 12:5e73a102d809 151
shorie 12:5e73a102d809 152 This process_cb function is called for each time the rx buffer is filled. The call back has 5 parameters.
shorie 0:5ac19c994288 153 \li left_rx Received data from I2S rx port. Left data only.
shorie 0:5ac19c994288 154 \li right_rx Received data from I2S rx port. Right data only.
shorie 0:5ac19c994288 155 \li left_tx Buffer to fill the transmission data. This buffer mus be filled by call back. Left data only
shorie 0:5ac19c994288 156 \li right_tx Buffer to fill the transmission data. This buffer mus be filled by call back. Right data only
shorie 0:5ac19c994288 157 \li length length of above buffers.
shorie 0:5ac19c994288 158
shorie 12:5e73a102d809 159 The process call back is called for each time interrupt comes n times. Where n is the value which is specified by \ref set_block_size()
shorie 2:6613e62da521 160 function. This n is also passed to call back as above length parameter. By default, n is 1.
shorie 0:5ac19c994288 161
shorie 0:5ac19c994288 162 Note that the call back is called at interrupt context. Not the thread level context.
shorie 2:6613e62da521 163 That mean, it is better to avoid to call mbed API except the mbed-RTOS API for interrupt handler.
shorie 12:5e73a102d809 164 */
shorie 12:5e73a102d809 165 void start(
shorie 12:5e73a102d809 166 void (* init_cb ) (unsigned int),
shorie 12:5e73a102d809 167 void (* process_cb ) (float[], float[], float[], float[], unsigned int)
shorie 12:5e73a102d809 168 );
shorie 12:5e73a102d809 169
shorie 12:5e73a102d809 170
shorie 0:5ac19c994288 171 void set_pre_interrupt_callback( void (* cb ) (void));
shorie 0:5ac19c994288 172
shorie 0:5ac19c994288 173 /**
shorie 0:5ac19c994288 174 \brief Debug hook for interrupt handler.
shorie 0:5ac19c994288 175 \param cb A call back which is called at the end of I2S interrupt.
shorie 0:5ac19c994288 176 \details
shorie 0:5ac19c994288 177 Parameter cb is call at the end of the I2S interrupt. This call back can be
shorie 0:5ac19c994288 178 used to mesure the timing of interrupt by toggling the GPIO pin.
shorie 0:5ac19c994288 179
shorie 0:5ac19c994288 180 Passing 0 to cb parameter let the framwork ignore the callback.
shorie 0:5ac19c994288 181 */
shorie 0:5ac19c994288 182 void set_post_interrupt_callback( void (* cb ) (void));
shorie 0:5ac19c994288 183
shorie 0:5ac19c994288 184 /**
shorie 0:5ac19c994288 185 \brief Debug hook for processing handler.
shorie 0:5ac19c994288 186 \param cb A call back which is called at the beggining of processing.
shorie 0:5ac19c994288 187 \details
shorie 0:5ac19c994288 188 Parameter cb is call at the beggining of the signal processing. This call back can be
shorie 0:5ac19c994288 189 used to mesure the load of CPU by toggling the GPIO pin.
shorie 0:5ac19c994288 190
shorie 0:5ac19c994288 191 Passing 0 to cb parameter let the framwork ignore the callback.
shorie 0:5ac19c994288 192 */
shorie 0:5ac19c994288 193 void set_pre_process_callback( void (* cb ) (void));
shorie 0:5ac19c994288 194
shorie 0:5ac19c994288 195 /**
shorie 0:5ac19c994288 196 \brief Debug hook for processing handler.
shorie 0:5ac19c994288 197 \param cb A call back which is called at the end of processing.
shorie 0:5ac19c994288 198 \details
shorie 0:5ac19c994288 199 Parameter cb is call at the end of the signal processing. This call back can be
shorie 0:5ac19c994288 200 used to mesure the load of CPU by toggling the GPIO pin.
shorie 0:5ac19c994288 201
shorie 0:5ac19c994288 202 Passing 0 to cb parameter let the framwork ignore the callback.
shorie 0:5ac19c994288 203 */
shorie 0:5ac19c994288 204 void set_post_process_callback( void (* cb ) (void));
shorie 0:5ac19c994288 205
shorie 0:5ac19c994288 206 /**
shorie 0:5ac19c994288 207 \brief optional priority control for I2S IRQ.
shorie 0:5ac19c994288 208 \param pri Priority of IRQ.
shorie 0:5ac19c994288 209 \details
shorie 0:5ac19c994288 210 This is optional control. Usually, user doesn't need to call this method.
shorie 0:5ac19c994288 211 In case the framework has serious irq priority contention with other software,
shorie 0:5ac19c994288 212 this API help programmer to change the priority of the Unzen framework.
shorie 0:5ac19c994288 213
shorie 0:5ac19c994288 214 Value must be acceptable to CMSIS NVIC_SetPriority(). For LPC4337, it is range of 0..7. The 0 is highest priority.
shorie 0:5ac19c994288 215
shorie 0:5ac19c994288 216
shorie 0:5ac19c994288 217 By default, the framework set this priority as +2 higher than the lowest.
shorie 0:5ac19c994288 218
shorie 0:5ac19c994288 219 The priority set by this API must be higher than priority set by \ref set_process_irq_priority
shorie 0:5ac19c994288 220 */
shorie 0:5ac19c994288 221 void set_i2s_irq_priority( unsigned int pri );
shorie 0:5ac19c994288 222
shorie 0:5ac19c994288 223 /**
shorie 0:5ac19c994288 224 \brief optional priority control for Signal Processing IRQ.
shorie 0:5ac19c994288 225 \param pri Priority of IRQ.
shorie 0:5ac19c994288 226 \details
shorie 0:5ac19c994288 227 This is optional control. Usually, user doesn't need to call this method.
shorie 0:5ac19c994288 228 In case the framework has serious irq priority contention with other software,
shorie 0:5ac19c994288 229 this API help programmer to change the priority of the Unzen framework
shorie 0:5ac19c994288 230
shorie 0:5ac19c994288 231 Value must be acceptable to CMSIS NVIC_SetPriority(). For LPC4337, it is range of 0..7. The 0 is highest priority.
shorie 0:5ac19c994288 232
shorie 0:5ac19c994288 233 By default, the framework set this priority as +2 higher than the lowest.
shorie 0:5ac19c994288 234
shorie 0:5ac19c994288 235 */
shorie 0:5ac19c994288 236 void set_process_irq_priority( unsigned int pri );
shorie 12:5e73a102d809 237
shorie 12:5e73a102d809 238 private:
shorie 12:5e73a102d809 239 static Framework * _fw;
shorie 0:5ac19c994288 240 private:
shorie 10:45cbff9ee6e4 241 void (* _pre_interrupt_callback )(void);
shorie 10:45cbff9ee6e4 242 void (* _post_interrupt_callback )(void);
shorie 10:45cbff9ee6e4 243 void (* _pre_process_callback )(void);
shorie 10:45cbff9ee6e4 244 void (* _post_process_callback )(void);
shorie 0:5ac19c994288 245
shorie 10:45cbff9ee6e4 246 void (* _process_callback )( float left_in[], float right_in[], float left_out[], float right_out[], unsigned int length );
shorie 0:5ac19c994288 247
shorie 2:6613e62da521 248 // Size of the blocks ( interval of interrupt to call process_callback. 1 means every interrupt. 2 means every 2 interrupt )
shorie 10:45cbff9ee6e4 249 int _block_size;
shorie 0:5ac19c994288 250
shorie 2:6613e62da521 251 // Index for indentifying the buffer for interrupt. 0 or 1.
shorie 10:45cbff9ee6e4 252 int _buffer_index;
shorie 0:5ac19c994288 253
shorie 2:6613e62da521 254 // Index for indentifying the buffer for processing. 0 or 1.
shorie 10:45cbff9ee6e4 255 int _process_index;
shorie 2:6613e62da521 256
shorie 2:6613e62da521 257 // next transfer position in buffer
shorie 10:45cbff9ee6e4 258 int _sample_index;
shorie 0:5ac19c994288 259
shorie 0:5ac19c994288 260 // buffer for interrupt handler.
shorie 0:5ac19c994288 261 // data format is LRLR...
shorie 10:45cbff9ee6e4 262 int *_tx_int_buffer[2];
shorie 10:45cbff9ee6e4 263 int *_rx_int_buffer[2];
shorie 0:5ac19c994288 264
shorie 0:5ac19c994288 265 // buffers for passing
shorie 10:45cbff9ee6e4 266 float * _tx_left_buffer, * _tx_right_buffer;
shorie 10:45cbff9ee6e4 267 float * _rx_left_buffer, * _rx_right_buffer;
shorie 0:5ac19c994288 268
shorie 0:5ac19c994288 269 // real processing method.
shorie 10:45cbff9ee6e4 270 void _do_i2s_irq(void);
shorie 10:45cbff9ee6e4 271 void _do_process_irq(void);
shorie 0:5ac19c994288 272
shorie 0:5ac19c994288 273 // handler for NIVC
shorie 10:45cbff9ee6e4 274 static void _i2s_irq_handler();
shorie 10:45cbff9ee6e4 275 static void _process_irq_handler();
shorie 0:5ac19c994288 276 };
shorie 1:9710fb328a08 277
shorie 8:63e098b779e9 278
shorie 8:63e098b779e9 279
shorie 0:5ac19c994288 280 }
shorie 0:5ac19c994288 281
shorie 0:5ac19c994288 282 #endif