Andy Lustig
/
stateScript_v2
fork of StateScript
Fork of stateScript_v2 by
mbedInterface/mbedInterface.cpp
- Committer:
- alustig3
- Date:
- 2017-04-28
- Revision:
- 10:f65649c13b5b
- Parent:
- 9:f783bce314cd
File content as of revision 10:f65649c13b5b:
#include "mbedInterface.h" #include "mbed.h" //-------------------------------------------------------------- //-------------------------------------------------------------- //This section is required for all custom harware interfaces //globals defined in hardwareInterface.cpp extern uint32_t timeKeeper; //the master clock uint32_t uSec_SinceLastClockInc = 0; uint32_t uSec_SinceLastReset = 0; extern bool resetTimer; extern bool clockSlave; extern bool changeToSlave; extern bool changeToStandAlone; extern outputStream textDisplay; int externalIncrementMod = 1; int externalIncrementCounter = 0; #ifdef MBED_RF //We are listening to an RF signal for hardware syncing---------------------------------------- //Uses DB9->RJ45 connector to map the following channels: //1: P28 Clock Signal In //2: P27 Data Signal In //3: P20 FiberLED Out Signal //4: 5V //5: GND //6: P6 NC //7: P7 NC //8: P8 NC DigitalOut mainLED(LED1); DigitalOut secondaryLED(LED2); bool lightOn = false; bool lightOn2 = false; int pulseCounter = 0; uint32_t lastPulse = 0; uint32_t currentRFTime = 0; uint32_t lastRFTime = 0; uint32_t timeKeeperAtCurrentRFTime = 0; uint32_t timeKeeperAtLastRFTime = 0; int RFSyncCounter = 0; bool RFSyncReadable = false; bool RFSyncWritable = true; #ifdef LPC1768 //Recieve clock signal from RF system InterruptIn RFClock(p28); DigitalIn RFData(p27); #endif #ifdef K64 InterruptIn RFClock(PTA1); DigitalIn RFData(PTB9); #endif void callback_RFClock(void) { //if this amount of time has passed since the last pulse, we have a new timestamp if ((timeKeeper-lastPulse) > 4) { //make sure the previous timestamp was 32 pulses //if so, update lastRFTime //we only process every 100th stamp (once every 10 seconds with 10 Hz timestamps) if ((pulseCounter == 31) && (RFSyncCounter == 99)){ if (RFSyncWritable) { lastRFTime = currentRFTime; timeKeeperAtLastRFTime = timeKeeperAtCurrentRFTime; RFSyncReadable = true; RFSyncWritable = false; } } pulseCounter = 0; currentRFTime = 0; timeKeeperAtCurrentRFTime = timeKeeper; RFSyncCounter = (RFSyncCounter+1)%100; if (lightOn) { mainLED = 0; lightOn = false; } else { mainLED = 1; lightOn = true; } } else { if (pulseCounter < 32) { currentRFTime = (currentRFTime | ( RFData.read() << pulseCounter)); pulseCounter++; } } lastPulse = timeKeeper; } //------------------------------------------------------------ #endif void externalClockIncDown() { //The external clock increment signal pulse has come back down. If the pulse was long //enough, then we condsider it a valid pulse (the pulses should be 0.5 ms long) if ((clockSlave)&&(uSec_SinceLastClockInc >= 300)) { uSec_SinceLastClockInc = 0; timeKeeper++; //Clock resets happen upon update so we dont get a partial first ms if (resetTimer) { uSec_SinceLastReset = 0; timeKeeper = 0; resetTimer = false; } } } void externalResetDown() { //The external clock reset signal pulse has come back down. If the pulse was long //enough, then we condsider it a valid pulse (the pulses should be 1 ms long) /* textDisplay << uSec_SinceLastReset; if ((clockSlave)&&(uSec_SinceLastReset >= 700)) { uSec_SinceLastReset = 0; timeKeeper = 1; //It has been 1ms since the reset pulse went up textDisplay << timeKeeper << " Clock reset\r\n"; }*/ } //------------------------------------------------------------------------ //------------------------------------------------------------------------ //MBED-specific stuff //--------------------------------------------------------------------- //translate pin numbers to hardware pins #ifdef LPC1768 PinName dInPins[NUMDIGINPORTS] = {p5,p14,p16,p17,p22,p24,p26,p30}; PinName dOutPins[NUMDIGOUTPORTS] = {p7,p15,p13,p11,p29,p25,p23,p21}; //With analog pins PinName aInPins[NUMANINPORTS] = {p20}; PinName aOutPins[NUMANOUTPORTS] = {p18}; // SOMO II sound module http://www.4dsystems.com.au/product/SOMO_II/ // Datasheet http://www.4dsystems.com.au/productpages/SOMO-II/downloads/SOMO-II_datasheet_R_1_2.pdf SOMO audio(p9,p10); //(TX,RX) #endif #ifdef K64 PinName dInPins[NUMDIGINPORTS] = {PTB2, PTB9, PTC10, PTA1, PTD1}; PinName dOutPins[NUMDIGOUTPORTS] = {PTB11, PTC14, PTC11, PTC15, PTE24, PTD4, PTC9, PTB18, PTD0}; PinName aInPins[NUMANINPORTS] = {}; PinName aOutPins[NUMANOUTPORTS] = {}; SOMO audio(PTC17,PTC16); //(TX,RX,Reset) #endif #ifdef LPC1768 //This is the callback for the MBED timer extern "C" void TIMER0_IRQHandler (void) { //The function is called every 1 ms if((LPC_TIM0->IR & 0x01) == 0x01) { // if MR0 interrupt, proceed LPC_TIM0->IR |= 1 << 0; // Clear MR0 interrupt flag timeKeeper++; if (resetTimer) { timeKeeper = 0; resetTimer = false; } } } //----------------------------------------------------------------------- #endif MBEDSystem::MBEDSystem(): #ifdef LPC1768 clockResetInt(p5), clockExternalIncrement(p8) { clockResetInt.rise(this, &MBEDSystem::externalClockReset); #endif #ifdef K64 clockResetInt(PTD4), clockExternalIncrement(PTD6) { clockResetInt.rise(callback(this, &MBEDSystem::externalClockReset)); #endif clockResetInt.fall(&externalResetDown); clockResetInt.mode(PullDown); clockExternalIncrement.mode(PullDown); #ifdef MBED_RF //Karpova version------------- //Set up callbacks for RF clock signal RFClock.rise(&callback_RFClock); RFClock.mode(PullDown); #endif //------------------------------- for (int i=0; i < NUMDIGINPORTS; i++) { dIn[i].init(i); } for (int i=0; i < NUMDIGOUTPORTS; i++) { dOut[i].init(i); } for (int i=0; i < NUMANINPORTS; i++) { aIn[i].init(i); } for (int i=0; i < NUMANOUTPORTS; i++) { aOut[i].init(i); } audio.reset(); } void MBEDSystem::timerinit() { #ifdef LPC1768 //intiatiation of timer (specific to the LPC17xx chip). This is used in //standalone mode to increment the clock every ms. //---------------------------------------------------- //LPC_SC->PCLKSEL1 &= (3 << 12); //mask //LPC_SC->PCLKSEL1 |= (1 << 12); //sets it to 1*SystemCoreClock - table 42 (page 57 in user manual) //LPC_SC->PCLKSEL0 &= (3 << 3); //mask //LPC_SC->PCLKSEL0 |= (1 << 3); //sets it to 1*SystemCoreClock - table 42 (page 57 in user manual) LPC_SC->PCONP |=1<1; //timer0 power on LPC_TIM0->MR0 = 23980; //1 msec //LPC_TIM0->PR = (SystemCoreClock / 1000000); //microsecond steps //LPC_TIM0->MR0 = 1000; //100 msec //LPC_TIM0->MR0 = (SystemCoreClock / 1000000); //microsecond steps LPC_TIM0->MCR = 3; //interrupt and reset control //3 = Interrupt & reset timer0 on match //1 = Interrupt only, no reset of timer0 NVIC_EnableIRQ(TIMER0_IRQn); //enable timer0 interrupt LPC_TIM0->TCR = 1; //enable Timer0 //-------------------------------------------------------------- #endif } void MBEDSystem::pauseInterrupts() { __disable_irq(); } void MBEDSystem::resumeInterrupts() { __enable_irq(); } void MBEDSystem::mainLoopToDo() { #ifdef MBED_RF //Karpova version-------------------------- //Karpova lab RF addition. Print out time sync. if (RFSyncReadable) { /* ostringstream RFTimeConvert; RFTimeConvert << timeKeeperAtLastRFTime << " " << "RFsync " << lastRFTime << " "; //broadcast the earliest timestamp when a change occured textDisplay.send(RFTimeConvert.str() + "\r\n"); RFTimeConvert.clear(); RFTimeConvert.seekp(0); */ textDisplay << timeKeeperAtLastRFTime << " RFsync " << lastRFTime << "\r\n"; RFSyncReadable = false; RFSyncWritable = true; } //------------------------------------------------------------ #endif } sDigitalOut* MBEDSystem::getDigitalOutPtr(int portNum){ if (portNum < NUMDIGOUTPORTS) { return &dOut[portNum]; } else { return NULL; } } sDigitalIn* MBEDSystem::getDigitalInPtr(int portNum) { if (portNum < NUMDIGINPORTS) { return &dIn[portNum]; } else { return NULL; } } sAnalogOut* MBEDSystem::getAnalogOutPtr(int portNum){ if (portNum < NUMANOUTPORTS) { return &aOut[portNum]; } else { return NULL; } } sAnalogIn* MBEDSystem::getAnalogInPtr(int portNum) { if (portNum < NUMANINPORTS) { return &aIn[portNum]; } else { return NULL; } } sSound* MBEDSystem::createNewSoundAction() { MBEDSound *tmpSound = new MBEDSound(); return tmpSound; } void MBEDSystem::externalClockReset() { //The pulse has gone high. When the pulse comes down we will check to see if it was long enough to be valid. uSec_SinceLastReset = 0; if (clockSlave) { #ifdef LPC1768 LPC_TIM0->TCR = 0x02; // reset timer #endif externalIncrementCounter = 0; immediateClockReset(); } } void MBEDSystem::setStandAloneClock() { clockSlave = false; #ifdef LPC1768 NVIC_DisableIRQ(TIMER0_IRQn); // Disable the interrupt #endif timerinit(); //set up and enable interrupt clockExternalIncrement.rise(NULL); //remove the callback to the external interrupt //clockExternalIncrement.fall(NULL); changeToSlave = false; changeToStandAlone = false; } void MBEDSystem::setSlaveClock() { clockSlave = true; #ifdef LPC1768 NVIC_DisableIRQ(TIMER0_IRQn); // Disable the interrupt clockExternalIncrement.rise(this, &MBEDSystem::incrementClock); #endif #ifdef K64 clockExternalIncrement.rise(callback(this, &MBEDSystem::incrementClock)); #endif clockSlave = true; changeToSlave = false; changeToStandAlone = false; } void MBEDSystem::incrementClock() { if (clockSlave) { //The pulse has gone high. When the pulse comes down we will check to see if it was long enough to be valid. //uSec_SinceLastClockInc = 0; //The clock is incremented externalIncrementCounter = (externalIncrementCounter+1) % externalIncrementMod; if (externalIncrementCounter==0) { timeKeeper++; } } else { timeKeeper++; } //Clock resets happen upon update so we dont get a partial first ms /* if (resetTimer) { uSec_SinceLastReset = 0; timeKeeper = 0; resetTimer = false; }*/ } //----------------------------------------------------- MBEDSound::MBEDSound() { } void MBEDSound::execute() { if (reset) { audio.reset(); } else if (!play) { audio.stopTrack(); } else { if (volume > -1) { audio.volume(volume); } else if (volumePtr != NULL) { audio.volume(*volumePtr); } if (fileNameExists) { //audio.playTracks(); audio.stopTrack(); audio.playTrackName(fileName); } } } //----------------------------------------------------- MBEDAnalogOut::MBEDAnalogOut() { } void MBEDAnalogOut::init(int pin) { if (pin < NUMANOUTPORTS) { outpin = new AnalogOut(aOutPins[pin]); pinExists = true; } } int MBEDAnalogOut::read() { if (pinExists) { return outpin->read()*3300.0; //read value is a float between 0 and 1.0 (max voltage). Convert to mV integer value. } else { return 0; } } void MBEDAnalogOut::write(int value) { if (pinExists) { outpin->write((float)value / 3300.0);//should be a float input (percentage). We convert from integer mV value. } } //-------------------------------------------------------- MBEDAnalogIn::MBEDAnalogIn() { } void MBEDAnalogIn::init(int pin) { if (pin < NUMANINPORTS) { inpin = new AnalogIn(aInPins[pin]); pinExists = true; } } int MBEDAnalogIn::read() { if (pinExists) { return inpin->read()*3300.0; //read value is a fload between 0 and 1.0 (max voltage). Convert to mV integer value. } else { return 0; } } //----------------------------------------------------- MBEDDigitalOut::MBEDDigitalOut() { pinExists = false; } void MBEDDigitalOut::init(int pin) { if (pin < NUMDIGOUTPORTS) { outpin = new DigitalOut(dOutPins[pin]); pinExists = true; } } int MBEDDigitalOut::read() { if (pinExists) { return outpin->read(); } else { return 0; } } void MBEDDigitalOut::write(int value) { if (pinExists) { outpin->write(value); } } //-------------------------------------------------------- MBEDDigitalIn::MBEDDigitalIn() { pinExists = false; } void MBEDDigitalIn::init(int pin) { if (pin < NUMDIGINPORTS) { inpin = new DigitalIn(dInPins[pin]); inpin_interrupt = new InterruptIn(dInPins[pin]); inpin->mode(PullDown); //Set up callbacks for the port interrupts #ifdef LPC1768 inpin_interrupt->rise(this, &MBEDDigitalIn::interrupt_up_callback); inpin_interrupt->fall(this, &MBEDDigitalIn::interrupt_down_callback); #endif #ifdef K64 inpin_interrupt->rise(callback(this, &MBEDDigitalIn::interrupt_up_callback)); inpin_interrupt->fall(callback(this, &MBEDDigitalIn::interrupt_down_callback)); #endif pinExists = true; } } int MBEDDigitalIn::read() { if (pinExists) { return inpin->read(); } else { return 0; } } void MBEDDigitalIn::interrupt_up_callback() { addStateChange(1, timeKeeper); } void MBEDDigitalIn::interrupt_down_callback() { addStateChange(0, timeKeeper); } //---------------------------------------------------------- MBEDSerialPort::MBEDSerialPort() { } void MBEDSerialPort::init() { //Initialize serial communication serialToPC = new Serial(USBTX, USBRX); // tx, rx serialToPC->baud(115200); } bool MBEDSerialPort::readable() { return serialToPC->readable(); } char MBEDSerialPort::readChar() { return serialToPC->getc(); } void MBEDSerialPort::writeChar(char s) { serialToPC->printf("%c", s); } int MBEDSerialPort::requestToWriteString(char *s, int numBytesRequested) { //request to print a string to the serial output buffer //function returns the number of chars actually accepted for output int numBytesAccepted = 0; while (numBytesAccepted < numBytesRequested) { writeChar(*(s+numBytesAccepted)); numBytesAccepted++; } return numBytesAccepted; }