ADC using MODDMA and then sending the sampled value encapsulated in an OSC message
Dependencies: EthernetNetIf mbed
main.cpp
00001 #include "mbed.h" 00002 #include "MODDMA.h" 00003 #include "mbedOSC.h" 00004 00005 00006 // How long between grabbing samples on all channels. 00007 // Value is in microseconds. 00008 #define SAMPLE_PERIOD 10000//////10ms sampling of all adc pins 00009 #define NUM_OF_SAMPLES 6 00010 00011 00012 //// ETHERNET 00013 // Ethernet can be created with *either* an address assigned by DHCP or a static IP address. Uncomment the define line for DHCP 00014 //#define DHCP 00015 #ifdef DHCP 00016 EthernetNetIf eth; 00017 #else 00018 EthernetNetIf eth( 00019 IpAddr(192,168,1,1), //IP Address 00020 IpAddr(255,255,255,0), //Network Mask 00021 IpAddr(), //Gateway 00022 IpAddr() //DNS 00023 ); 00024 #endif 00025 00026 00027 00028 DigitalOut led1(LED1); 00029 DigitalOut led2(LED2); 00030 DigitalOut led3(LED3); 00031 DigitalOut led4(LED4); 00032 00033 //// OSC 00034 // The object to do the work of sending and receiving 00035 OSCClass osc; 00036 // The message objects to send and receive with 00037 OSCMessage recMes; 00038 OSCMessage sendMes; 00039 // Setting - The port we're listening to on the mbed for OSC messages 00040 int mbedListenPort = 9000; 00041 // Setting - The address and port we're going to send to, from the mbed 00042 uint8_t destIp[] = { 192, 168, 1, 2}; 00043 int destPort = 8000; 00044 //// Our messageReceivedCallback function 00045 void processOSC() 00046 { 00047 // If this function has been called, the OSC message just received will have been parsed into our recMes OSCMessage object 00048 // Note we can access recMes here, outside of the main loop, as we created it as a global variable. 00049 // TASK: If this message one we want, do something about it. 00050 // In this example we're listening for messages with a top address of "mbed". 00051 // Note the strcmp function returns 0 if identical, so !strcmp is true if the two strings are the same 00052 if ( !strcmp( recMes.getAddress(0) , "mbed" ) ) { 00053 printf("OSC Message received addressed to mbed \r\n"); 00054 if ( !strcmp( recMes.getAddress(1) , "test1" ) ) 00055 printf("Received subAddress= test1 \r\n"); 00056 // Send some osc message: 00057 sendMes.setTopAddress("/working..."); 00058 osc.sendOsc(&sendMes); 00059 } 00060 led1=!led1; 00061 } 00062 00063 00064 uint32_t adBuffer[NUM_OF_SAMPLES]; 00065 bool dmaTransferComplete; 00066 00067 MODDMA dma; 00068 MODDMA_Config *conf; 00069 00070 00071 void TC0_callback(void); /////DMA Transmission 00072 void ERR0_callback(void); 00073 void Sensor_Tap(int chan, uint32_t value1); //////Sending OSC 00074 00075 extern "C" void TIMER1_handler(void) __irq ////// Aka Wahaj bhai!!! yeah im talking to myself ...this function is called 00076 { ///when i want to sample the analgue pins using burst mode and reseting the DMA and timer Configuration for the next sample 00077 led2 = !led2; // Show life 00078 //uint32_t dummyADC = LPC_ADC->ADGDR; 00079 dma.Setup( conf ); // Pre-prep a transfer 00080 dma.Enable( conf ); 00081 LPC_ADC->ADCR |= (1UL << 16); // ADC burst mode 00082 LPC_ADC->ADINTEN = 0x100; // Do all channels. 00083 LPC_TIM1->IR = 1; // Clr timer1 irq. 00084 } 00085 00086 int main() 00087 { 00088 00089 //// TASK: Set up the Ethernet port 00090 printf("Setting up ethernet...\r\n"); 00091 EthernetErr ethErr = eth.setup(); 00092 if (ethErr) { 00093 printf("Ethernet Failed to setup. Error: %d\r\n", ethErr); 00094 return -1; 00095 } 00096 printf("Ethernet OK\r\n"); 00097 //// TASK: Set up OSC message sending 00098 // In the OSC message container we've made for send messages, set where we want it to go: 00099 sendMes.setIp( destIp ); 00100 sendMes.setPort( destPort ); 00101 //// TASK: Set up OSC message receiving 00102 // In the OSC send/receive object... 00103 // Set the OSC message container for it to parse received messages into 00104 osc.setReceiveMessage(&recMes); 00105 // Tell it to begin listening for OSC messages at the port specified (the IP address we know already, it's the mbed's!). 00106 osc.begin(mbedListenPort); 00107 // Rather than constantly checking to see whether there are new messages waiting, the object can call some code of ours to run when a message is received. 00108 // This line does that, attaching a callback function we've written before getting to this point, in this case it's called processOSC 00109 // For more info how this works, see http://mbed.org/cookbook/FunctionPointer 00110 osc.messageReceivedCallback.attach(&processOSC); 00111 00112 00113 00114 00115 00116 ///////////////DMA AND ADC////////// 00117 00118 memset(adBuffer, 0, sizeof(adBuffer)); 00119 00120 00121 // Power up the ADC and set PCLK-----Configuraion 00122 LPC_SC->PCONP |= (1UL << 12); 00123 LPC_SC->PCLKSEL0 |= (3UL << 24); // PCLK = CCLK/8 96M/8 = 12MHz 00124 NVIC_DisableIRQ(ADC_IRQn); ///For burst mode disable NVIc for adc 00125 00126 // Set the pin functions to ADC 00127 00128 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 14); 00129 LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 14; 00130 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 14); 00131 LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 14; 00132 00133 //p16://=p0.24 of LPC1768 00134 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 16); 00135 LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 16; 00136 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 16); 00137 LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 16; 00138 00139 // p17://=p0.25 of LPC1768 00140 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 18); 00141 LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 18; 00142 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 18); 00143 LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 18; 00144 00145 //p18://=p0.26 of LPC1768: 00146 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 20); 00147 LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 20; 00148 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 20); 00149 LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 20; 00150 00151 //=p1.30 of LPC1768 00152 LPC_PINCON->PINSEL3 &= ~((unsigned int)0x3 << 28); 00153 LPC_PINCON->PINSEL3 |= (unsigned int)0x3 << 28; 00154 LPC_PINCON->PINMODE3 &= ~((unsigned int)0x3 << 28); 00155 LPC_PINCON->PINMODE3 |= (unsigned int)0x2 << 28; 00156 00157 //=p1.31 of LPC1768 00158 LPC_PINCON->PINSEL3 &= ~((unsigned int)0x3 << 30); 00159 LPC_PINCON->PINSEL3 |= (unsigned int)0x3 << 30; 00160 LPC_PINCON->PINMODE3 &= ~((unsigned int)0x3 << 30); 00161 LPC_PINCON->PINMODE3 |= (unsigned int)0x2 << 30; 00162 00163 LPC_ADC->ADINTEN = 0x100; 00164 ////////////////Enable ADC////1Mhz clock////6 ADC pins 00165 LPC_ADC->ADCR = (1UL << 21) | (11UL << 8) | (63UL << 0); 00166 00167 00168 //////TIMER 1 Configuraion 00169 LPC_SC->PCONP |= (1UL << 2); // TIM1 On 00170 LPC_SC->PCLKSEL0 |= (3UL << 4); // CCLK/8 = 12MHz 00171 LPC_TIM1->PR = 11; // TC clocks at 1MHz. 00172 LPC_TIM1->MR0 = SAMPLE_PERIOD-1; 00173 LPC_TIM1->MCR = 3; // Reset TCR to zero on match and irq. 00174 NVIC_SetVector(TIMER1_IRQn, (uint32_t)TIMER1_handler); 00175 NVIC_EnableIRQ(TIMER1_IRQn); 00176 00177 // Prepare the GPDMA system. 00178 conf = new MODDMA_Config; 00179 conf 00180 ->channelNum ( MODDMA::Channel_0 ) 00181 ->dstMemAddr ( (uint32_t)adBuffer ) 00182 ->transferSize ( NUM_OF_SAMPLES ) 00183 ->transferType ( MODDMA::p2m ) 00184 ->transferWidth ( MODDMA::word ) 00185 ->srcConn ( MODDMA::ADC ) 00186 ->attach_tc ( &TC0_callback ) 00187 ->attach_err ( &ERR0_callback ) 00188 ; // end conf. 00189 00190 // Prepare configuration. 00191 if (!dma.Setup( conf )) 00192 { 00193 error("Doh!"); 00194 } 00195 00196 // Begin. 00197 LPC_TIM1->TCR = 1; 00198 while (1) 00199 { 00200 00201 // This polls the network connection for new activity, without keeping on calling this you won't receive any OSC! 00202 Net::poll(); 00203 if (dmaTransferComplete) 00204 { 00205 int i, value, channel; 00206 00207 for (i = 0; i <NUM_OF_SAMPLES ; i++) 00208 { 00209 value = (adBuffer[i] >> 4) & 0xFFF; 00210 channel = (adBuffer[i] >> 24) & 0x3; 00211 channel--; 00212 adBuffer[i]=0; 00213 if (channel == -1) 00214 channel = 5; // Workaround ch num problem. 00215 double fVal = 5 * (double)((double)value) / ((double)0x1000); // scale to 0v to 3.3v 00216 Sensor_Tap(i,(uint32_t)fVal); 00217 00218 00219 //pc.printf("ADC input (channel=%d) = 0x%03x %01.3f volts\n", channel, value, fVal); 00220 } 00221 dmaTransferComplete = false; 00222 wait(0.05); ////wait for 50 ms for the next finger to pe pressed 00223 00224 } 00225 } 00226 } 00227 00228 // Configuration callback on TC 00229 void TC0_callback(void) 00230 { 00231 led4=!led4; 00232 MODDMA_Config *config = dma.getConfig(); 00233 00234 // Disbale burst mode and switch off the IRQ flag. 00235 LPC_ADC->ADCR &= ~(1UL << 16); 00236 LPC_ADC->ADINTEN = 0; 00237 00238 // Finish the DMA cycle by shutting down the channel. 00239 dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum()); 00240 dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); 00241 00242 // Tell main() while(1) loop to print the results. 00243 dmaTransferComplete = true; 00244 00245 // Clear DMA IRQ flags. 00246 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); 00247 if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq(); 00248 } 00249 00250 // Configuration callback on Error 00251 void ERR0_callback(void) { 00252 // Switch off burst conversions. 00253 LPC_ADC->ADCR |= ~(1UL << 16); 00254 LPC_ADC->ADINTEN = 0; 00255 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); 00256 } 00257 00258 00259 void Sensor_Tap(int chan, uint32_t value1) 00260 { 00261 led3 = !led3; 00262 00263 // if((value>>4)&0xFFFF >= Adc_Threshold) 00264 { 00265 //SendOsc 00266 00267 sendMes.setTopAddress("/MidiGlove"); 00268 switch (chan) 00269 { 00270 case 0: 00271 default: 00272 sendMes.setSubAddress("/Thumb"); 00273 break; 00274 case 1: 00275 sendMes.setSubAddress("/Finger1"); 00276 break; 00277 case 2: 00278 sendMes.setSubAddress("/Finger2"); 00279 break; 00280 case 3: 00281 sendMes.setSubAddress("/Finger3"); 00282 break; 00283 case 4: 00284 sendMes.setSubAddress("/Finger4"); 00285 break; 00286 case 5: 00287 sendMes.setSubAddress("/Finger5"); 00288 break; 00289 } 00290 // uint32_t v=123; 00291 sendMes.setArgs("i",&value1); // The payload will be the button state as an integer, ie. 0 or 1. We need to cast to 'long' for ints (and 'double' for floats). 00292 osc.sendOsc(&sendMes); 00293 } 00294 00295 }
Generated on Tue Jul 12 2022 21:52:12 by 1.7.2