Mbed firmware to capture 4 mic inputs and provide data over ethernet.

Dependencies:   EthernetInterface MODDMA mbed-rtos mbed

Committer:
Andrew Pullin
Date:
Wed Jul 30 14:58:05 2014 -0700
Revision:
0:7eb08d1a4037
Initial commit of files

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Andrew Pullin 0:7eb08d1a4037 1 /*This code is based off of Andy Kirkham's
Andrew Pullin 0:7eb08d1a4037 2 *work making MODDMA.
Andrew Pullin 0:7eb08d1a4037 3 *http://mbed.org/users/AjK/code/MODDMA/
Andrew Pullin 0:7eb08d1a4037 4 */
Andrew Pullin 0:7eb08d1a4037 5 #include "mbed.h"
Andrew Pullin 0:7eb08d1a4037 6 #include "MODDMA.h"
Andrew Pullin 0:7eb08d1a4037 7 #include "string.h"
Andrew Pullin 0:7eb08d1a4037 8 #include "EthernetInterface.h"
Andrew Pullin 0:7eb08d1a4037 9
Andrew Pullin 0:7eb08d1a4037 10 #define SAMPLE_BUFFER_LENGTH 32
Andrew Pullin 0:7eb08d1a4037 11
Andrew Pullin 0:7eb08d1a4037 12 DigitalOut led1(LED1);
Andrew Pullin 0:7eb08d1a4037 13 DigitalOut led2(LED2);
Andrew Pullin 0:7eb08d1a4037 14
Andrew Pullin 0:7eb08d1a4037 15 MODDMA dma;
Andrew Pullin 0:7eb08d1a4037 16 const int BROADCAST_PORT = 58083;
Andrew Pullin 0:7eb08d1a4037 17
Andrew Pullin 0:7eb08d1a4037 18 // ISR set's this when transfer complete.
Andrew Pullin 0:7eb08d1a4037 19 bool dmaTransferComplete = false;
Andrew Pullin 0:7eb08d1a4037 20
Andrew Pullin 0:7eb08d1a4037 21 // Function prototypes for IRQ callbacks.
Andrew Pullin 0:7eb08d1a4037 22 // See definitions following main() below.
Andrew Pullin 0:7eb08d1a4037 23 void TC0_callback(void);
Andrew Pullin 0:7eb08d1a4037 24 void ERR0_callback(void);
Andrew Pullin 0:7eb08d1a4037 25
Andrew Pullin 0:7eb08d1a4037 26 int main() {
Andrew Pullin 0:7eb08d1a4037 27 //Set up the ethernet to broadcast
Andrew Pullin 0:7eb08d1a4037 28 EthernetInterface eth;
Andrew Pullin 0:7eb08d1a4037 29 eth.init(); //Use DHCP
Andrew Pullin 0:7eb08d1a4037 30 eth.connect();
Andrew Pullin 0:7eb08d1a4037 31
Andrew Pullin 0:7eb08d1a4037 32 UDPSocket sock;
Andrew Pullin 0:7eb08d1a4037 33 sock.init();
Andrew Pullin 0:7eb08d1a4037 34 sock.set_broadcasting();
Andrew Pullin 0:7eb08d1a4037 35
Andrew Pullin 0:7eb08d1a4037 36 Endpoint broadcast;
Andrew Pullin 0:7eb08d1a4037 37 broadcast.set_address("255.255.255.255", BROADCAST_PORT);
Andrew Pullin 0:7eb08d1a4037 38
Andrew Pullin 0:7eb08d1a4037 39 // Create a buffer to hold the ADC samples and clear it.
Andrew Pullin 0:7eb08d1a4037 40 // Note, we are going to sample two ADC inputs so they
Andrew Pullin 0:7eb08d1a4037 41 // end up in this buffer "interleaved". So you will want
Andrew Pullin 0:7eb08d1a4037 42 // a buffer twice this size to a real life given sample
Andrew Pullin 0:7eb08d1a4037 43 // frequency. See the printf() output for details.
Andrew Pullin 0:7eb08d1a4037 44 uint32_t adcInputBuffer[SAMPLE_BUFFER_LENGTH];
Andrew Pullin 0:7eb08d1a4037 45 memset(adcInputBuffer, 0, sizeof(adcInputBuffer));
Andrew Pullin 0:7eb08d1a4037 46
Andrew Pullin 0:7eb08d1a4037 47 // We use the ADC irq to trigger DMA and the manual says
Andrew Pullin 0:7eb08d1a4037 48 // that in this case the NVIC for ADC must be disabled.
Andrew Pullin 0:7eb08d1a4037 49 NVIC_DisableIRQ(ADC_IRQn);
Andrew Pullin 0:7eb08d1a4037 50
Andrew Pullin 0:7eb08d1a4037 51 // Power up the ADC and set PCLK
Andrew Pullin 0:7eb08d1a4037 52 LPC_SC->PCONP |= (1UL << 12);
Andrew Pullin 0:7eb08d1a4037 53 LPC_SC->PCLKSEL0 &= ~(3UL << 24); // PCLK = CCLK/4 96M/4 = 24MHz
Andrew Pullin 0:7eb08d1a4037 54
Andrew Pullin 0:7eb08d1a4037 55 // Enable the ADC, 12MHz, ADC0.0 & .1
Andrew Pullin 0:7eb08d1a4037 56 LPC_ADC->ADCR = (1UL << 21) | (1UL << 8) | (3UL << 0);
Andrew Pullin 0:7eb08d1a4037 57
Andrew Pullin 0:7eb08d1a4037 58 // Set the pin functions to ADC
Andrew Pullin 0:7eb08d1a4037 59 LPC_PINCON->PINSEL1 &= ~(3UL << 14); /* P0.23, Mbed p15. */
Andrew Pullin 0:7eb08d1a4037 60 LPC_PINCON->PINSEL1 |= (1UL << 14);
Andrew Pullin 0:7eb08d1a4037 61 LPC_PINCON->PINSEL1 &= ~(3UL << 16); /* P0.24, Mbed p16. */
Andrew Pullin 0:7eb08d1a4037 62 LPC_PINCON->PINSEL1 |= (1UL << 16);
Andrew Pullin 0:7eb08d1a4037 63
Andrew Pullin 0:7eb08d1a4037 64 // Prepare an ADC configuration.
Andrew Pullin 0:7eb08d1a4037 65 MODDMA_Config *conf = new MODDMA_Config;
Andrew Pullin 0:7eb08d1a4037 66 conf
Andrew Pullin 0:7eb08d1a4037 67 ->channelNum ( MODDMA::Channel_0 )
Andrew Pullin 0:7eb08d1a4037 68 ->srcMemAddr ( 0 )
Andrew Pullin 0:7eb08d1a4037 69 ->dstMemAddr ( (uint32_t)adcInputBuffer )
Andrew Pullin 0:7eb08d1a4037 70 ->transferSize ( SAMPLE_BUFFER_LENGTH )
Andrew Pullin 0:7eb08d1a4037 71 ->transferType ( MODDMA::p2m )
Andrew Pullin 0:7eb08d1a4037 72 ->transferWidth ( MODDMA::word )
Andrew Pullin 0:7eb08d1a4037 73 ->srcConn ( MODDMA::ADC )
Andrew Pullin 0:7eb08d1a4037 74 ->dstConn ( 0 )
Andrew Pullin 0:7eb08d1a4037 75 ->dmaLLI ( 0 )
Andrew Pullin 0:7eb08d1a4037 76 ->attach_tc ( &TC0_callback )
Andrew Pullin 0:7eb08d1a4037 77 ->attach_err ( &ERR0_callback )
Andrew Pullin 0:7eb08d1a4037 78 ; // end conf.
Andrew Pullin 0:7eb08d1a4037 79
Andrew Pullin 0:7eb08d1a4037 80 // Prepare configuration.
Andrew Pullin 0:7eb08d1a4037 81 dma.Setup( conf );
Andrew Pullin 0:7eb08d1a4037 82
Andrew Pullin 0:7eb08d1a4037 83 // Enable configuration.
Andrew Pullin 0:7eb08d1a4037 84 dma.Enable( conf );
Andrew Pullin 0:7eb08d1a4037 85
Andrew Pullin 0:7eb08d1a4037 86 // Enable ADC irq flag (to DMA).
Andrew Pullin 0:7eb08d1a4037 87 // Note, don't set the individual flags,
Andrew Pullin 0:7eb08d1a4037 88 // just set the global flag.
Andrew Pullin 0:7eb08d1a4037 89 LPC_ADC->ADINTEN = 0x100;
Andrew Pullin 0:7eb08d1a4037 90
Andrew Pullin 0:7eb08d1a4037 91 // Enable burst mode on inputs 0 and 1.
Andrew Pullin 0:7eb08d1a4037 92 LPC_ADC->ADCR |= (1UL << 16);
Andrew Pullin 0:7eb08d1a4037 93
Andrew Pullin 0:7eb08d1a4037 94 char out_buffer[SAMPLE_BUFFER_LENGTH];
Andrew Pullin 0:7eb08d1a4037 95
Andrew Pullin 0:7eb08d1a4037 96 while (1) {
Andrew Pullin 0:7eb08d1a4037 97 // When transfer complete do this block.
Andrew Pullin 0:7eb08d1a4037 98 if (dmaTransferComplete) {
Andrew Pullin 0:7eb08d1a4037 99 delete conf; // No memory leaks, delete the configuration.
Andrew Pullin 0:7eb08d1a4037 100 dmaTransferComplete = false;
Andrew Pullin 0:7eb08d1a4037 101 for (int i = 0; i < SAMPLE_BUFFER_LENGTH; i++) {
Andrew Pullin 0:7eb08d1a4037 102 //int channel = (adcInputBuffer[i] >> 24) & 0x7;
Andrew Pullin 0:7eb08d1a4037 103 int iVal = (adcInputBuffer[i] >> 4) & 0xFFF;
Andrew Pullin 0:7eb08d1a4037 104 double fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v
Andrew Pullin 0:7eb08d1a4037 105 memcpy(&out_buffer,&fVal,sizeof(fVal));
Andrew Pullin 0:7eb08d1a4037 106 }
Andrew Pullin 0:7eb08d1a4037 107 }
Andrew Pullin 0:7eb08d1a4037 108 sock.sendTo(broadcast, out_buffer, sizeof(out_buffer));
Andrew Pullin 0:7eb08d1a4037 109 wait(0.25);
Andrew Pullin 0:7eb08d1a4037 110 }
Andrew Pullin 0:7eb08d1a4037 111 }
Andrew Pullin 0:7eb08d1a4037 112
Andrew Pullin 0:7eb08d1a4037 113 // Configuration callback on TC
Andrew Pullin 0:7eb08d1a4037 114 void TC0_callback(void) {
Andrew Pullin 0:7eb08d1a4037 115
Andrew Pullin 0:7eb08d1a4037 116 MODDMA_Config *config = dma.getConfig();
Andrew Pullin 0:7eb08d1a4037 117
Andrew Pullin 0:7eb08d1a4037 118 // Disbale burst mode and switch off the IRQ flag.
Andrew Pullin 0:7eb08d1a4037 119 LPC_ADC->ADCR &= ~(1UL << 16);
Andrew Pullin 0:7eb08d1a4037 120 LPC_ADC->ADINTEN = 0;
Andrew Pullin 0:7eb08d1a4037 121
Andrew Pullin 0:7eb08d1a4037 122 // Finish the DMA cycle by shutting down the channel.
Andrew Pullin 0:7eb08d1a4037 123 dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
Andrew Pullin 0:7eb08d1a4037 124 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
Andrew Pullin 0:7eb08d1a4037 125
Andrew Pullin 0:7eb08d1a4037 126 // Tell main() while(1) loop to print the results.
Andrew Pullin 0:7eb08d1a4037 127 dmaTransferComplete = true;
Andrew Pullin 0:7eb08d1a4037 128
Andrew Pullin 0:7eb08d1a4037 129 // Switch on LED2 to show transfer complete.
Andrew Pullin 0:7eb08d1a4037 130 led2 = 1;
Andrew Pullin 0:7eb08d1a4037 131
Andrew Pullin 0:7eb08d1a4037 132 // Clear DMA IRQ flags.
Andrew Pullin 0:7eb08d1a4037 133 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
Andrew Pullin 0:7eb08d1a4037 134 if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
Andrew Pullin 0:7eb08d1a4037 135 }
Andrew Pullin 0:7eb08d1a4037 136
Andrew Pullin 0:7eb08d1a4037 137 // Configuration callback on Error
Andrew Pullin 0:7eb08d1a4037 138 void ERR0_callback(void) {
Andrew Pullin 0:7eb08d1a4037 139 // Switch off burst conversions.
Andrew Pullin 0:7eb08d1a4037 140 LPC_ADC->ADCR |= ~(1UL << 16);
Andrew Pullin 0:7eb08d1a4037 141 LPC_ADC->ADINTEN = 0;
Andrew Pullin 0:7eb08d1a4037 142 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
Andrew Pullin 0:7eb08d1a4037 143 }