Teensy3 I2S with DMA

Status
Not open for further replies.
Hi All

Thanks, Hugh for giving me the heads up about your awesome progress! Can't wait to get this working.
I'm having trouble compiling so far, using Arduino 1.0.3 and Teensyduino 1.12:

Code:
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In member function 'void I2S_class::start()':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:81:26: error: 'I2S_RCSR_RE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:82:26: error: 'I2S_RCSR_BCE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:83:26: error: 'I2S_RCSR_FRDE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:89:26: error: 'I2S_TCSR_TE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:90:26: error: 'I2S_TCSR_BCE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:91:26: error: 'I2S_TCSR_FRDE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:101:26: error: 'I2S_RCSR_RE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:102:26: error: 'I2S_RCSR_BCE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:103:26: error: 'I2S_RCSR_FRIE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:110:26: error: 'I2S_TCSR_TE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:111:26: error: 'I2S_TCSR_BCE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:112:26: error: 'I2S_TCSR_FRIE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In member function 'void I2S_class::clock_init(unsigned char)':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:234:34: error: 'I2S_MCR_MICS' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:240:34: error: 'I2S_MCR_MICS' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:240:38: error: 'I2S_MCR_MOE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:248:43: error: 'I2S_MDR_FRACT' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:248:64: error: 'I2S_MDR_DIVIDE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In member function 'void I2S_class::i2s_transmit_init()':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:291:20: error: 'I2S_TCSR_TE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:300:35: error: 'I2S_TCR1_TFW' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:302:33: error: 'I2S_TCR2_SYNC' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:303:18: error: 'I2S_TCR2_BCP' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:310:18: error: 'I2S_TCR3_TCE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:312:36: error: 'I2S_TCR4_FRSZ' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:313:36: error: 'I2S_TCR4_SYWD' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:314:18: error: 'I2S_TCR4_MF' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:315:18: error: 'I2S_TCR4_FSE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:317:18: error: 'I2S_TCR4_FSD' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:320:35: error: 'I2S_TCR5_W0W' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:321:35: error: 'I2S_TCR5_WNW' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:322:35: error: 'I2S_TCR5_FBT' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In member function 'void I2S_class::i2s_receive_init()':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:328:20: error: 'I2S_RCSR_RE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:337:35: error: 'I2S_RCR1_RFW' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:339:33: error: 'I2S_RCR2_SYNC' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:340:18: error: 'I2S_TCR2_BCP' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:347:18: error: 'I2S_RCR3_RCE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:349:36: error: 'I2S_RCR4_FRSZ' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:350:36: error: 'I2S_RCR4_SYWD' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:351:18: error: 'I2S_RCR4_MF' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:352:18: error: 'I2S_RCR4_FSE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:354:18: error: 'I2S_RCR4_FSD' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:357:35: error: 'I2S_RCR5_W0W' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:358:35: error: 'I2S_RCR5_WNW' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:359:35: error: 'I2S_RCR5_FBT' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In member function 'void I2S_class::i2s_tx_callback()':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:367:20: error: 'I2S_TCSR_FEF' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:368:20: error: 'I2S_TCSR_SEF' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In member function 'void I2S_class::i2s_rx_callback()':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:382:20: error: 'I2S_RCSR_FEF' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:383:20: error: 'I2S_RCSR_SEF' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In member function 'void I2S_class::dma_transmit_init()':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:446:23: error: 'DMA_CSR_ACTIVE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:458:14: error: 'DMA_CR_EMLM' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:460:14: error: 'DMA_CR_ERCA' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:467:46: error: 'DMA_ATTR_SMOD' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:468:46: error: 'DMA_ATTR_SIZE_16BIT' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:468:65: error: 'DMA_ATTR_SSIZE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:469:46: error: 'DMA_ATTR_DMOD' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:470:65: error: 'DMA_ATTR_DSIZE' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:476:49: error: 'DMA_CITER_MASK' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:477:49: error: 'DMA_BITER_MASK' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:478:31: error: 'DMA_CSR_INTMAJOR' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:479:44: error: 'DMA_CSR_BWC' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:482:15: error: 'DMA_ERQ_ERQ0' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:483:31: error: 'DMA_SERQ_SERQ' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In member function 'void I2S_class::dma_start()':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:505:39: error: 'DMA_SERQ_SERQ' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In member function 'void I2S_class::dma_stop()':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:511:39: error: 'DMA_CERQ_CERQ' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In function 'void dma_ch0_isr()':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:567:31: error: 'DMA_CINT_CINT' was not declared in this scope
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp: In function 'void dma_ch1_isr()':
/Users/alexandersmith/Documents/Arduino/libraries/i2s/i2s.cpp:573:31: error: 'DMA_CINT_CINT' was not declared in this scope

