Dependencies: mbed NetServicesMin
main.cpp@0:aa9ebbd3715f, 2012-06-18 (annotated)
- Committer:
- fernya
- Date:
- Mon Jun 18 03:59:39 2012 +0000
- Revision:
- 0:aa9ebbd3715f
Beta
Who changed what in which revision?
User | Revision | Line number | New 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 | } |