A well tested I2S library where the send and recieve parts are seperate instances.

Dependents:   TLV320_Write_test flash_audio_playerI2S Wolfson_3_wav

Committer:
p07gbar
Date:
Wed Sep 19 10:53:33 2012 +0000
Revision:
0:455d5826751b
Working fairly stably with read/write 16/32 tx/rx

Who changed what in which revision?

UserRevisionLine numberNew contents of line
p07gbar 0:455d5826751b 1 /**
p07gbar 0:455d5826751b 2 * @author Giles Barton-Owen
p07gbar 0:455d5826751b 3 *
p07gbar 0:455d5826751b 4 * @section LICENSE
p07gbar 0:455d5826751b 5 *
p07gbar 0:455d5826751b 6 * Copyright (c) 2012 mbed
p07gbar 0:455d5826751b 7 *
p07gbar 0:455d5826751b 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
p07gbar 0:455d5826751b 9 * of this software and associated documentation files (the "Software"), to deal
p07gbar 0:455d5826751b 10 * in the Software without restriction, including without limitation the rights
p07gbar 0:455d5826751b 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
p07gbar 0:455d5826751b 12 * copies of the Software, and to permit persons to whom the Software is
p07gbar 0:455d5826751b 13 * furnished to do so, subject to the following conditions:
p07gbar 0:455d5826751b 14 *
p07gbar 0:455d5826751b 15 * The above copyright notice and this permission notice shall be included in
p07gbar 0:455d5826751b 16 * all copies or substantial portions of the Software.
p07gbar 0:455d5826751b 17 *
p07gbar 0:455d5826751b 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
p07gbar 0:455d5826751b 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
p07gbar 0:455d5826751b 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
p07gbar 0:455d5826751b 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
p07gbar 0:455d5826751b 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
p07gbar 0:455d5826751b 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
p07gbar 0:455d5826751b 24 * THE SOFTWARE.
p07gbar 0:455d5826751b 25 *
p07gbar 0:455d5826751b 26 * @section DESCRIPTION
p07gbar 0:455d5826751b 27 * A I2S library for the LPC1768's built-in I2S peripheral
p07gbar 0:455d5826751b 28 *
p07gbar 0:455d5826751b 29 */
p07gbar 0:455d5826751b 30
p07gbar 0:455d5826751b 31 #include "mbed.h"
p07gbar 0:455d5826751b 32 #include "math.h"
p07gbar 0:455d5826751b 33
p07gbar 0:455d5826751b 34 #ifndef I2S_H
p07gbar 0:455d5826751b 35 #define I2S_H
p07gbar 0:455d5826751b 36
p07gbar 0:455d5826751b 37 #define I2S_TRANSMIT 0
p07gbar 0:455d5826751b 38 #define I2S_RECEIVE 1
p07gbar 0:455d5826751b 39
p07gbar 0:455d5826751b 40 #define I2S_MASTER 0
p07gbar 0:455d5826751b 41 #define I2S_SLAVE 1
p07gbar 0:455d5826751b 42
p07gbar 0:455d5826751b 43 #define I2S_STEREO 0
p07gbar 0:455d5826751b 44 #define I2S_MONO 1
p07gbar 0:455d5826751b 45
p07gbar 0:455d5826751b 46 #define I2S_MUTED 1
p07gbar 0:455d5826751b 47 #define I2S_UNMUTED 0
p07gbar 0:455d5826751b 48
p07gbar 0:455d5826751b 49 #define I2S_4WIRE 1
p07gbar 0:455d5826751b 50 #define I2S_3WIRE 0
p07gbar 0:455d5826751b 51
p07gbar 0:455d5826751b 52 /** A class to play give access to the I2S library
p07gbar 0:455d5826751b 53 */
p07gbar 0:455d5826751b 54
p07gbar 0:455d5826751b 55 class I2S
p07gbar 0:455d5826751b 56 {
p07gbar 0:455d5826751b 57
p07gbar 0:455d5826751b 58 public:
p07gbar 0:455d5826751b 59
p07gbar 0:455d5826751b 60 /** Create a I2S instance
p07gbar 0:455d5826751b 61 *
p07gbar 0:455d5826751b 62 * @param rxtx Set the I2S instance to be transmit or recieve (I2S_TRANSMIT/I2S_RECEIVE)
p07gbar 0:455d5826751b 63 * @param sd The serial data pin
p07gbar 0:455d5826751b 64 * @param ws The word select pin
p07gbar 0:455d5826751b 65 * @param clk The clock pin
p07gbar 0:455d5826751b 66 */
p07gbar 0:455d5826751b 67 I2S(bool rxtx, PinName sd, PinName ws, PinName clk);
p07gbar 0:455d5826751b 68
p07gbar 0:455d5826751b 69 /** Create a I2S instance: Only with the serial data line set. Won't really do much.
p07gbar 0:455d5826751b 70 *
p07gbar 0:455d5826751b 71 * @param rxtx Set the I2S instance to be transmit or recieve (I2S_TRANSMIT/I2S_RECEIVE)
p07gbar 0:455d5826751b 72 * @param sd The serial data pin
p07gbar 0:455d5826751b 73 */
p07gbar 0:455d5826751b 74 I2S(bool rxtx, PinName sd);
p07gbar 0:455d5826751b 75
p07gbar 0:455d5826751b 76
p07gbar 0:455d5826751b 77 /** Create a I2S instance: Only with serial data line and word select.
p07gbar 0:455d5826751b 78 *
p07gbar 0:455d5826751b 79 * @param rxtx Set the I2S instance to be transmit or recieve (I2S_TRANSMIT/I2S_RECEIVE)
p07gbar 0:455d5826751b 80 * @param sd The serial data pin
p07gbar 0:455d5826751b 81 * @param ws The word select pin
p07gbar 0:455d5826751b 82 */
p07gbar 0:455d5826751b 83 I2S(bool rxtx, PinName sd, PinName ws);
p07gbar 0:455d5826751b 84
p07gbar 0:455d5826751b 85
p07gbar 0:455d5826751b 86
p07gbar 0:455d5826751b 87 /** Create a I2S instance: Only with serial data line. Four wire mode means this is functional
p07gbar 0:455d5826751b 88 *
p07gbar 0:455d5826751b 89 * @param rxtx Set the I2S instance to be transmit or recieve (I2S_TRANSMIT/I2S_RECEIVE)
p07gbar 0:455d5826751b 90 * @param sd The serial data pin
p07gbar 0:455d5826751b 91 * @param fourwiremode True means the peripheral is in 4-wire mode. It borrows WS and CLK from the other half
p07gbar 0:455d5826751b 92 */
p07gbar 0:455d5826751b 93 I2S(bool rxtx, PinName sd, bool fourwiremode);
p07gbar 0:455d5826751b 94
p07gbar 0:455d5826751b 95 /** Create a I2S instance: Only with serial data line and word select line. Four wire mode means this is functional
p07gbar 0:455d5826751b 96 *
p07gbar 0:455d5826751b 97 * @param rxtx Set the I2S instance to be transmit or recieve (I2S_TRANSMIT/I2S_RECEIVE)
p07gbar 0:455d5826751b 98 * @param sd The serial data pin
p07gbar 0:455d5826751b 99 * @param ws The word select pin
p07gbar 0:455d5826751b 100 * @param fourwiremode True means the peripheral is in 4-wire mode. It borrows WS and CLK from the other half
p07gbar 0:455d5826751b 101 */
p07gbar 0:455d5826751b 102 I2S(bool rxtx, PinName sd, PinName ws, bool fourwiremode);
p07gbar 0:455d5826751b 103
p07gbar 0:455d5826751b 104 /** Destroy the I2S instance
p07gbar 0:455d5826751b 105 */
p07gbar 0:455d5826751b 106 ~I2S();
p07gbar 0:455d5826751b 107
p07gbar 0:455d5826751b 108 /** Write to the FIFO
p07gbar 0:455d5826751b 109 *
p07gbar 0:455d5826751b 110 * @param buf[] The buffer of values to write: are bit stuffed in fours
p07gbar 0:455d5826751b 111 * @param len The number of chars to write
p07gbar 0:455d5826751b 112 */
p07gbar 0:455d5826751b 113 void write(char buf[], int len);
p07gbar 0:455d5826751b 114
p07gbar 0:455d5826751b 115 /** Write to the FIFO
p07gbar 0:455d5826751b 116 *
p07gbar 0:455d5826751b 117 * @param buf[] The buffer of values to write: are bit stuffed automatically
p07gbar 0:455d5826751b 118 * @param len The number of chars to write
p07gbar 0:455d5826751b 119 */
p07gbar 0:455d5826751b 120 void write(int buf[], int len);
p07gbar 0:455d5826751b 121
p07gbar 0:455d5826751b 122 /** Read the FIFOs contents
p07gbar 0:455d5826751b 123 *
p07gbar 0:455d5826751b 124 * @return The buffers value.
p07gbar 0:455d5826751b 125 */
p07gbar 0:455d5826751b 126 int read();
p07gbar 0:455d5826751b 127
p07gbar 0:455d5826751b 128 /** Read from the FIFO
p07gbar 0:455d5826751b 129 *
p07gbar 0:455d5826751b 130 * @param buf[] The buffer of values to read: raw bit shifted
p07gbar 0:455d5826751b 131 * @param len The number of chars to read
p07gbar 0:455d5826751b 132 */
p07gbar 0:455d5826751b 133 void read(char buf[], int len);
p07gbar 0:455d5826751b 134
p07gbar 0:455d5826751b 135 /** Read from the FIFO
p07gbar 0:455d5826751b 136 *
p07gbar 0:455d5826751b 137 * @param buf[] The buffer of values to read: sorted to just values
p07gbar 0:455d5826751b 138 * @param len The number of chars to read
p07gbar 0:455d5826751b 139 */
p07gbar 0:455d5826751b 140 void read(int buf[], int len);
p07gbar 0:455d5826751b 141
p07gbar 0:455d5826751b 142 /** Get the maximum number of points of data the FIFO could store
p07gbar 0:455d5826751b 143 *
p07gbar 0:455d5826751b 144 * @return The number of points
p07gbar 0:455d5826751b 145 */
p07gbar 0:455d5826751b 146 int max_fifo_points();
p07gbar 0:455d5826751b 147 /** Switch the peripheral on and off
p07gbar 0:455d5826751b 148 *
p07gbar 0:455d5826751b 149 * @param pwr Power status
p07gbar 0:455d5826751b 150 */
p07gbar 0:455d5826751b 151 void power(bool pwr);
p07gbar 0:455d5826751b 152
p07gbar 0:455d5826751b 153 /** Switch the peripheral between master and slave
p07gbar 0:455d5826751b 154 *
p07gbar 0:455d5826751b 155 * @param mastermode The peripherals master/slave status (I2S_MASTER/I2S_SLAVE)
p07gbar 0:455d5826751b 156 */
p07gbar 0:455d5826751b 157 void masterslave(bool mastermode);
p07gbar 0:455d5826751b 158
p07gbar 0:455d5826751b 159 /** Switch the peripheral between different wordsizes
p07gbar 0:455d5826751b 160 *
p07gbar 0:455d5826751b 161 * @param words The number of bits per word: 8,16,32
p07gbar 0:455d5826751b 162 */
p07gbar 0:455d5826751b 163 void wordsize(int words);
p07gbar 0:455d5826751b 164
p07gbar 0:455d5826751b 165 /** Define the mclk frequency
p07gbar 0:455d5826751b 166 *
p07gbar 0:455d5826751b 167 * @param freq The frequency desired for the mclk
p07gbar 0:455d5826751b 168 */
p07gbar 0:455d5826751b 169 void mclk_freq(int freq);
p07gbar 0:455d5826751b 170
p07gbar 0:455d5826751b 171 /** Define the sample rate
p07gbar 0:455d5826751b 172 *
p07gbar 0:455d5826751b 173 * @param freq The desired sample rate frequency
p07gbar 0:455d5826751b 174 */
p07gbar 0:455d5826751b 175 void frequency(int freq);
p07gbar 0:455d5826751b 176
p07gbar 0:455d5826751b 177 /** Set the level that the fifo interrupts at
p07gbar 0:455d5826751b 178 *
p07gbar 0:455d5826751b 179 * @param level A number between 0 and 7 at which the fifo interrupts
p07gbar 0:455d5826751b 180 */
p07gbar 0:455d5826751b 181 void set_interrupt_fifo_level(int level);
p07gbar 0:455d5826751b 182
p07gbar 0:455d5826751b 183 /** Get the current FIFO level
p07gbar 0:455d5826751b 184 *
p07gbar 0:455d5826751b 185 * @return A number between 0 and 7 the FIFO is currently at
p07gbar 0:455d5826751b 186 */
p07gbar 0:455d5826751b 187 int fifo_level();
p07gbar 0:455d5826751b 188
p07gbar 0:455d5826751b 189 /** Get the current number of samples in the FIFO
p07gbar 0:455d5826751b 190 *
p07gbar 0:455d5826751b 191 * @return A number showing how many samples are in the FIFO
p07gbar 0:455d5826751b 192 */
p07gbar 0:455d5826751b 193 int fifo_points();
p07gbar 0:455d5826751b 194
p07gbar 0:455d5826751b 195 /** Set whether the peripheral is in stereo or mono mode: in mono the perifpheral sends out the same data twice
p07gbar 0:455d5826751b 196 *
p07gbar 0:455d5826751b 197 * @param stereomode Whether the peripheral is in stereo or mono: I2S_STEREO/I2S_MONO
p07gbar 0:455d5826751b 198 */
p07gbar 0:455d5826751b 199 void stereomono(bool stereomode);
p07gbar 0:455d5826751b 200
p07gbar 0:455d5826751b 201 /** Mute the peripheral
p07gbar 0:455d5826751b 202 *
p07gbar 0:455d5826751b 203 */
p07gbar 0:455d5826751b 204 void mute();
p07gbar 0:455d5826751b 205
p07gbar 0:455d5826751b 206 /** Set the mute status of the peripheral
p07gbar 0:455d5826751b 207 *
p07gbar 0:455d5826751b 208 * @param mute_en Set whether the mute is enabled
p07gbar 0:455d5826751b 209 */
p07gbar 0:455d5826751b 210 void mute(bool mute_en);
p07gbar 0:455d5826751b 211
p07gbar 0:455d5826751b 212 /** Stop the peripheral
p07gbar 0:455d5826751b 213 *
p07gbar 0:455d5826751b 214 */
p07gbar 0:455d5826751b 215 void stop();
p07gbar 0:455d5826751b 216
p07gbar 0:455d5826751b 217 /** Start the peripheral
p07gbar 0:455d5826751b 218 *
p07gbar 0:455d5826751b 219 */
p07gbar 0:455d5826751b 220 void start();
p07gbar 0:455d5826751b 221
p07gbar 0:455d5826751b 222 /** Check the Clock and Pin setup went according to plan
p07gbar 0:455d5826751b 223 *
p07gbar 0:455d5826751b 224 * @return Setup okay?
p07gbar 0:455d5826751b 225 */
p07gbar 0:455d5826751b 226 bool setup_ok();
p07gbar 0:455d5826751b 227
p07gbar 0:455d5826751b 228 /** Attach a function to be called when the FIFO triggers
p07gbar 0:455d5826751b 229 *
p07gbar 0:455d5826751b 230 * @param fptr A pointer to the function to be called
p07gbar 0:455d5826751b 231 */
p07gbar 0:455d5826751b 232 void attach(void (*fptr)(void))
p07gbar 0:455d5826751b 233 {
p07gbar 0:455d5826751b 234 if (_rxtx == I2S_TRANSMIT)
p07gbar 0:455d5826751b 235 {
p07gbar 0:455d5826751b 236 I2STXISR.attach(fptr);
p07gbar 0:455d5826751b 237 txisr = true;
p07gbar 0:455d5826751b 238 }
p07gbar 0:455d5826751b 239 else
p07gbar 0:455d5826751b 240 {
p07gbar 0:455d5826751b 241 I2SRXISR.attach(fptr);
p07gbar 0:455d5826751b 242 rxisr = true;
p07gbar 0:455d5826751b 243 }
p07gbar 0:455d5826751b 244 }
p07gbar 0:455d5826751b 245
p07gbar 0:455d5826751b 246 /** Attach a member function to be called when the FIFO triggers
p07gbar 0:455d5826751b 247 *
p07gbar 0:455d5826751b 248 * @param tptr A pointer to the instance of the class
p07gbar 0:455d5826751b 249 * @param mptr A pointer to the member function
p07gbar 0:455d5826751b 250 */
p07gbar 0:455d5826751b 251 template<typename T>
p07gbar 0:455d5826751b 252 void attach(T *tptr, void (T::*mptr)(void))
p07gbar 0:455d5826751b 253 {
p07gbar 0:455d5826751b 254 if (_rxtx == I2S_TRANSMIT)
p07gbar 0:455d5826751b 255 {
p07gbar 0:455d5826751b 256 I2STXISR.attach(tptr, mptr);
p07gbar 0:455d5826751b 257 txisr = true;
p07gbar 0:455d5826751b 258 }
p07gbar 0:455d5826751b 259 else
p07gbar 0:455d5826751b 260 {
p07gbar 0:455d5826751b 261 I2SRXISR.attach(tptr, mptr);
p07gbar 0:455d5826751b 262 rxisr = true;
p07gbar 0:455d5826751b 263 }
p07gbar 0:455d5826751b 264 }
p07gbar 0:455d5826751b 265
p07gbar 0:455d5826751b 266 private:
p07gbar 0:455d5826751b 267
p07gbar 0:455d5826751b 268 void mclk_enable(bool mclk_en);
p07gbar 0:455d5826751b 269
p07gbar 0:455d5826751b 270 void write_registers();
p07gbar 0:455d5826751b 271
p07gbar 0:455d5826751b 272 void pin_setup();
p07gbar 0:455d5826751b 273
p07gbar 0:455d5826751b 274 void fraction_estimator(float in, int * num, int * den);
p07gbar 0:455d5826751b 275
p07gbar 0:455d5826751b 276 float mod(float in);
p07gbar 0:455d5826751b 277
p07gbar 0:455d5826751b 278 void defaulter();
p07gbar 0:455d5826751b 279
p07gbar 0:455d5826751b 280 PinName _sd, _ws, _clk, _mclk;
p07gbar 0:455d5826751b 281 bool ws_d, clk_d, mclk_d;
p07gbar 0:455d5826751b 282 bool _rxtx;
p07gbar 0:455d5826751b 283 bool pwr;
p07gbar 0:455d5826751b 284 bool master;
p07gbar 0:455d5826751b 285 int wordwidth;
p07gbar 0:455d5826751b 286 char wordwidth_code;
p07gbar 0:455d5826751b 287 bool mclk_en;
p07gbar 0:455d5826751b 288 int mclk_frequency;
p07gbar 0:455d5826751b 289 int freq;
p07gbar 0:455d5826751b 290 bool stereo;
p07gbar 0:455d5826751b 291 bool muted;
p07gbar 0:455d5826751b 292 bool stopped;
p07gbar 0:455d5826751b 293 int interrupt_fifo_level;
p07gbar 0:455d5826751b 294 int pin_setup_err;
p07gbar 0:455d5826751b 295 int reg_write_err;
p07gbar 0:455d5826751b 296 bool deallocating;
p07gbar 0:455d5826751b 297 int old_freq;
p07gbar 0:455d5826751b 298
p07gbar 0:455d5826751b 299 bool fourwire;
p07gbar 0:455d5826751b 300
p07gbar 0:455d5826751b 301 int old_pre_num;
p07gbar 0:455d5826751b 302 int old_pre_den;
p07gbar 0:455d5826751b 303 int old_bitrate_div;
p07gbar 0:455d5826751b 304 static void _i2sisr(void);
p07gbar 0:455d5826751b 305
p07gbar 0:455d5826751b 306 static FunctionPointer I2STXISR;
p07gbar 0:455d5826751b 307 static FunctionPointer I2SRXISR;
p07gbar 0:455d5826751b 308
p07gbar 0:455d5826751b 309 static bool txisr;
p07gbar 0:455d5826751b 310 static bool rxisr;
p07gbar 0:455d5826751b 311
p07gbar 0:455d5826751b 312 void write(int bufr[], int bufl[], int len);
p07gbar 0:455d5826751b 313 void read(int bufr[], int bufl[], int len);
p07gbar 0:455d5826751b 314 };
p07gbar 0:455d5826751b 315
p07gbar 0:455d5826751b 316 #endif