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.
Fork of ST_I2S by
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 Sun Jul 17 2022 07:57:10 by
1.7.2
