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.h
00001 #ifndef MBED_I2S_H 00002 #define MBED_I2S_H 00003 00004 #include "platform/platform.h" 00005 00006 #if DEVICE_I2S 00007 00008 #include "platform/PlatformMutex.h" 00009 #include "hal/stm_i2s_api.h" 00010 #include "platform/SingletonPtr.h" 00011 00012 #include "platform/CThunk.h" 00013 #include "hal/stm_dma_api.h" 00014 #include "platform/CircularBuffer.h" 00015 #include "platform/FunctionPointer.h" 00016 #include "platform/Transaction.h" 00017 00018 #include "events/EventQueue.h" 00019 00020 /** A I2S Master/Slave, used for communicating with I2S slave/master devices 00021 * 00022 * The default format is set to master transmission mode, one-shot (i.e. not circular) 00023 * 16 data bits & 16 bits per frame, clock polarity 0, 00024 * protocol PHILIPS, and a clock frequency of 44.1kHz 00025 * 00026 * Most I2S devices will also require Reset signals. These 00027 * can be controlled using <DigitalOut> pins 00028 * 00029 * @Note Synchronization level: Thread safe 00030 * 00031 */ 00032 class I2S { 00033 00034 public: 00035 /** Create a I2S master connected to the specified pins 00036 * 00037 * @param dpin I2S data input/output pin 00038 * @param clk I2S clock output pin 00039 * @param wsel I2S word select output pin (might be NC for PDM sources) 00040 * @param fdpin I2S data input pin (for full-duplex operation, default = NC) 00041 * @param mck I2S master clock output (additional pin when needed for some external audio devices, default = NC) 00042 * 00043 * @Note It is up to the application programmer to not generate at the same time two I2S instances with the 00044 * same pin (NC excluded) for one of the parameters, otherwise the correct operation of this class cannot be 00045 * guaranteed (e.g. things like SPI/I2S clock enabling and above all disabling might not work correctly)! 00046 */ 00047 I2S(PinName dpin, PinName clk, PinName wsel, PinName fdpin = NC, PinName mck = NC); 00048 00049 /** Configure the data transmission format 00050 * 00051 * @param dbits Number of data bits per I2S frame (16, 24, or 32) 00052 * @param fbits Number of bits per I2S frame (16 or 32) 00053 * @param polarity Clock polarity (either 0/low or 1/high, default = 0) 00054 * @return Zero if the usage was set, -1 if a transaction is on-going 00055 */ 00056 int format(int dbits, int fbits, int polarity = 0); 00057 00058 /** Set the i2s audio frequency 00059 * 00060 * @param hz audio frequency in hz 00061 * @return Zero if the usage was set, -1 if a transaction is on-going 00062 */ 00063 int audio_frequency(unsigned int hz); 00064 00065 /** Get the i2s audio frequency 00066 * 00067 * @return Currently set audio frequency 00068 */ 00069 unsigned int get_audio_frequency(void) { 00070 return _hz; 00071 } 00072 00073 /** Set the i2s bus protocol 00074 * 00075 * @param protocol I2S protocol to be used 00076 * @return Zero if the usage was set, -1 if a transaction is on-going 00077 */ 00078 int protocol(i2s_bitorder_t protocol); 00079 00080 /** Set the i2s mode 00081 * 00082 * @param mode I2S mode to be used 00083 * @param circular I2S should read/write buffers continuously (in circular mode) 00084 * @return Zero if the usage was set, -1 if a transaction is on-going 00085 */ 00086 int mode(i2s_mode_t mode, bool circular); 00087 00088 /** Start non-blocking I2S transfer as configured with above methods 00089 * 00090 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, 00091 * no transmission will be set up 00092 * @param tx_length The length of TX buffer in bytes 00093 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00094 * received data will be ignored 00095 * @param rx_length The length of RX buffer in bytes 00096 * @param callback The event callback function 00097 * @param event The logical OR of events to notify. Look at i2s hal header file for I2S events. 00098 * @return Zero if the transfer has started (or been queued), or 00099 * -1 if I2S peripheral is busy (or out of resources) 00100 */ 00101 template<typename Type> 00102 int transfer(const Type *tx_buffer, int tx_length, Type *rx_buffer, int rx_length, const mbed::event_callback_t& callback, int event) { 00103 int ret = 0; 00104 00105 lock(); 00106 00107 if (i2s_active(&_i2s) 00108 #if TRANSACTION_QUEUE_SIZE_I2S 00109 || !_transaction_buffer.empty() 00110 #endif 00111 ) { 00112 ret = queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, callback, event); 00113 } else { 00114 start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, callback, event); 00115 } 00116 00117 unlock(); 00118 return ret; 00119 } 00120 00121 /** Abort the on-going I2S transfer, and continue with transfer's in the queue if any. 00122 */ 00123 void abort_transfer(); 00124 00125 /** Clear the transaction buffer 00126 */ 00127 void clear_transfer_buffer(); 00128 00129 /** Clear the transaction buffer and abort on-going transfer. 00130 */ 00131 void abort_all_transfers(); 00132 00133 /** Get transfer status 00134 * 00135 * @return -1 if a transaction is on-going, zero otherwise 00136 */ 00137 int get_transfer_status(); 00138 00139 /** Get internal module id 00140 * 00141 * @return internal module id 00142 */ 00143 unsigned int get_module(); 00144 00145 /** Configure DMA priority for transfers 00146 * 00147 * @param prio The DMA priority to be used 00148 * @return Zero if the usage was set, -1 if a transaction is on-going 00149 */ 00150 int dma_priority(i2s_dma_prio_t prio); 00151 00152 /** Harmonize the frequencies of the given I2S objects so that they are 00153 * the exact multiple one of the other. It can be useful whenever two I2S 00154 * peripherals have to work together and no drift is allowed between them. 00155 * 00156 * @param dev_i2s_1 reference to the first I2S object. 00157 * @param dev_i2s_2 reference to the second I2S object. 00158 * @return Zero if the frequencies have been harmonized correctly, -1 00159 * otherwise. 00160 */ 00161 static int harmonize(I2S &dev_i2s_1, I2S &dev_i2s_2); 00162 00163 00164 /** Bottom-half & transactions event queue for all I2S objects 00165 * Must be used by application programmer to schedule/execute bottom-halves 00166 * (i.e. transfer event callback functions) and automatically start queued 00167 * transactions (i.e. transfers), e.g. by calling `events::EventQueue::dispatch_forever()`! */ 00168 static events::EventQueue i2s_bh_queue; 00169 00170 protected: 00171 /** Acquire exclusive access to this I2S bus 00172 */ 00173 virtual void lock(void); 00174 00175 /** Release exclusive access to this I2S bus 00176 */ 00177 virtual void unlock(void); 00178 00179 /** I2S TX DMA IRQ handler 00180 * 00181 */ 00182 void irq_handler_asynch_tx(void); 00183 00184 /** I2S RX DMA IRQ handler 00185 * 00186 */ 00187 void irq_handler_asynch_rx(void); 00188 00189 /** Add a transfer to the queue 00190 * @param data Transaction data 00191 * @return Zero if a transfer was added to the queue, or -1 if the queue is full 00192 */ 00193 int queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, 00194 const mbed::event_callback_t& callback, int event); 00195 00196 /** Configures a callback, i2s peripheral and initiate a new transfer 00197 * 00198 * @param data Transaction data 00199 */ 00200 void start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, 00201 const mbed::event_callback_t& callback, int event); 00202 00203 class I2sBhHandler { 00204 friend class I2S; 00205 00206 static void i2s_defer_function(const mbed::event_callback_t& bottom_half, int event) { 00207 i2s_bh_queue.call(bottom_half, event); 00208 } 00209 00210 static void i2s_defer_function(const mbed::Callback<void()>& bottom_half) { 00211 i2s_bh_queue.call(bottom_half); 00212 } 00213 }; 00214 00215 #if TRANSACTION_QUEUE_SIZE_I2S 00216 /** Start a new transaction 00217 * 00218 * @param data Transaction data 00219 */ 00220 void start_transaction(mbed::transaction_t *data); 00221 00222 /** Dequeue a transaction 00223 * 00224 */ 00225 void dequeue_transaction(); 00226 00227 mbed::CircularBuffer<mbed::Transaction<I2S>, TRANSACTION_QUEUE_SIZE_I2S> _transaction_buffer; 00228 #endif // TRANSACTION_QUEUE_SIZE_I2S 00229 00230 public: 00231 virtual ~I2S() { 00232 /* TODO: cleanup has still to be revised completely! */ 00233 abort_all_transfers(); 00234 i2s_free(&_i2s); 00235 } 00236 00237 protected: 00238 i2s_t _i2s; 00239 00240 CThunk<I2S> _irq_tx; 00241 CThunk<I2S> _irq_rx; 00242 mbed::event_callback_t _callback; 00243 i2s_dma_prio_t _priority; // DMA priority 00244 00245 void acquire(void); 00246 00247 static I2S *_owner; 00248 static SingletonPtr<PlatformMutex> _mutex; 00249 00250 int _dbits; 00251 int _fbits; 00252 int _polarity; 00253 i2s_bitorder_t _protocol; 00254 i2s_mode_t _mode; 00255 bool _circular; 00256 unsigned int _hz; 00257 }; 00258 00259 #endif // DEVICE_I2S 00260 00261 #endif // MBED_I2S_H
Generated on Fri Jul 15 2022 06:41:44 by
1.7.2