Dependencies:   mbed NetServicesMin

Committer:
fernya
Date:
Mon Jun 18 03:59:39 2012 +0000
Revision:
0:aa9ebbd3715f
Beta

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fernya 0:aa9ebbd3715f 1 /*
fernya 0:aa9ebbd3715f 2 * Demonstrates sending a buffer repeatedly to the DAC using DMA.
fernya 0:aa9ebbd3715f 3 * Connect an oscilloscope to Mbed pin 18. This example doesn't
fernya 0:aa9ebbd3715f 4 * output anything else (nothing on any serial ports).
fernya 0:aa9ebbd3715f 5 */
fernya 0:aa9ebbd3715f 6 #include "mbed.h"
fernya 0:aa9ebbd3715f 7
fernya 0:aa9ebbd3715f 8 #include "MODDMA.h"
fernya 0:aa9ebbd3715f 9
fernya 0:aa9ebbd3715f 10 #include "EthernetNetIf.h"
fernya 0:aa9ebbd3715f 11 #include "ipaddr.h"
fernya 0:aa9ebbd3715f 12 #include "UDPSocket.h"
fernya 0:aa9ebbd3715f 13
fernya 0:aa9ebbd3715f 14 #include "fifo.h"
fernya 0:aa9ebbd3715f 15 #include "rtp.h"
fernya 0:aa9ebbd3715f 16
fernya 0:aa9ebbd3715f 17 // Make the buffer size match the number of degrees
fernya 0:aa9ebbd3715f 18 // in a circle since we are going to output a sinewave.
fernya 0:aa9ebbd3715f 19 #define BUFFER_SIZE 300
fernya 0:aa9ebbd3715f 20
fernya 0:aa9ebbd3715f 21 // Set DAC output power mode.
fernya 0:aa9ebbd3715f 22 #define DAC_POWER_MODE (1 << 16)
fernya 0:aa9ebbd3715f 23
fernya 0:aa9ebbd3715f 24 DigitalOut led1(LED1);
fernya 0:aa9ebbd3715f 25 DigitalOut led2(LED2);
fernya 0:aa9ebbd3715f 26 DigitalOut led3(LED3);
fernya 0:aa9ebbd3715f 27 DigitalOut led4(LED4);
fernya 0:aa9ebbd3715f 28
fernya 0:aa9ebbd3715f 29 volatile int life_counter = 0;
fernya 0:aa9ebbd3715f 30
fernya 0:aa9ebbd3715f 31 EthernetNetIf eth;
fernya 0:aa9ebbd3715f 32 UDPSocket data_sock;
fernya 0:aa9ebbd3715f 33
fernya 0:aa9ebbd3715f 34 fifo circ_buf;
fernya 0:aa9ebbd3715f 35 char packet_buf[512] = {0};
fernya 0:aa9ebbd3715f 36 struct rtp_header head;
fernya 0:aa9ebbd3715f 37 int play[2][40];
fernya 0:aa9ebbd3715f 38
fernya 0:aa9ebbd3715f 39 AnalogOut signal(p18);
fernya 0:aa9ebbd3715f 40 Timer timeout;
fernya 0:aa9ebbd3715f 41 MODDMA dma;
fernya 0:aa9ebbd3715f 42 MODDMA_Config *conf0, *conf1;
fernya 0:aa9ebbd3715f 43
fernya 0:aa9ebbd3715f 44 void TC0_callback(void);
fernya 0:aa9ebbd3715f 45 void ERR0_callback(void);
fernya 0:aa9ebbd3715f 46
fernya 0:aa9ebbd3715f 47 void TC1_callback(void);
fernya 0:aa9ebbd3715f 48 void ERR1_callback(void);
fernya 0:aa9ebbd3715f 49
fernya 0:aa9ebbd3715f 50 int ethInit(void);
fernya 0:aa9ebbd3715f 51 int udpInit(void);
fernya 0:aa9ebbd3715f 52 void UDPReceive(UDPSocketEvent e);
fernya 0:aa9ebbd3715f 53
fernya 0:aa9ebbd3715f 54 int main() {
fernya 0:aa9ebbd3715f 55
fernya 0:aa9ebbd3715f 56 //serial initialization
fernya 0:aa9ebbd3715f 57 Serial pc(USBTX, USBRX);
fernya 0:aa9ebbd3715f 58 pc.baud(115200);
fernya 0:aa9ebbd3715f 59 //serial init done
fernya 0:aa9ebbd3715f 60
fernya 0:aa9ebbd3715f 61 ethInit();
fernya 0:aa9ebbd3715f 62 udpInit();
fernya 0:aa9ebbd3715f 63
fernya 0:aa9ebbd3715f 64 // Prepare the GPDMA system for buffer0.
fernya 0:aa9ebbd3715f 65 conf0 = new MODDMA_Config;
fernya 0:aa9ebbd3715f 66 conf0
fernya 0:aa9ebbd3715f 67 ->channelNum ( MODDMA::Channel_0 )
fernya 0:aa9ebbd3715f 68 ->srcMemAddr ( (uint32_t) &play[0] )
fernya 0:aa9ebbd3715f 69 ->dstMemAddr ( MODDMA::DAC )
fernya 0:aa9ebbd3715f 70 ->transferSize ( 40 )
fernya 0:aa9ebbd3715f 71 ->transferType ( MODDMA::m2p )
fernya 0:aa9ebbd3715f 72 ->dstConn ( MODDMA::DAC )
fernya 0:aa9ebbd3715f 73 ->attach_tc ( &TC0_callback )
fernya 0:aa9ebbd3715f 74 ->attach_err ( &ERR0_callback )
fernya 0:aa9ebbd3715f 75 ; // config end
fernya 0:aa9ebbd3715f 76
fernya 0:aa9ebbd3715f 77 // Prepare the GPDMA system for buffer1.
fernya 0:aa9ebbd3715f 78 conf1 = new MODDMA_Config;
fernya 0:aa9ebbd3715f 79 conf1
fernya 0:aa9ebbd3715f 80 ->channelNum ( MODDMA::Channel_1 )
fernya 0:aa9ebbd3715f 81 ->srcMemAddr ( (uint32_t) &play[1] )
fernya 0:aa9ebbd3715f 82 ->dstMemAddr ( MODDMA::DAC )
fernya 0:aa9ebbd3715f 83 ->transferSize ( 40 )
fernya 0:aa9ebbd3715f 84 ->transferType ( MODDMA::m2p )
fernya 0:aa9ebbd3715f 85 ->dstConn ( MODDMA::DAC )
fernya 0:aa9ebbd3715f 86 ->attach_tc ( &TC1_callback )
fernya 0:aa9ebbd3715f 87 ->attach_err ( &ERR1_callback )
fernya 0:aa9ebbd3715f 88 ; // config end
fernya 0:aa9ebbd3715f 89
fernya 0:aa9ebbd3715f 90
fernya 0:aa9ebbd3715f 91 // Calculating the transfer frequency:
fernya 0:aa9ebbd3715f 92 // By default, the Mbed library sets the PCLK_DAC clock value
fernya 0:aa9ebbd3715f 93 // to 24MHz.
fernya 0:aa9ebbd3715f 94
fernya 0:aa9ebbd3715f 95 LPC_DAC->DACCNTVAL = 3000; // 24e6/8000
fernya 0:aa9ebbd3715f 96
fernya 0:aa9ebbd3715f 97 // Prepare first configuration.
fernya 0:aa9ebbd3715f 98 if (!dma.Prepare( conf0 )) {
fernya 0:aa9ebbd3715f 99 error("Doh!");
fernya 0:aa9ebbd3715f 100 }
fernya 0:aa9ebbd3715f 101
fernya 0:aa9ebbd3715f 102 // Begin (enable DMA and counter). Note, don't enable
fernya 0:aa9ebbd3715f 103 // DBLBUF_ENA as we are using DMA double buffering.
fernya 0:aa9ebbd3715f 104 LPC_DAC->DACCTRL |= (3UL << 2);
fernya 0:aa9ebbd3715f 105
fernya 0:aa9ebbd3715f 106 while (1) {
fernya 0:aa9ebbd3715f 107 // There's not a lot to do as DMA and interrupts are
fernya 0:aa9ebbd3715f 108 // now handling the buffer transfers. So we'll just
fernya 0:aa9ebbd3715f 109 // flash led1 to show the Mbed is alive and kicking.
fernya 0:aa9ebbd3715f 110
fernya 0:aa9ebbd3715f 111 if (life_counter++ > 100000) {
fernya 0:aa9ebbd3715f 112 led1 = !led1; // Show some sort of life.
fernya 0:aa9ebbd3715f 113 life_counter = 0;
fernya 0:aa9ebbd3715f 114 Net::poll();
fernya 0:aa9ebbd3715f 115 }
fernya 0:aa9ebbd3715f 116 }
fernya 0:aa9ebbd3715f 117 }
fernya 0:aa9ebbd3715f 118
fernya 0:aa9ebbd3715f 119 // Configuration callback on TC
fernya 0:aa9ebbd3715f 120 void TC0_callback(void) {
fernya 0:aa9ebbd3715f 121
fernya 0:aa9ebbd3715f 122 // Get configuration pointer.
fernya 0:aa9ebbd3715f 123 MODDMA_Config *config = dma.getConfig();
fernya 0:aa9ebbd3715f 124
fernya 0:aa9ebbd3715f 125 // Finish the DMA cycle by shutting down the channel.
fernya 0:aa9ebbd3715f 126 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
fernya 0:aa9ebbd3715f 127
fernya 0:aa9ebbd3715f 128 // Swap to buffer1
fernya 0:aa9ebbd3715f 129 dma.Prepare( conf1 );
fernya 0:aa9ebbd3715f 130
fernya 0:aa9ebbd3715f 131 // Clear DMA IRQ flags.
fernya 0:aa9ebbd3715f 132 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
fernya 0:aa9ebbd3715f 133 int i;
fernya 0:aa9ebbd3715f 134
fernya 0:aa9ebbd3715f 135 for (i=0; i<40; i++) {
fernya 0:aa9ebbd3715f 136 circ_buf.get((uint32_t*)&play[0][i]);
fernya 0:aa9ebbd3715f 137 }
fernya 0:aa9ebbd3715f 138 }
fernya 0:aa9ebbd3715f 139
fernya 0:aa9ebbd3715f 140 // Configuration callback on Error
fernya 0:aa9ebbd3715f 141 void ERR0_callback(void) {
fernya 0:aa9ebbd3715f 142 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
fernya 0:aa9ebbd3715f 143 }
fernya 0:aa9ebbd3715f 144
fernya 0:aa9ebbd3715f 145 // Configuration callback on TC
fernya 0:aa9ebbd3715f 146 void TC1_callback(void) {
fernya 0:aa9ebbd3715f 147
fernya 0:aa9ebbd3715f 148 // Get configuration pointer.
fernya 0:aa9ebbd3715f 149 MODDMA_Config *config = dma.getConfig();
fernya 0:aa9ebbd3715f 150
fernya 0:aa9ebbd3715f 151 // Finish the DMA cycle by shutting down the channel.
fernya 0:aa9ebbd3715f 152 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
fernya 0:aa9ebbd3715f 153
fernya 0:aa9ebbd3715f 154 // Swap to buffer0
fernya 0:aa9ebbd3715f 155 dma.Prepare( conf0 );
fernya 0:aa9ebbd3715f 156
fernya 0:aa9ebbd3715f 157 // Clear DMA IRQ flags.
fernya 0:aa9ebbd3715f 158 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
fernya 0:aa9ebbd3715f 159 int i;
fernya 0:aa9ebbd3715f 160
fernya 0:aa9ebbd3715f 161 for (i=0; i<40; i++) {
fernya 0:aa9ebbd3715f 162 circ_buf.get((uint32_t*)&play[1][i]);
fernya 0:aa9ebbd3715f 163 }
fernya 0:aa9ebbd3715f 164 }
fernya 0:aa9ebbd3715f 165
fernya 0:aa9ebbd3715f 166 // Configuration callback on Error
fernya 0:aa9ebbd3715f 167 void ERR1_callback(void) {
fernya 0:aa9ebbd3715f 168 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
fernya 0:aa9ebbd3715f 169 }
fernya 0:aa9ebbd3715f 170
fernya 0:aa9ebbd3715f 171 int ethInit(void) {
fernya 0:aa9ebbd3715f 172 //Ethernet konfiguracio (DHCP)
fernya 0:aa9ebbd3715f 173 printf("Setting up...\r\n");
fernya 0:aa9ebbd3715f 174 EthernetErr ethErr = eth.setup();
fernya 0:aa9ebbd3715f 175 IpAddr ownIP = eth.getIp();
fernya 0:aa9ebbd3715f 176 printf("My IP is: %d.%d.%d.%d\r\n",ownIP[0],ownIP[1],ownIP[2],ownIP[3]);
fernya 0:aa9ebbd3715f 177 if (ethErr) {
fernya 0:aa9ebbd3715f 178 printf("Error %d in Ethernet setup.\r\n", ethErr);
fernya 0:aa9ebbd3715f 179 return -1;
fernya 0:aa9ebbd3715f 180 }
fernya 0:aa9ebbd3715f 181 printf("Setup OK\r\n");
fernya 0:aa9ebbd3715f 182 return 0;
fernya 0:aa9ebbd3715f 183 //Ethernet konfiguracio vege
fernya 0:aa9ebbd3715f 184 }
fernya 0:aa9ebbd3715f 185
fernya 0:aa9ebbd3715f 186 int udpInit(void) {
fernya 0:aa9ebbd3715f 187 //UDP konfiguracio
fernya 0:aa9ebbd3715f 188 Host rtp_addr;
fernya 0:aa9ebbd3715f 189 data_sock.setOnEvent(&UDPReceive);
fernya 0:aa9ebbd3715f 190 UDPSocketErr sockErr = data_sock.bind(Host(IpAddr(), 5004));
fernya 0:aa9ebbd3715f 191 printf("Ack\r\n");
fernya 0:aa9ebbd3715f 192 if (sockErr) {
fernya 0:aa9ebbd3715f 193 printf("Error %d in socket setup.\r\n", sockErr);
fernya 0:aa9ebbd3715f 194 return -1;
fernya 0:aa9ebbd3715f 195 }
fernya 0:aa9ebbd3715f 196 return 0;
fernya 0:aa9ebbd3715f 197 //UDP konfiguracio vege
fernya 0:aa9ebbd3715f 198 }
fernya 0:aa9ebbd3715f 199
fernya 0:aa9ebbd3715f 200 /**UDP recv callback */
fernya 0:aa9ebbd3715f 201 void UDPReceive(UDPSocketEvent e) {
fernya 0:aa9ebbd3715f 202
fernya 0:aa9ebbd3715f 203 short * data_ptr;
fernya 0:aa9ebbd3715f 204 int i,length;
fernya 0:aa9ebbd3715f 205 int tmp;
fernya 0:aa9ebbd3715f 206
fernya 0:aa9ebbd3715f 207 switch (e) {
fernya 0:aa9ebbd3715f 208 case UDPSOCKET_READABLE:
fernya 0:aa9ebbd3715f 209 Host host;
fernya 0:aa9ebbd3715f 210 while ( int len = data_sock.recvfrom(packet_buf, 512, &host ) ) {
fernya 0:aa9ebbd3715f 211 if ( len <= 0 )
fernya 0:aa9ebbd3715f 212 break;
fernya 0:aa9ebbd3715f 213 rtp_decompose(packet_buf, len, &head, (char**)&data_ptr);
fernya 0:aa9ebbd3715f 214 length = head.data_len/2;
fernya 0:aa9ebbd3715f 215 for ( i = 0; i < length; i++ ) {
fernya 0:aa9ebbd3715f 216 tmp = ntohs(data_ptr[i]); //network to host endianness
fernya 0:aa9ebbd3715f 217 tmp = ((tmp + 0x7FFF) & 0xFFC0) | (DAC_POWER_MODE); //format DAC register input (signed->unsigned conversion and masking)
fernya 0:aa9ebbd3715f 218 circ_buf.put( tmp ); //fill the circular buffer
fernya 0:aa9ebbd3715f 219 }
fernya 0:aa9ebbd3715f 220 }
fernya 0:aa9ebbd3715f 221 break;
fernya 0:aa9ebbd3715f 222 }
fernya 0:aa9ebbd3715f 223 }