modification of Andrew Kirkhams MODDMA code to send packets over Ethernet and using multiple ADC channels

Dependencies:   EthernetInterface MODDMA mbed-rtos mbed

Committer:
michaelcoe
Date:
Tue Aug 05 22:06:11 2014 +0000
Revision:
0:68a1564919d0
Initial Commit

Who changed what in which revision?

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