Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: temp X_NUCLEO_CCA01M1 X_NUCLEO_CCA01M1 X_NUCLEO_CCA02M1
I2S.cpp
00001 #include "drivers/I2S.h" 00002 #include "platform/mbed_critical.h" 00003 #include "platform/mbed_assert.h" 00004 00005 #if DEVICE_I2S 00006 00007 I2S* I2S::_owner = NULL; 00008 SingletonPtr<PlatformMutex> I2S::_mutex; // intentional class level lock! 00009 00010 events::EventQueue I2S::i2s_bh_queue; 00011 00012 void I2S::lock() { 00013 #if defined(NDEBUG) || !defined(MBED_CONF_RTOS_PRESENT) 00014 _mutex->lock(); // intentional class level lock! 00015 #else 00016 osStatus ret = _mutex->lock(); // intentional class level lock! 00017 MBED_ASSERT(ret == osOK); 00018 #endif 00019 } 00020 00021 void I2S::unlock() { 00022 #if defined(NDEBUG) || !defined(MBED_CONF_RTOS_PRESENT) 00023 _mutex->unlock(); // intentional class level lock! 00024 #else 00025 osStatus ret = _mutex->unlock(); // intentional class level lock! 00026 MBED_ASSERT(ret == osOK); 00027 #endif 00028 } 00029 00030 I2S::I2S(PinName dpin, PinName clk, PinName wsel, PinName fdpin, PinName mck) : 00031 _i2s(), 00032 _irq_tx(this), _irq_rx(this), 00033 _priority(MEDIUM), 00034 _dbits(16), 00035 _fbits(16), 00036 _polarity(0), 00037 _protocol(PHILIPS), 00038 _mode(MASTER_TX), 00039 _circular(false), 00040 _hz(44100) { 00041 lock(); 00042 /* Init instance */ 00043 i2s_init(&_i2s, dpin, clk, wsel, fdpin, mck, _mode); 00044 acquire(); 00045 unlock(); 00046 } 00047 00048 int I2S::format(int dbits, int fbits, int polarity) { 00049 lock(); 00050 if (i2s_active(&_i2s)) { 00051 unlock(); 00052 return -1; 00053 } 00054 _dbits = dbits; 00055 _fbits = fbits; 00056 _polarity = polarity; 00057 I2S::_owner = NULL; // Not that elegant, but works. rmeyer 00058 acquire(); 00059 unlock(); 00060 return 0; 00061 } 00062 00063 int I2S::audio_frequency(unsigned int hz) { 00064 lock(); 00065 if (i2s_active(&_i2s)) { 00066 unlock(); 00067 return -1; 00068 } 00069 _hz = hz; 00070 I2S::_owner = NULL; // Not that elegant, but works. rmeyer 00071 acquire(); 00072 unlock(); 00073 return 0; 00074 } 00075 00076 int I2S::protocol(i2s_bitorder_t protocol) { 00077 lock(); 00078 if (i2s_active(&_i2s)) { 00079 unlock(); 00080 return -1; 00081 } 00082 _protocol = protocol; 00083 I2S::_owner = NULL; // Not that elegant, but works. rmeyer 00084 acquire(); 00085 unlock(); 00086 return 0; 00087 } 00088 00089 int I2S::mode(i2s_mode_t mode, bool circular) { 00090 lock(); 00091 if (i2s_active(&_i2s)) { 00092 unlock(); 00093 return -1; 00094 } 00095 _mode = mode; 00096 _circular = circular; 00097 I2S::_owner = NULL; // Not that elegant, but works. rmeyer 00098 acquire(); 00099 unlock(); 00100 return 0; 00101 } 00102 00103 int I2S::harmonize(I2S &dev_i2s_1, I2S &dev_i2s_2) { 00104 dev_i2s_1.lock(); 00105 if (i2s_active(&dev_i2s_1._i2s)) { 00106 dev_i2s_1.unlock(); 00107 return -1; 00108 } 00109 00110 dev_i2s_2.lock(); 00111 if (i2s_active(&dev_i2s_2._i2s)) { 00112 dev_i2s_2.unlock(); 00113 dev_i2s_1.unlock(); 00114 return -1; 00115 } 00116 00117 uint32_t hz1 = dev_i2s_1._hz; 00118 uint32_t hz2 = dev_i2s_2._hz; 00119 int8_t ret = i2s_harmonize(&dev_i2s_1._i2s, &hz1, &dev_i2s_2._i2s, &hz2); 00120 00121 if(ret == 0) { 00122 dev_i2s_1.audio_frequency(hz1); 00123 dev_i2s_2.audio_frequency(hz2); 00124 } 00125 00126 dev_i2s_2.unlock(); 00127 dev_i2s_1.unlock(); 00128 00129 return ret; 00130 } 00131 00132 void I2S::abort_transfer() 00133 { 00134 lock(); 00135 i2s_abort_asynch(&_i2s); 00136 #if TRANSACTION_QUEUE_SIZE_I2S 00137 dequeue_transaction(); 00138 #endif 00139 unlock(); 00140 } 00141 00142 00143 void I2S::clear_transfer_buffer() 00144 { 00145 #if TRANSACTION_QUEUE_SIZE_I2S 00146 lock(); 00147 _transaction_buffer.reset(); 00148 unlock(); 00149 #endif 00150 } 00151 00152 void I2S::abort_all_transfers() 00153 { 00154 lock(); 00155 clear_transfer_buffer(); 00156 abort_transfer(); 00157 unlock(); 00158 } 00159 00160 int I2S::get_transfer_status() 00161 { 00162 lock(); 00163 if (i2s_active(&_i2s)) { 00164 unlock(); 00165 return -1; 00166 } 00167 unlock(); 00168 return 0; 00169 } 00170 00171 unsigned int I2S::get_module() 00172 { 00173 return i2s_get_module(&_i2s); 00174 } 00175 00176 int I2S::dma_priority(i2s_dma_prio_t prio) 00177 { 00178 lock(); 00179 if (i2s_active(&_i2s)) { 00180 unlock(); 00181 return -1; 00182 } 00183 _priority = prio; 00184 unlock(); 00185 return 0; 00186 } 00187 00188 int I2S::queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, const mbed::event_callback_t& callback, int event) 00189 { // NOTE: MUST be called with lock held! 00190 #if TRANSACTION_QUEUE_SIZE_I2S 00191 mbed::transaction_t t; 00192 00193 t.tx_buffer = const_cast<void *>(tx_buffer); 00194 t.tx_length = tx_length; 00195 t.rx_buffer = rx_buffer; 00196 t.rx_length = rx_length; 00197 t.event = event; 00198 t.callback = callback; 00199 t.width = 16; 00200 mbed::Transaction<I2S> transaction(this, t); 00201 core_util_critical_section_enter(); 00202 if (_transaction_buffer.full()) { 00203 core_util_critical_section_enter(); 00204 return -1; // the buffer is full 00205 } else { 00206 _transaction_buffer.push(transaction); 00207 core_util_critical_section_exit(); 00208 return 0; 00209 } 00210 #else 00211 return -1; 00212 #endif 00213 } 00214 00215 00216 // ignore the fact that there are multiple physical i2s's, and always update if it wasn't us last 00217 void I2S::acquire() { // NOTE: MUST be called with lock held! 00218 if (_owner != this) { 00219 i2s_format(&_i2s, _dbits, _fbits, _polarity); 00220 i2s_audio_frequency(&_i2s, _hz); 00221 i2s_set_protocol(&_i2s, _protocol); 00222 i2s_set_mode(&_i2s, _mode); 00223 _owner = this; 00224 } 00225 } 00226 00227 void I2S::start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, 00228 const mbed::event_callback_t& callback, int event) 00229 { // NOTE: MUST be called with lock held! 00230 acquire(); 00231 _callback = callback; 00232 _irq_tx.callback(&I2S::irq_handler_asynch_tx); 00233 _irq_rx.callback(&I2S::irq_handler_asynch_rx); 00234 i2s_transfer(&_i2s, 00235 const_cast<void *>(tx_buffer), tx_length, rx_buffer, rx_length, 00236 _circular, _priority, 00237 _irq_tx.entry(), _irq_rx.entry(), 00238 event); 00239 } 00240 00241 #if TRANSACTION_QUEUE_SIZE_I2S 00242 00243 void I2S::start_transaction(mbed::transaction_t *data) 00244 { // NOTE: MUST be called with lock held! 00245 start_transfer(data->tx_buffer, data->tx_length, data->rx_buffer, data->rx_length, data->callback, data->event); 00246 } 00247 00248 void I2S::dequeue_transaction() 00249 { 00250 lock(); 00251 if (!i2s_active(&_i2s)) { 00252 mbed::Transaction<I2S> t; 00253 if (_transaction_buffer.pop(t)) { 00254 I2S* obj = t.get_object(); 00255 mbed::transaction_t* data = t.get_transaction(); 00256 MBED_ASSERT(obj == this); 00257 obj->start_transaction(data); 00258 } 00259 } 00260 unlock(); 00261 } 00262 00263 #endif 00264 00265 void I2S::irq_handler_asynch_rx(void) 00266 { 00267 int event = i2s_irq_handler_asynch(&_i2s, I2S_RX_EVENT); 00268 if (_callback && (event & I2S_EVENT_ALL)) { 00269 I2sBhHandler::i2s_defer_function(_callback, event & I2S_EVENT_ALL); 00270 } 00271 #if TRANSACTION_QUEUE_SIZE_I2S 00272 if (event & I2S_EVENT_INTERNAL_TRANSFER_COMPLETE) { 00273 I2sBhHandler::i2s_defer_function(mbed::Callback<void()>(this, &I2S::dequeue_transaction)); 00274 } 00275 #endif 00276 } 00277 00278 void I2S::irq_handler_asynch_tx(void) 00279 { 00280 int event = i2s_irq_handler_asynch(&_i2s, I2S_TX_EVENT); 00281 if (_callback && (event & I2S_EVENT_ALL)) { 00282 I2sBhHandler::i2s_defer_function(_callback, event & I2S_EVENT_ALL); 00283 } 00284 #if TRANSACTION_QUEUE_SIZE_I2S 00285 if (event & I2S_EVENT_INTERNAL_TRANSFER_COMPLETE) { 00286 I2sBhHandler::i2s_defer_function(mbed::Callback<void()>(this, &I2S::dequeue_transaction)); 00287 } 00288 #endif 00289 } 00290 00291 #endif // DEVICE_I2S
Generated on Fri Jul 15 2022 06:41:44 by
1.7.2