STMicroelectronics' implementation of an I2S driver, also including DMA support.
Dependents: temp X_NUCLEO_CCA01M1 X_NUCLEO_CCA01M1 X_NUCLEO_CCA02M1
Platform compatibility
This driver has been designed to support a wide range of the Nucleo F4 Family of platforms and MCUs, but not all members of this family support I2S
and/or some of the members might require slight modifications to the sources of this driver in order to make it work on those.
This driver has for now been tested only with the following platforms:
drivers/I2S.h@4:21603d68bcf7, 2016-12-21 (annotated)
- Committer:
- Davide Aliprandi
- Date:
- Wed Dec 21 20:24:16 2016 +0100
- Revision:
- 4:21603d68bcf7
- Parent:
- 1:f90318e0923b
- Child:
- 9:c4c2240e06d6
Added algorithm to automatically harmonize two I2S peripherals' frequencies.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Wolfgang Betz |
0:752e74bf5ef1 | 1 | #ifndef MBED_I2S_H |
Wolfgang Betz |
0:752e74bf5ef1 | 2 | #define MBED_I2S_H |
Wolfgang Betz |
0:752e74bf5ef1 | 3 | |
Wolfgang Betz |
0:752e74bf5ef1 | 4 | #include "platform/platform.h" |
Wolfgang Betz |
0:752e74bf5ef1 | 5 | |
Wolfgang Betz |
0:752e74bf5ef1 | 6 | #if DEVICE_I2S |
Wolfgang Betz |
0:752e74bf5ef1 | 7 | |
Wolfgang Betz |
0:752e74bf5ef1 | 8 | #ifndef MBED_CONF_RTOS_PRESENT |
Wolfgang Betz |
0:752e74bf5ef1 | 9 | #error "I2S only supports asynchronous transfers which currently require a RTOS!" |
Wolfgang Betz |
0:752e74bf5ef1 | 10 | #else |
Wolfgang Betz |
0:752e74bf5ef1 | 11 | #include "rtos/Thread.h" // betzw - TODO: this requires a RTOS (i.e. needs to be generalized for mbed-classic) |
Wolfgang Betz |
0:752e74bf5ef1 | 12 | #endif |
Wolfgang Betz |
0:752e74bf5ef1 | 13 | |
Wolfgang Betz |
0:752e74bf5ef1 | 14 | #include "platform/PlatformMutex.h" |
Wolfgang Betz |
1:f90318e0923b | 15 | #include "hal/stm_i2s_api.h" |
Wolfgang Betz |
0:752e74bf5ef1 | 16 | #include "platform/SingletonPtr.h" |
Wolfgang Betz |
0:752e74bf5ef1 | 17 | |
Wolfgang Betz |
0:752e74bf5ef1 | 18 | #include "platform/CThunk.h" |
Wolfgang Betz |
1:f90318e0923b | 19 | #include "hal/stm_dma_api.h" |
Wolfgang Betz |
0:752e74bf5ef1 | 20 | #include "platform/CircularBuffer.h" |
Wolfgang Betz |
0:752e74bf5ef1 | 21 | #include "platform/FunctionPointer.h" |
Wolfgang Betz |
0:752e74bf5ef1 | 22 | #include "platform/Transaction.h" |
Wolfgang Betz |
0:752e74bf5ef1 | 23 | |
Wolfgang Betz |
0:752e74bf5ef1 | 24 | #include "events/EventQueue.h" |
Wolfgang Betz |
0:752e74bf5ef1 | 25 | |
Wolfgang Betz |
0:752e74bf5ef1 | 26 | namespace mbed { |
Wolfgang Betz |
0:752e74bf5ef1 | 27 | |
Wolfgang Betz |
0:752e74bf5ef1 | 28 | /** A I2S Master/Slave, used for communicating with I2S slave/master devices |
Wolfgang Betz |
0:752e74bf5ef1 | 29 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 30 | * The default format is set to master transmission mode, one-shot (i.e. not circular) |
Wolfgang Betz |
0:752e74bf5ef1 | 31 | * 16 data bits & 16 bits per frame, clock polarity 0, |
Wolfgang Betz |
0:752e74bf5ef1 | 32 | * protocol PHILIPS, and a clock frequency of 44.1kHz |
Wolfgang Betz |
0:752e74bf5ef1 | 33 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 34 | * TODO: "direct" PDM support |
Wolfgang Betz |
0:752e74bf5ef1 | 35 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 36 | * Most I2S devices will also require Reset signals. These |
Wolfgang Betz |
0:752e74bf5ef1 | 37 | * can be controlled using <DigitalOut> pins |
Wolfgang Betz |
0:752e74bf5ef1 | 38 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 39 | * @Note Synchronization level: Thread safe |
Wolfgang Betz |
0:752e74bf5ef1 | 40 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 41 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 42 | class I2S { |
Wolfgang Betz |
0:752e74bf5ef1 | 43 | |
Wolfgang Betz |
0:752e74bf5ef1 | 44 | public: |
Wolfgang Betz |
0:752e74bf5ef1 | 45 | /** Create a I2S master connected to the specified pins |
Wolfgang Betz |
0:752e74bf5ef1 | 46 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 47 | * @param dpin I2S data input/output pin |
Wolfgang Betz |
0:752e74bf5ef1 | 48 | * @param clk I2S clock output pin |
Wolfgang Betz |
0:752e74bf5ef1 | 49 | * @param wsel I2S word select output pin (might be NC for PDM sources) |
Wolfgang Betz |
0:752e74bf5ef1 | 50 | * @param fdpin I2S data input pin (for full-duplex operation, default = NC) |
Wolfgang Betz |
0:752e74bf5ef1 | 51 | * @param mck I2S master clock output (additional pin when needed for some external audio devices, default = NC) |
Wolfgang Betz |
0:752e74bf5ef1 | 52 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 53 | * @Note It is up to the application programmer to not generate at the same time two I2S instances with the |
Wolfgang Betz |
0:752e74bf5ef1 | 54 | * same pin (NC excluded) for one of the parameters, otherwise the correct operation of this class cannot be |
Wolfgang Betz |
0:752e74bf5ef1 | 55 | * guaranteed (e.g. things like SPI/I2S clock enabling and above all disabling might not work correctly)! |
Wolfgang Betz |
0:752e74bf5ef1 | 56 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 57 | I2S(PinName dpin, PinName clk, PinName wsel, PinName fdpin = NC, PinName mck = NC); |
Wolfgang Betz |
0:752e74bf5ef1 | 58 | |
Wolfgang Betz |
0:752e74bf5ef1 | 59 | /** Configure the data transmission format |
Wolfgang Betz |
0:752e74bf5ef1 | 60 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 61 | * @param dbits Number of data bits per I2S frame (16, 24, or 32) |
Wolfgang Betz |
0:752e74bf5ef1 | 62 | * @param fbits Number of bits per I2S frame (16 or 32) |
Wolfgang Betz |
0:752e74bf5ef1 | 63 | * @param polarity Clock polarity (either 0/low or 1/high, default = 0) |
Wolfgang Betz |
0:752e74bf5ef1 | 64 | * @return Zero if the usage was set, -1 if a transaction is on-going |
Wolfgang Betz |
0:752e74bf5ef1 | 65 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 66 | int format(int dbits, int fbits, int polarity = 0); |
Wolfgang Betz |
0:752e74bf5ef1 | 67 | |
Wolfgang Betz |
0:752e74bf5ef1 | 68 | /** Set the i2s audio frequency |
Wolfgang Betz |
0:752e74bf5ef1 | 69 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 70 | * @param hz audio frequency in hz |
Wolfgang Betz |
0:752e74bf5ef1 | 71 | * @return Zero if the usage was set, -1 if a transaction is on-going |
Wolfgang Betz |
0:752e74bf5ef1 | 72 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 73 | int audio_frequency(unsigned int hz); |
Wolfgang Betz |
0:752e74bf5ef1 | 74 | |
Wolfgang Betz |
0:752e74bf5ef1 | 75 | /** Set the i2s bus protocol |
Wolfgang Betz |
0:752e74bf5ef1 | 76 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 77 | * @param protocol I2S protocol to be used |
Wolfgang Betz |
0:752e74bf5ef1 | 78 | * @return Zero if the usage was set, -1 if a transaction is on-going |
Wolfgang Betz |
0:752e74bf5ef1 | 79 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 80 | int set_protocol(i2s_bitorder_t protocol); |
Wolfgang Betz |
0:752e74bf5ef1 | 81 | |
Wolfgang Betz |
0:752e74bf5ef1 | 82 | /** Set the i2s mode |
Wolfgang Betz |
0:752e74bf5ef1 | 83 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 84 | * @param mode I2S mode to be used |
Wolfgang Betz |
0:752e74bf5ef1 | 85 | * @param circular I2S should read/write buffers continuously (in circular mode) |
Wolfgang Betz |
0:752e74bf5ef1 | 86 | * @return Zero if the usage was set, -1 if a transaction is on-going |
Wolfgang Betz |
0:752e74bf5ef1 | 87 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 88 | int set_mode(i2s_mode_t mode, bool circular); |
Wolfgang Betz |
0:752e74bf5ef1 | 89 | |
Wolfgang Betz |
0:752e74bf5ef1 | 90 | /** Start non-blocking I2S transfer as configured with above methods |
Wolfgang Betz |
0:752e74bf5ef1 | 91 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 92 | * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, |
Wolfgang Betz |
0:752e74bf5ef1 | 93 | * no transmission will be set up |
Wolfgang Betz |
0:752e74bf5ef1 | 94 | * @param tx_length The length of TX buffer in bytes |
Wolfgang Betz |
0:752e74bf5ef1 | 95 | * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, |
Wolfgang Betz |
0:752e74bf5ef1 | 96 | * received data will be ignored |
Wolfgang Betz |
0:752e74bf5ef1 | 97 | * @param rx_length The length of RX buffer in bytes |
Wolfgang Betz |
0:752e74bf5ef1 | 98 | * @param callback The event callback function |
Wolfgang Betz |
0:752e74bf5ef1 | 99 | * @param event The logical OR of events to notify. Look at i2s hal header file for I2S events. |
Wolfgang Betz |
0:752e74bf5ef1 | 100 | * @return Zero if the transfer has started (or been queued), or |
Wolfgang Betz |
0:752e74bf5ef1 | 101 | * -1 if I2S peripheral is busy (or out of resources) |
Wolfgang Betz |
0:752e74bf5ef1 | 102 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 103 | template<typename Type> |
Wolfgang Betz |
0:752e74bf5ef1 | 104 | int transfer(const Type *tx_buffer, int tx_length, Type *rx_buffer, int rx_length, const event_callback_t& callback, int event) { |
Wolfgang Betz |
0:752e74bf5ef1 | 105 | int ret = 0; |
Wolfgang Betz |
0:752e74bf5ef1 | 106 | |
Wolfgang Betz |
0:752e74bf5ef1 | 107 | lock(); |
Wolfgang Betz |
0:752e74bf5ef1 | 108 | #if !TRANSACTION_QUEUE_SIZE_I2S |
Wolfgang Betz |
0:752e74bf5ef1 | 109 | if(callback && (event & I2S_EVENT_ALL)) { |
Wolfgang Betz |
0:752e74bf5ef1 | 110 | /* Init bottom half daemon */ |
Wolfgang Betz |
0:752e74bf5ef1 | 111 | I2sBhHandler::init(); |
Wolfgang Betz |
0:752e74bf5ef1 | 112 | } |
Wolfgang Betz |
0:752e74bf5ef1 | 113 | #endif |
Wolfgang Betz |
0:752e74bf5ef1 | 114 | |
Wolfgang Betz |
0:752e74bf5ef1 | 115 | if (i2s_active(&_i2s) |
Wolfgang Betz |
0:752e74bf5ef1 | 116 | #if TRANSACTION_QUEUE_SIZE_I2S |
Wolfgang Betz |
0:752e74bf5ef1 | 117 | || !_transaction_buffer.empty() |
Wolfgang Betz |
0:752e74bf5ef1 | 118 | #endif |
Wolfgang Betz |
0:752e74bf5ef1 | 119 | ) { |
Wolfgang Betz |
0:752e74bf5ef1 | 120 | ret = queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, callback, event); |
Wolfgang Betz |
0:752e74bf5ef1 | 121 | } else { |
Wolfgang Betz |
0:752e74bf5ef1 | 122 | start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, callback, event); |
Wolfgang Betz |
0:752e74bf5ef1 | 123 | } |
Wolfgang Betz |
0:752e74bf5ef1 | 124 | unlock(); |
Wolfgang Betz |
0:752e74bf5ef1 | 125 | return ret; |
Wolfgang Betz |
0:752e74bf5ef1 | 126 | } |
Wolfgang Betz |
0:752e74bf5ef1 | 127 | |
Wolfgang Betz |
0:752e74bf5ef1 | 128 | /** Acquire exclusive access to this I2S bus |
Wolfgang Betz |
0:752e74bf5ef1 | 129 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 130 | virtual void lock(void); |
Wolfgang Betz |
0:752e74bf5ef1 | 131 | |
Wolfgang Betz |
0:752e74bf5ef1 | 132 | /** Release exclusive access to this I2S bus |
Wolfgang Betz |
0:752e74bf5ef1 | 133 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 134 | virtual void unlock(void); |
Wolfgang Betz |
0:752e74bf5ef1 | 135 | |
Wolfgang Betz |
0:752e74bf5ef1 | 136 | /** Abort the on-going I2S transfer, and continue with transfer's in the queue if any. |
Wolfgang Betz |
0:752e74bf5ef1 | 137 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 138 | void abort_transfer(); |
Wolfgang Betz |
0:752e74bf5ef1 | 139 | |
Wolfgang Betz |
0:752e74bf5ef1 | 140 | /** Clear the transaction buffer |
Wolfgang Betz |
0:752e74bf5ef1 | 141 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 142 | void clear_transfer_buffer(); |
Wolfgang Betz |
0:752e74bf5ef1 | 143 | |
Wolfgang Betz |
0:752e74bf5ef1 | 144 | /** Clear the transaction buffer and abort on-going transfer. |
Wolfgang Betz |
0:752e74bf5ef1 | 145 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 146 | void abort_all_transfers(); |
Wolfgang Betz |
0:752e74bf5ef1 | 147 | |
Wolfgang Betz |
0:752e74bf5ef1 | 148 | /** Get transfer status |
Wolfgang Betz |
0:752e74bf5ef1 | 149 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 150 | * @return -1 if a transaction is on-going, zero otherwise |
Wolfgang Betz |
0:752e74bf5ef1 | 151 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 152 | int get_transfer_status(); |
Wolfgang Betz |
0:752e74bf5ef1 | 153 | |
Wolfgang Betz |
0:752e74bf5ef1 | 154 | /** Get internal module id |
Wolfgang Betz |
0:752e74bf5ef1 | 155 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 156 | * @return internal module id |
Wolfgang Betz |
0:752e74bf5ef1 | 157 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 158 | unsigned int get_module(); |
Wolfgang Betz |
0:752e74bf5ef1 | 159 | |
Wolfgang Betz |
0:752e74bf5ef1 | 160 | /** Configure DMA priority for transfers |
Wolfgang Betz |
0:752e74bf5ef1 | 161 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 162 | * @param prio The DMA priority to be used |
Wolfgang Betz |
0:752e74bf5ef1 | 163 | * @return Zero if the usage was set, -1 if a transaction is on-going |
Wolfgang Betz |
0:752e74bf5ef1 | 164 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 165 | int set_dma_priority(i2s_dma_prio_t prio); |
Wolfgang Betz |
0:752e74bf5ef1 | 166 | |
Davide Aliprandi |
4:21603d68bcf7 | 167 | /** Harmonize the frequencies of the given I2S objects so that they are |
Davide Aliprandi |
4:21603d68bcf7 | 168 | * exact multiple one of the other. It can be useful whenever two I2S |
Davide Aliprandi |
4:21603d68bcf7 | 169 | * peripherals have to work together and no drift is allowed between them. |
Davide Aliprandi |
4:21603d68bcf7 | 170 | * |
Davide Aliprandi |
4:21603d68bcf7 | 171 | * @param dev_i2s_1 reference to the first I2S object. |
Davide Aliprandi |
4:21603d68bcf7 | 172 | * @param dev_i2s_2 reference to the second I2S object. |
Davide Aliprandi |
4:21603d68bcf7 | 173 | * @return Zero if the frequencies have been harmonized correctly, -1 |
Davide Aliprandi |
4:21603d68bcf7 | 174 | * otherwise. |
Davide Aliprandi |
4:21603d68bcf7 | 175 | */ |
Davide Aliprandi |
4:21603d68bcf7 | 176 | static int harmonize(I2S *dev_i2s_1, I2S *dev_i2s_2); |
Davide Aliprandi |
4:21603d68bcf7 | 177 | |
Wolfgang Betz |
0:752e74bf5ef1 | 178 | protected: |
Wolfgang Betz |
0:752e74bf5ef1 | 179 | /** I2S TX DMA IRQ handler |
Wolfgang Betz |
0:752e74bf5ef1 | 180 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 181 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 182 | void irq_handler_asynch_tx(void); |
Wolfgang Betz |
0:752e74bf5ef1 | 183 | |
Wolfgang Betz |
0:752e74bf5ef1 | 184 | /** I2S RX DMA IRQ handler |
Wolfgang Betz |
0:752e74bf5ef1 | 185 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 186 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 187 | void irq_handler_asynch_rx(void); |
Wolfgang Betz |
0:752e74bf5ef1 | 188 | |
Wolfgang Betz |
0:752e74bf5ef1 | 189 | /** Add a transfer to the queue |
Wolfgang Betz |
0:752e74bf5ef1 | 190 | * @param data Transaction data |
Wolfgang Betz |
0:752e74bf5ef1 | 191 | * @return Zero if a transfer was added to the queue, or -1 if the queue is full |
Wolfgang Betz |
0:752e74bf5ef1 | 192 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 193 | int queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, |
Wolfgang Betz |
0:752e74bf5ef1 | 194 | const event_callback_t& callback, int event); |
Wolfgang Betz |
0:752e74bf5ef1 | 195 | |
Wolfgang Betz |
0:752e74bf5ef1 | 196 | /** Configures a callback, i2s peripheral and initiate a new transfer |
Wolfgang Betz |
0:752e74bf5ef1 | 197 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 198 | * @param data Transaction data |
Wolfgang Betz |
0:752e74bf5ef1 | 199 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 200 | void start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, |
Wolfgang Betz |
0:752e74bf5ef1 | 201 | const event_callback_t& callback, int event); |
Wolfgang Betz |
0:752e74bf5ef1 | 202 | |
Wolfgang Betz |
0:752e74bf5ef1 | 203 | class I2sBhHandler { |
Wolfgang Betz |
0:752e74bf5ef1 | 204 | friend class I2S; |
Wolfgang Betz |
0:752e74bf5ef1 | 205 | |
Wolfgang Betz |
0:752e74bf5ef1 | 206 | static void init() { |
Wolfgang Betz |
0:752e74bf5ef1 | 207 | static bool inited = false; |
Wolfgang Betz |
0:752e74bf5ef1 | 208 | |
Wolfgang Betz |
0:752e74bf5ef1 | 209 | if(!inited) { |
Wolfgang Betz |
0:752e74bf5ef1 | 210 | Callback<void()> i2s_bh_task(&_i2s_bh_queue, &events::EventQueue::dispatch_forever); |
Wolfgang Betz |
0:752e74bf5ef1 | 211 | _i2s_bh_daemon.start(i2s_bh_task); // betzw - TODO: this requires a RTOS (i.e. needs to be generalized for mbed-classic) |
Wolfgang Betz |
0:752e74bf5ef1 | 212 | inited = true; |
Wolfgang Betz |
0:752e74bf5ef1 | 213 | } |
Wolfgang Betz |
0:752e74bf5ef1 | 214 | } |
Wolfgang Betz |
0:752e74bf5ef1 | 215 | |
Wolfgang Betz |
0:752e74bf5ef1 | 216 | static void i2s_defer_function(const event_callback_t& bottom_half, int event) { |
Wolfgang Betz |
0:752e74bf5ef1 | 217 | _i2s_bh_queue.call(bottom_half, event); |
Wolfgang Betz |
0:752e74bf5ef1 | 218 | } |
Wolfgang Betz |
0:752e74bf5ef1 | 219 | |
Wolfgang Betz |
0:752e74bf5ef1 | 220 | static void i2s_defer_function(const Callback<void()>& bottom_half) { |
Wolfgang Betz |
0:752e74bf5ef1 | 221 | _i2s_bh_queue.call(bottom_half); |
Wolfgang Betz |
0:752e74bf5ef1 | 222 | } |
Wolfgang Betz |
0:752e74bf5ef1 | 223 | |
Wolfgang Betz |
0:752e74bf5ef1 | 224 | static rtos::Thread _i2s_bh_daemon; // betzw - TODO: this requires a RTOS (i.e. needs to be generalized for mbed-classic) |
Wolfgang Betz |
0:752e74bf5ef1 | 225 | static events::EventQueue _i2s_bh_queue; |
Wolfgang Betz |
0:752e74bf5ef1 | 226 | }; |
Wolfgang Betz |
0:752e74bf5ef1 | 227 | |
Wolfgang Betz |
0:752e74bf5ef1 | 228 | #if TRANSACTION_QUEUE_SIZE_I2S |
Wolfgang Betz |
0:752e74bf5ef1 | 229 | /** Start a new transaction |
Wolfgang Betz |
0:752e74bf5ef1 | 230 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 231 | * @param data Transaction data |
Wolfgang Betz |
0:752e74bf5ef1 | 232 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 233 | void start_transaction(transaction_t *data); |
Wolfgang Betz |
0:752e74bf5ef1 | 234 | |
Wolfgang Betz |
0:752e74bf5ef1 | 235 | /** Dequeue a transaction |
Wolfgang Betz |
0:752e74bf5ef1 | 236 | * |
Wolfgang Betz |
0:752e74bf5ef1 | 237 | */ |
Wolfgang Betz |
0:752e74bf5ef1 | 238 | void dequeue_transaction(); |
Wolfgang Betz |
0:752e74bf5ef1 | 239 | |
Wolfgang Betz |
0:752e74bf5ef1 | 240 | /* betzw - WAS : static */ CircularBuffer<Transaction<I2S>, TRANSACTION_QUEUE_SIZE_I2S> _transaction_buffer; |
Wolfgang Betz |
0:752e74bf5ef1 | 241 | #endif // TRANSACTION_QUEUE_SIZE_I2S |
Wolfgang Betz |
0:752e74bf5ef1 | 242 | |
Davide Aliprandi |
4:21603d68bcf7 | 243 | /** Compute the real frequency of a given I2S objects. |
Davide Aliprandi |
4:21603d68bcf7 | 244 | * |
Davide Aliprandi |
4:21603d68bcf7 | 245 | * @param dev_i2s reference to the I2S object. |
Davide Aliprandi |
4:21603d68bcf7 | 246 | * @return the computed real frequency. |
Davide Aliprandi |
4:21603d68bcf7 | 247 | */ |
Davide Aliprandi |
4:21603d68bcf7 | 248 | static float compute_real_frequency(I2S *dev_i2s); |
Davide Aliprandi |
4:21603d68bcf7 | 249 | |
Davide Aliprandi |
4:21603d68bcf7 | 250 | /** Computes the two-div-plus-odd factor of a given I2S objects |
Davide Aliprandi |
4:21603d68bcf7 | 251 | * on a desired frequency. |
Davide Aliprandi |
4:21603d68bcf7 | 252 | * |
Davide Aliprandi |
4:21603d68bcf7 | 253 | * @param dev_i2s reference to the I2S object. |
Davide Aliprandi |
4:21603d68bcf7 | 254 | * @frequency the desired frequency. |
Davide Aliprandi |
4:21603d68bcf7 | 255 | * @return the computed two-div-plus-odd factor. |
Davide Aliprandi |
4:21603d68bcf7 | 256 | */ |
Davide Aliprandi |
4:21603d68bcf7 | 257 | static float compute_magic_factor(I2S *dev_i2s, float f); |
Davide Aliprandi |
4:21603d68bcf7 | 258 | |
Davide Aliprandi |
4:21603d68bcf7 | 259 | /** Compute the desired frequency of a given I2S objects, given the magic |
Davide Aliprandi |
4:21603d68bcf7 | 260 | * factor. |
Davide Aliprandi |
4:21603d68bcf7 | 261 | * |
Davide Aliprandi |
4:21603d68bcf7 | 262 | * @param dev_i2s reference to the I2S object. |
Davide Aliprandi |
4:21603d68bcf7 | 263 | * @param mf the two-div-plus-odd factor. |
Davide Aliprandi |
4:21603d68bcf7 | 264 | * @return the computed desired frequency. |
Davide Aliprandi |
4:21603d68bcf7 | 265 | */ |
Davide Aliprandi |
4:21603d68bcf7 | 266 | static float compute_desired_frequency(I2S *dev_i2s, float mf); |
Davide Aliprandi |
4:21603d68bcf7 | 267 | |
Wolfgang Betz |
0:752e74bf5ef1 | 268 | public: |
Wolfgang Betz |
0:752e74bf5ef1 | 269 | virtual ~I2S() { |
Wolfgang Betz |
0:752e74bf5ef1 | 270 | /* betzw - TODO: cleanup has still to be revised completely! */ |
Wolfgang Betz |
0:752e74bf5ef1 | 271 | abort_all_transfers(); |
Wolfgang Betz |
0:752e74bf5ef1 | 272 | i2s_free(&_i2s); |
Wolfgang Betz |
0:752e74bf5ef1 | 273 | } |
Wolfgang Betz |
0:752e74bf5ef1 | 274 | |
Wolfgang Betz |
0:752e74bf5ef1 | 275 | protected: |
Wolfgang Betz |
0:752e74bf5ef1 | 276 | i2s_t _i2s; |
Wolfgang Betz |
0:752e74bf5ef1 | 277 | |
Wolfgang Betz |
0:752e74bf5ef1 | 278 | CThunk<I2S> _irq_tx; |
Wolfgang Betz |
0:752e74bf5ef1 | 279 | CThunk<I2S> _irq_rx; |
Wolfgang Betz |
0:752e74bf5ef1 | 280 | event_callback_t _callback; |
Wolfgang Betz |
0:752e74bf5ef1 | 281 | i2s_dma_prio_t _priority; // DMA priority |
Wolfgang Betz |
0:752e74bf5ef1 | 282 | |
Wolfgang Betz |
0:752e74bf5ef1 | 283 | void acquire(void); |
Wolfgang Betz |
0:752e74bf5ef1 | 284 | |
Wolfgang Betz |
0:752e74bf5ef1 | 285 | static I2S *_owner; |
Wolfgang Betz |
0:752e74bf5ef1 | 286 | static SingletonPtr<PlatformMutex> _mutex; |
Wolfgang Betz |
0:752e74bf5ef1 | 287 | |
Wolfgang Betz |
0:752e74bf5ef1 | 288 | int _dbits; |
Wolfgang Betz |
0:752e74bf5ef1 | 289 | int _fbits; |
Wolfgang Betz |
0:752e74bf5ef1 | 290 | int _polarity; |
Wolfgang Betz |
0:752e74bf5ef1 | 291 | i2s_bitorder_t _protocol; |
Wolfgang Betz |
0:752e74bf5ef1 | 292 | i2s_mode_t _mode; |
Wolfgang Betz |
0:752e74bf5ef1 | 293 | bool _circular; |
Wolfgang Betz |
0:752e74bf5ef1 | 294 | unsigned int _hz; |
Wolfgang Betz |
0:752e74bf5ef1 | 295 | }; |
Wolfgang Betz |
0:752e74bf5ef1 | 296 | |
Wolfgang Betz |
0:752e74bf5ef1 | 297 | } // namespace mbed |
Wolfgang Betz |
0:752e74bf5ef1 | 298 | |
Wolfgang Betz |
0:752e74bf5ef1 | 299 | #endif |
Wolfgang Betz |
0:752e74bf5ef1 | 300 | |
Wolfgang Betz |
0:752e74bf5ef1 | 301 | #endif |