DMA_play_from_header.ino
1 #include "Adafruit_MP3.h" 2 #include "sine.h" 3 4 #include <Adafruit_ZeroDMA.h> 5 #include "utility/dma.h" 6 7 #define VOLUME_MAX 2047 8 9 Adafruit_ZeroDMA myDMA; 10 ZeroDMAstatus stat; // DMA status codes returned by some functions 11 Adafruit_MP3_DMA player; 12 DmacDescriptor *desc; 13 14 //the output data buffers 15 int16_t *ping, *pong; 16 17 uint8_t *currentPtr; 18 uint32_t thisManyBytesLeft; 19 20 //this gets called when the player wants more data 21 int getMoreData(uint8_t *writeHere, int thisManyBytes){ 22 int toWrite = min(thisManyBytesLeft, thisManyBytes); 23 memcpy(writeHere, currentPtr, toWrite); 24 currentPtr += toWrite; 25 thisManyBytesLeft -= toWrite; 26 return toWrite; 27 } 28 29 30 //this will get called when data has been decoded 31 void decodeCallback(int16_t *data, int len){ 32 for(int i=0; i<len; i++){ 33 int val = map(*data, -32768, 32767, 0, VOLUME_MAX); 34 *data++ = val; 35 } 36 } 37 38 39 void dma_callback(Adafruit_ZeroDMA *dma) { 40 41 //try to fill the next buffer 42 if(player.fill()){ 43 //stop 44 myDMA.abort(); 45 } 46 } 47 48 // the setup routine runs once when you press reset: 49 void setup() { 50 51 //set up the DMA channel 52 myDMA.setTrigger(MP3_DMA_TRIGGER); 53 myDMA.setAction(DMA_TRIGGER_ACTON_BEAT); 54 stat = myDMA.allocate(); 55 56 //ask for the buffers we're going to use 57 player.getBuffers(&ping, &pong); 58 59 //make the descriptors 60 desc = myDMA.addDescriptor( 61 ping, // move data from here 62 (void *)(&DAC->DATA[0]), // to here (M4) 63 MP3_OUTBUF_SIZE, // this many... 64 DMA_BEAT_SIZE_HWORD, // bytes/hword/words 65 true, // increment source addr? 66 false); // increment dest addr? 67 desc->BTCTRL.bit.BLOCKACT = DMA_BLOCK_ACTION_INT; 68 69 desc = myDMA.addDescriptor( 70 pong, // move data from here 71 (void *)(&DAC->DATA[0]), // to here (M4) 72 MP3_OUTBUF_SIZE, // this many... 73 DMA_BEAT_SIZE_HWORD, // bytes/hword/words 74 true, // increment source addr? 75 false); // increment dest addr? 76 desc->BTCTRL.bit.BLOCKACT = DMA_BLOCK_ACTION_INT; 77 78 //make the descriptor list loop 79 myDMA.loop(true); 80 myDMA.setCallback(dma_callback); 81 82 //set the DAC to the center of the range 83 analogWrite(A0, 2048); 84 85 currentPtr = (uint8_t*)sine_mp3; 86 thisManyBytesLeft = sizeof(sine_mp3); 87 88 //begin the player 89 player.begin(); 90 91 //this will be how the player asks for data 92 player.setBufferCallback(getMoreData); 93 94 //this will be how the player asks you to clean the data 95 player.setDecodeCallback(decodeCallback); 96 97 player.play(); //this will automatically fill the first buffer 98 99 //the DMA controller will dictate what happens from here on out 100 myDMA.startJob(); 101 } 102 103 // the loop routine runs over and over again forever: 104 void loop() { 105 106 }