Andy Lustig / Mbed 2 deprecated stateScript_v2_karpova

Dependencies:   SMARTWAV mbed

Fork of stateScript_v2 by Mattias Karlsson

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbedInterface.cpp Source File

mbedInterface.cpp

00001 #include "mbedInterface.h"
00002 #include "mbed.h"
00003 
00004 
00005 
00006 //--------------------------------------------------------------
00007 //--------------------------------------------------------------
00008 //This section is required for all custom harware interfaces
00009 
00010 //globals defined in hardwareInterface.cpp
00011 extern uint32_t timeKeeper; //the master clock
00012 uint32_t uSec_SinceLastClockInc = 0;
00013 uint32_t uSec_SinceLastReset = 0;
00014 
00015 extern bool resetTimer;
00016 extern bool clockSlave;
00017 extern bool changeToSlave;
00018 extern bool changeToStandAlone;
00019 extern outputStream textDisplay;
00020 
00021 int externalIncrementMod = 30;
00022 int externalIncrementCounter = 0;
00023 
00024 
00025 #ifdef MBED_RF
00026 //We are listening to an RF signal for hardware syncing----------------------------------------
00027 //Uses DB9->RJ45 connector to map the following channels:
00028 //1: P28    Clock Signal In
00029 //2: P27    Data Signal In
00030 //3: P20    FiberLED Out Signal
00031 //4: 5V
00032 //5: GND
00033 //6: P6     NC
00034 //7: P7     NC
00035 //8: P8     NC
00036 
00037 DigitalOut mainLED(LED1);
00038 DigitalOut secondaryLED(LED2);
00039 
00040 bool lightOn = false;
00041 bool lightOn2 = false;
00042 int pulseCounter = 0;
00043 uint32_t lastPulse = 0;
00044 uint32_t currentRFTime = 0;
00045 uint32_t lastRFTime = 0;
00046 uint32_t timeKeeperAtCurrentRFTime = 0;
00047 uint32_t timeKeeperAtLastRFTime = 0;
00048 int RFSyncCounter = 0;
00049 bool RFSyncReadable = false;
00050 bool RFSyncWritable = true;
00051 
00052 //Recieve clock signal from RF system
00053 InterruptIn RFClock(p28);
00054 DigitalIn RFData(p27);
00055 
00056 
00057 void callback_RFClock(void) {
00058 
00059     //if this amount of time has passed since the last pulse, we have a new timestamp
00060     if ((timeKeeper-lastPulse) > 4) {
00061 
00062         //make sure the previous timestamp was 32 pulses
00063         //if so, update lastRFTime
00064         //we only process every 100th stamp (once every 10 seconds with 10 Hz timestamps)
00065         if ((pulseCounter == 31) && (RFSyncCounter == 99)){
00066             if (RFSyncWritable) {
00067                 lastRFTime = currentRFTime;
00068                 timeKeeperAtLastRFTime = timeKeeperAtCurrentRFTime;
00069                 RFSyncReadable = true;
00070                 RFSyncWritable = false;
00071             }
00072         }
00073 
00074         pulseCounter = 0;
00075         currentRFTime = 0;
00076         timeKeeperAtCurrentRFTime = timeKeeper;
00077         RFSyncCounter = (RFSyncCounter+1)%100;
00078 
00079 
00080         if (lightOn) {
00081             mainLED = 0;
00082             lightOn = false;
00083         } else {
00084             mainLED = 1;
00085             lightOn = true;
00086         }
00087     } else {
00088         if (pulseCounter < 32) {
00089             currentRFTime = (currentRFTime | ( RFData.read() << pulseCounter));
00090             pulseCounter++;
00091         }
00092     }
00093     lastPulse = timeKeeper;
00094 }
00095 
00096 //------------------------------------------------------------
00097 #endif
00098 
00099 void externalClockIncDown() {
00100 
00101     //The external clock increment signal pulse has come back down.  If the pulse was long
00102     //enough, then we condsider it a valid pulse (the pulses should be 0.5 ms long)
00103     if ((clockSlave)&&(uSec_SinceLastClockInc >= 300)) {
00104         uSec_SinceLastClockInc = 0;
00105         timeKeeper++;
00106 
00107         //Clock resets happen upon update so we dont get a partial first ms
00108         if (resetTimer) {
00109             uSec_SinceLastReset = 0;
00110             timeKeeper = 0;
00111             resetTimer = false;
00112         }
00113     }
00114 
00115 }
00116 
00117 void externalResetDown() {
00118 
00119     //The external clock reset signal pulse has come back down.  If the pulse was long
00120     //enough, then we condsider it a valid pulse (the pulses should be 1 ms long)
00121     if ((clockSlave)&&(uSec_SinceLastReset >= 700)) {
00122         uSec_SinceLastReset = 0;
00123         timeKeeper = 1; //It has been 1ms since the reset pulse went up
00124         textDisplay << timeKeeper << " Clock reset\r\n";
00125     }
00126 }
00127 
00128 //------------------------------------------------------------------------
00129 //------------------------------------------------------------------------
00130 
00131 //MBED-specific stuff
00132 //---------------------------------------------------------------------
00133 
00134 //translate pin numbers to hardware pins
00135 //PinName outPins[NUMPORTS] = {p11,p13,p15,p18,p21,p23,p25,p29,p20};
00136 PinName outPins[NUMPORTS] = {p18,p15,p13,p11,p29,p25,p23,p21,p20};
00137 PinName inPins[NUMPORTS] = {p12,p14,p16,p17,p22,p24,p26,p30,p7};
00138 
00139 
00140 
00141 
00142 //The sound output uses a SmartWav device and their simple serial library
00143 SMARTWAV sWav(p9,p10,p19);   //(TX,RX,Reset);
00144 
00145 //This is the callback for the MBED timer
00146 extern "C" void TIMER0_IRQHandler (void) {
00147 
00148     if (clockSlave) {
00149         //The function is called every 100 us
00150         uSec_SinceLastClockInc = uSec_SinceLastClockInc+100;
00151         uSec_SinceLastReset = uSec_SinceLastReset+100;
00152     } else {
00153         //The function is called every 1 ms
00154         if((LPC_TIM0->IR & 0x01) == 0x01) {  // if MR0 interrupt, proceed
00155 
00156             LPC_TIM0->IR |= 1 << 0;         // Clear MR0 interrupt flag
00157             timeKeeper++;
00158 
00159             if (resetTimer) {
00160                 timeKeeper = 0;
00161                 resetTimer = false;
00162             }
00163         }
00164     }
00165 
00166 }
00167 //-----------------------------------------------------------------------
00168 
00169 
00170 
00171 MBEDSystem::MBEDSystem():
00172     clockResetInt(p5),
00173     clockExternalIncrement(p8) {
00174 
00175     clockResetInt.rise(this, &MBEDSystem::externalClockReset);
00176     clockResetInt.fall(&externalResetDown);
00177     clockResetInt.mode(PullDown);
00178 
00179     clockExternalIncrement.mode(PullDown);
00180 
00181     #ifdef MBED_RF
00182     //Karpova version-------------
00183     //Set up callbacks for RF clock signal
00184     RFClock.rise(&callback_RFClock);
00185     RFClock.mode(PullDown);
00186     #endif
00187 
00188     //-------------------------------
00189 
00190     for (int i=0; i < NUMPORTS; i++) {
00191         dIn[i].init(i);
00192         dOut[i].init(i);
00193     }
00194 
00195 
00196 
00197     sWav.reset();
00198 
00199 }
00200 
00201 void MBEDSystem::timerinit() {
00202     //intiatiation of timer (specific to the LPC17xx chip). This is used in
00203     //standalone mode to increment the clock every ms.
00204     //----------------------------------------------------
00205     //LPC_SC->PCLKSEL1 &= (3 << 12); //mask
00206     //LPC_SC->PCLKSEL1 |= (1 << 12); //sets it to 1*SystemCoreClock - table 42 (page 57 in user manual)
00207     //LPC_SC->PCLKSEL0 &= (3 << 3); //mask
00208     //LPC_SC->PCLKSEL0 |= (1 << 3); //sets it to 1*SystemCoreClock - table 42 (page 57 in user manual)
00209     LPC_SC->PCONP |=1<1;            //timer0 power on   
00210     LPC_TIM0->MR0 = 23980;        //1 msec
00211 
00212     //LPC_TIM0->PR  = (SystemCoreClock / 1000000); //microsecond steps
00213     //LPC_TIM0->MR0 = 1000;        //100 msec
00214     //LPC_TIM0->MR0  = (SystemCoreClock / 1000000); //microsecond steps
00215     LPC_TIM0->MCR = 3;              //interrupt and reset control
00216     //3 = Interrupt & reset timer0 on match
00217     //1 = Interrupt only, no reset of timer0
00218     NVIC_EnableIRQ(TIMER0_IRQn);    //enable timer0 interrupt
00219     LPC_TIM0->TCR = 1;              //enable Timer0
00220     //--------------------------------------------------------------
00221 }
00222 
00223 void MBEDSystem::pauseInterrupts() {
00224     __disable_irq();
00225 }
00226 
00227 void MBEDSystem::resumeInterrupts() {
00228     __enable_irq();
00229 }
00230 
00231 void MBEDSystem::mainLoopToDo() {
00232     #ifdef MBED_RF
00233     //Karpova version--------------------------
00234     //Karpova lab RF addition. Print out time sync.
00235     if (RFSyncReadable) {
00236            /*
00237            ostringstream RFTimeConvert;
00238            RFTimeConvert << timeKeeperAtLastRFTime << " " << "RFsync " << lastRFTime << "         "; //broadcast the earliest timestamp when a change occured
00239 
00240            textDisplay.send(RFTimeConvert.str() + "\r\n");
00241            RFTimeConvert.clear();
00242            RFTimeConvert.seekp(0);
00243            */
00244 
00245            textDisplay << timeKeeperAtLastRFTime << " RFsync " << lastRFTime << "\r\n";
00246 
00247            RFSyncReadable = false;
00248            RFSyncWritable = true;
00249     }
00250     //------------------------------------------------------------
00251     #endif
00252 }
00253 
00254 sDigitalOut* MBEDSystem::getDigitalOutPtr(int portNum){
00255     if (portNum < NUMPORTS) {
00256         return &dOut[portNum];
00257     } else {
00258         return NULL;
00259     }
00260 }
00261 
00262 sDigitalIn* MBEDSystem::getDigitalInPtr(int portNum) {
00263     if (portNum < NUMPORTS) {
00264         return &dIn[portNum];
00265     } else {
00266         return NULL;
00267     }
00268 }
00269 
00270 sSound* MBEDSystem::createNewSoundAction() {
00271     MBEDSound *tmpSound = new MBEDSound();
00272     return tmpSound;
00273 }
00274 
00275 
00276 void MBEDSystem::externalClockReset() {
00277 
00278     //The pulse has gone high.  When the pulse comes down we will check to see if it was long enough to be valid.
00279     uSec_SinceLastReset = 0;
00280 
00281 
00282     /*
00283     if (clockSlave) {
00284         LPC_TIM0->TCR = 0x02;    // reset timer
00285         externalIncrementCounter = 0;
00286         immediateClockReset();
00287     }*/
00288 
00289 }
00290 
00291 void MBEDSystem::setStandAloneClock() {
00292     clockSlave = false;
00293     NVIC_DisableIRQ(TIMER0_IRQn); // Disable the interrupt
00294     timerinit(); //set up and enable interrupt
00295     clockExternalIncrement.rise(NULL); //remove the callback to the external interrupt
00296     //clockExternalIncrement.fall(NULL);
00297     changeToSlave = false;
00298     changeToStandAlone = false;
00299 }
00300 
00301 void MBEDSystem::setSlaveClock() {
00302     clockSlave = true;
00303     NVIC_DisableIRQ(TIMER0_IRQn); // Disable the interrupt
00304     //timerinit(); //set up and enable interrupt
00305     clockExternalIncrement.rise(this, &MBEDSystem::incrementClock);
00306     //clockExternalIncrement.fall(&externalClockIncDown);
00307     clockSlave = true;
00308     changeToSlave = false;
00309     changeToStandAlone = false;
00310 }
00311 
00312 void MBEDSystem::incrementClock() {
00313 
00314     if (clockSlave) {
00315         //The pulse has gone high.  When the pulse comes down we will check to see if it was long enough to be valid.
00316         //uSec_SinceLastClockInc = 0;
00317 
00318 
00319         //The clock is incremented
00320 
00321         externalIncrementCounter = (externalIncrementCounter+1) % externalIncrementMod;
00322         if (externalIncrementCounter==0) {
00323             timeKeeper++;
00324         }
00325 
00326     } else {
00327         timeKeeper++;
00328     }
00329     //Clock resets happen upon update so we dont get a partial first ms
00330     /*
00331     if (resetTimer) {
00332         uSec_SinceLastReset = 0;
00333         timeKeeper = 0;
00334         resetTimer = false;
00335     }*/
00336 }
00337 
00338 //-----------------------------------------------------
00339 
00340 MBEDSound::MBEDSound() {
00341 
00342 }
00343 
00344 void MBEDSound::execute() {
00345     if (reset) {
00346         sWav.reset();
00347     } else if (!play) {
00348         sWav.stopTrack();
00349     } else {
00350         if (volume > -1) {
00351             sWav.volume(volume);
00352         } else if (volumePtr != NULL) {
00353             sWav.volume(*volumePtr);
00354         }
00355 
00356         if (fileNameExists) {
00357             //sWav.playTracks();
00358             sWav.stopTrack();
00359             sWav.playTrackName(fileName);
00360         }
00361     }
00362 }
00363 
00364 //-----------------------------------------------------
00365 MBEDDigitalOut::MBEDDigitalOut() {
00366 
00367 }
00368 
00369 void MBEDDigitalOut::init(int pin) {
00370     outpin = new DigitalOut(outPins[pin]);
00371 }
00372 
00373 int MBEDDigitalOut::read() {
00374     return outpin->read();
00375 }
00376 
00377 void MBEDDigitalOut::write(int value) {
00378     outpin->write(value);
00379 }
00380 //--------------------------------------------------------
00381 
00382 MBEDDigitalIn::MBEDDigitalIn() {
00383 
00384 }
00385 
00386 void MBEDDigitalIn::init(int pin) {
00387     inpin = new DigitalIn(inPins[pin]);
00388     inpin_interrupt = new InterruptIn(inPins[pin]);
00389     inpin->mode(PullDown);
00390     //Set up callbacks for the port interrupts
00391     inpin_interrupt->rise(this, &MBEDDigitalIn::interrupt_up_callback);
00392     inpin_interrupt->fall(this, &MBEDDigitalIn::interrupt_down_callback);
00393 }
00394 
00395 int MBEDDigitalIn::read() {
00396     return inpin->read();
00397 }
00398 
00399 void MBEDDigitalIn::interrupt_up_callback() {
00400     addStateChange(1, timeKeeper);
00401 }
00402 
00403 void MBEDDigitalIn::interrupt_down_callback() {
00404     addStateChange(0, timeKeeper);
00405 }
00406 
00407 //----------------------------------------------------------
00408 MBEDSerialPort::MBEDSerialPort() {
00409 
00410 }
00411 
00412 void MBEDSerialPort::init() {
00413     //Initialize serial communication
00414     serialToPC = new Serial(USBTX, USBRX); // tx, rx
00415     serialToPC->baud(115200);
00416 
00417 
00418 }
00419 
00420 bool MBEDSerialPort::readable() {
00421     return serialToPC->readable();
00422 }
00423 
00424 char MBEDSerialPort::readChar() {
00425     return serialToPC->getc();
00426 }
00427 
00428 void MBEDSerialPort::writeChar(char s) {
00429     serialToPC->printf("%c", s);
00430 }
00431 
00432 int MBEDSerialPort::requestToWriteString(char *s, int numBytesRequested) {
00433     //request to print a string to the serial output buffer
00434     //function returns the number of chars actually accepted for output
00435     int numBytesAccepted = 0;
00436     while (numBytesAccepted < numBytesRequested) {
00437 
00438         writeChar(*(s+numBytesAccepted));
00439         numBytesAccepted++;
00440     }
00441 
00442     return numBytesAccepted;
00443 }