Probably something stupid that I'm doing?
Thanks for any advice, so excited to make some noise!!

Alex
 
Hey Guys,

Getting closer! I needed to copy the modified mk20dx128.h into arduino/hardware/teensy/cores/teensy3 as stated in this thread and was able to compile!

Still not getting any sound, here is a snap of my setup. Should I not have ADCL or/and DACL wired up?

I can almost hear the synth just around the corner ;)
Many thanks
Alex

teensy3.jpg
 
Last edited:
nice job here, alex; are you too using a Wolfson chip? Did you design the board connected to the teensy?
 
For the pins, try adding DACL to pin 4, for the word clock (duh, my examples don't tell you this).
Are you using the DMA interface or straight I2S? Try the DMA-based example sketch. I think the I2S sample is broken (sorry - I haven't been in a position to work on this much very recently).
 
Last edited:
HI Hugh,

Thanks for your reply, still no luck I'm afraid. Using the i2s_tx_dma_wm8731 example sketch.

Should MISO or ADCL be hooked up to teensy too? Cheers
Alex
 
I'll have to check my hardware when I get home :) Tomorrow some time.

Meanwhile here's a copy of my additive-synthesizer code, if anyone's interested in hacking on it. It doesn't really work yet, but I figure it's never aimed at being a commercial product, so I should just publish it already. https://github.com/hughpyle/directsynth
 
I got it wrong in the examples' comments. You have SCK to pin 11 (MCLK), but it should be to the bit-clock, pin 9 (BCLK).

Here's the full list to check:
SCK -> Teensy 9 (I2S0_TX_BCLK)
MISO -> not connected for this transmit-only example
MOSI -> Teensy 3 (I2S0_TXD0). Can also be switched to pin 22.
ADCL -> not connected for this transmit-only example
DACL -> Teensy 4 (I2S0_TX_FS). Can also be switched to pin 23 or 25
SDA -> Teensy 18 (I2C0_SDA)
SCL -> Teensy 19 (I2C0_SCL)
3.3V -> Teensy 3.3v
GND -> Teensy GND
 
YESSSS! THANKS SO MUCH

I'm getting beautiful sine waves now! Thanks so much for posting your synth too. I prefer to "figure it out" from your sine example but appreciate your generosity.

I'll be sure to post my results. Hoping to make some kind of monophonic bassey synth

Cheers
Alex
 
Hi again,

Having a lot of fun making noises here - quick question: I'm used to working with float values with audio (0-1 range).
I am doing signal*32767 to convert it to Q15 - does that sound correct? no pun intended

Cheers
Alex
 
Yes, close enough. Q15 represents a fraction with one "sign" bit and 15 "fraction" bits; the values go from -1.0 (0x8000 or 32768) to nearly +1.0 (0x7FFF or +32767). Usually of course the exact value won't be critical. But dealing with "not quite +1.0" is a bit of a pain sometimes.

You need to be a bit careful with multiplication. Multiply two Q15 values produces a Q30 value. To get that back to a Q15, first shift left one bit (making a Q31) and then use the high 16-bit word. This pdf explains better than I can:
http://www.cs.washington.edu/education/courses/cse467/08au/pdfs/lectures/11-FixedPointArithmetic.pdf

The ARM processor has some quite nice built-in functions that can add Q15 types without overflow, "saturating" (clipping) instead.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CHDBHGFC.html
 
Nothing appears in my windows terminal as an output using WM8731 library

That's great! I hope you find the library useful. If you're rolling your own, the main trick is to not set the "transmit enable" flag until everything else is set up ;-)
You may find that my clock setup doesn't work for your application. It was done pretty much by trial and error with the Wolfson codec and a cheap single-channel oscilloscope... the only reliable way I could run a data stream was to set up as 32-bit data. YMMV.

Do feel free to fork my library/example code. I'll be working on this very much part-time -- I expect my first project could take months, no particular rush -- so even if you send me pull requests with a big refactoring of the library that's just fine. Especially to add Receive functions (I'm only using Transmit right now).

I'd love to hear more baout the sort of projects you're building, too! Mine, in sequence I think:
- A tiny midi synth (additive synthesis, with a decent range of stringlike & drumlike sounds, but polyphony will be limited by how efficient I can code)
- A high-as-possible-quality S/PDIF digital crossover
- Head-tracking binaural something or other, maybe...

Hugh


I am trying to make teensy3 to communicate with WM8731 codec through i2s ,first I tried the WM8731 code ,as you suggested , just to make sure that the clock is going to work and the code was supposed to print some results such as register address ,here it is what should be printed out:
Serial.print( "WM8731 register 0x" );
Serial.print( reg, HEX );
Serial.print( " = 0x" );
Serial.println( value, HEX );
but all i have gotten is a white windows terminal without anything printed on it ,so i am not sure if it is working ,but most likely not,to go for the next stage through your i2s library.I just would like to ask if you have faced such a problem before you succeeded to apply your i2s library completely?It should be mentioned that first i had an error which had an issue with setup and loop that have been discussed a lot in the forum about it,the thing that i did to get rid of the error was just removing the part in where set up and loop have been written because i thought that i wouldn't be needing this part ,but honestly i am not sure if i did right or wrong to do remove them?anyways i got rid of the error in that regard but unfortunately no output i got.I appreciate your time to read my inquiry.
Regards,
Emi
 
Last edited:
Are you using the Mikro breakout board? If so, you should try run the sample sketch -- it should make sound right away.

You're right that starting with the I2C communication is a good strategy. But if you see nothing on the serial monitor, there could be some more basic problem. Have you tried just writing a simple sketch with no audio or i2c, just printing to serial?
 
Are you using the Mikro breakout board? If so, you should try run the sample sketch -- it should make sound right away.

You're right that starting with the I2C communication is a good strategy. But if you see nothing on the serial monitor, there could be some more basic problem. Have you tried just writing a simple sketch with no audio or i2c, just printing to serial?

Thanks for replying Hyple,no i am using wm8731 it is Wolfson codec here it is the link for this codec http://www.wolfsonmicro.com/products/codecs/WM8731/
I should say that yes i tried simple audioinputoutput example of the built-in library and it worked i could see the results on the serial monitor.i am new in this and it is more troublesome than i could fix it.I truly appreciate if you could send me your library for the entire i2c you made ,the one you can send right clock and data from teensy3 to Wm8731 codec.will you?if it is so, here is my email goynic@gmail.com .
Regards,
Emi
 
The i2c library that I'm using to control WM8731 is here: https://github.com/hughpyle/machinesalem-arduino-libs/tree/master/WM8731
The i2c interface is not used for audio data. The i2s interface does that.
So far I have only tested the i2s interface with a codec in "master mode" and 12.288MHz clock, and a 48kHz audio sampling rate. Soon I hope to try with the Open Music Labs codec shield, which is WM8731 in "slave" mode and 11.2896MHz master clock, which is suitable for 44.1kHz audio.
 
Has anyone got this working with the Audio Codec Shield?
I believe I have it all hooked up correctly though I don't know about DACL. Does that go to SS? The codec shield has DACL and ADCL tied together.
I see activity on SCK, MOIS and DACL the but not SDA or SCL

One odd this is that when I tried to test if the code was working I didn't see 'nnn' changing in either of the included examples.

Thanks!
 
Yeah I don't think the codec shield will work with the code as is. I got one of the mikro breakouts and it works fine except for one thing.
I have to take the SCK line in and out of the pin for it to work. Sometimes it's good after uploading, sometimes I need to plugg it in a few times as the audio will be distorted or not in one of the channels.
 
Right, the library doesn't work with Open Music Labs codec shield yet. I got one and hope to spend some time this weekend working on the code. It looks like nice hardware.

I wonder what's up with your SCK issue. I've not had distortion-type issues at all.
 
I wonder what's up with your SCK issue. I've not had distortion-type issues at all.

Yeah it's odd. I can never get both channels to work at the same time but one usually works and the other is silent.
It sounds and looks like the the waves are being wrapped around past 64000. I've tried making a wave table and using DDS and it does the same thing.
I've also changed the clock type but it still acts pretty much the same.

It doesn't seem like a bad connection as it's stable.
 
I just checked in a change that makes the OML codec shield work. I think it may still be "wrong" (not deriving the clocks correctly) and I didn't regression-test the Mikro board, but it makes sound... which is all I can do right now :) More later.
 
Hello,

I'm a newbie here. I found this thread and I'm very interested in what you do. I have a couple of questions, just wondering:
- how many audio input/ouput can a single teensy3 handle?
- do you think a USB class-compliant audio card can be made with a teensy, some audio boards, and the code you are writing?

Cheers,

stéphane
 
I just checked in a change that makes the OML codec shield work. I think it may still be "wrong" (not deriving the clocks correctly) and I didn't regression-test the Mikro board, but it makes sound... which is all I can do right now :) More later.

Thanks!
I haven't had any clock problems with this version.

I see you added recieve but I'm not understanding how "I2SRx0.begin" works. Any hints?
 
Last edited:
I've got a nice basis for a multi-voice wavetable synth working but it seems that in DMA mode IntervalTimer won't work.
In non-DMA they work fine but then only so much can happen in the callback.
 
any of you been able to use ADC?
I have tried to record with the receipt functions of hpyle (functions i2s_RX)
I have not any result
the buffer that records always gets 0
can someone help me?
 
Status
Not open for further replies.
Back
Top