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.h
00001 #ifndef MBED_I2S_H 00002 #define MBED_I2S_H 00003 00004 #include "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 Sun Jul 17 2022 07:57:10 by
 1.7.2
 1.7.2 
    