fork of StateScript

Dependencies:   mbed SOMO_II

Fork of stateScript_v2 by Mattias Karlsson

mbedInterface/mbedInterface.cpp

Committer:
mkarlsso
Date:
2015-05-19
Revision:
0:8dbd6bd9167f
Child:
1:3a050d26d4f6
Child:
3:d7b0a0890d96

File content as of revision 0:8dbd6bd9167f:

#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
extern bool resetTimer;
extern bool clockSlave;
extern bool changeToSlave;
extern bool changeToStandAlone;
extern outputStream textDisplay;

int externalIncrementMod = 30;
int externalIncrementCounter = 0;


#ifdef MBED_RF
//Karpova version----------------------------------------
//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;

//Recieve clock signal from RF system
InterruptIn RFClock(p28);
DigitalIn RFData(p27);


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



//------------------------------------------------------------------------
//------------------------------------------------------------------------

//MBED-specific stuff
//---------------------------------------------------------------------

//translate pin numbers to hardware pins
PinName outPins[NUMPORTS] = {p11,p13,p15,p18,p21,p23,p25,p29,p20};
PinName inPins[NUMPORTS] = {p12,p14,p16,p17,p22,p24,p26,p30,p7};



//The sound output uses a SmartWav device and their simple serial library
SMARTWAV sWav(p9,p10,p19);   //(TX,RX,Reset);

//This is the callback for the MBED timer
extern "C" void TIMER0_IRQHandler (void) {

    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;
        }
    }
}
//-----------------------------------------------------------------------



MBEDSystem::MBEDSystem():
    clockResetInt(p5),
    clockExternalIncrement(p8) {

    clockResetInt.rise(this, &MBEDSystem::externalClockReset);
    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 < NUMPORTS; i++) {
        dIn[i].init(i);
        dOut[i].init(i);
    }



    sWav.reset();

}

void MBEDSystem::timerinit() {
    //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
    //--------------------------------------------------------------
}

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 < NUMPORTS) {
        return &dOut[portNum];
    } else {
        return NULL;
    }
}

sDigitalIn* MBEDSystem::getDigitalInPtr(int portNum) {
    if (portNum < NUMPORTS) {
        return &dIn[portNum];
    } else {
        return NULL;
    }
}

sSound* MBEDSystem::createNewSoundAction() {
    MBEDSound *tmpSound = new MBEDSound();
    return tmpSound;
}


void MBEDSystem::externalClockReset() {

    if (clockSlave) {
        LPC_TIM0->TCR = 0x02;    // reset timer
        externalIncrementCounter = 0;
        immediateClockReset();
    }

}

void MBEDSystem::setStandAloneClock() {
    timerinit();
    clockExternalIncrement.rise(NULL); //remove the callback to the external interrupt
    clockSlave = false;
    changeToSlave = false;
    changeToStandAlone = false;
}

void MBEDSystem::setSlaveClock() {
    NVIC_DisableIRQ(TIMER0_IRQn); // Disable the interrupt
    clockExternalIncrement.rise(this, &MBEDSystem::incrementClock);
    clockSlave = true;
    changeToSlave = false;
    changeToStandAlone = false;
}

void MBEDSystem::incrementClock() {

    if (clockSlave) {
        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) {
        timeKeeper = 0;
        resetTimer = false;
    }
}

//-----------------------------------------------------

MBEDSound::MBEDSound() {

}

void MBEDSound::execute() {
    if (reset) {
        sWav.reset();
    } else if (!play) {
        sWav.stopTrack();
    } else {
        if (volume > -1) {
            sWav.volume(volume);
        } else if (volumePtr != NULL) {
            sWav.volume(*volumePtr);
        }

        if (fileNameExists) {
            //sWav.playTracks();
            sWav.stopTrack();
            sWav.playTrackName(fileName);
        }
    }
}

//-----------------------------------------------------
MBEDDigitalOut::MBEDDigitalOut() {

}

void MBEDDigitalOut::init(int pin) {
    outpin = new DigitalOut(outPins[pin]);
}

int MBEDDigitalOut::read() {
    return outpin->read();
}

void MBEDDigitalOut::write(int value) {
    outpin->write(value);
}
//--------------------------------------------------------

MBEDDigitalIn::MBEDDigitalIn() {

}

void MBEDDigitalIn::init(int pin) {
    inpin = new DigitalIn(inPins[pin]);
    inpin_interrupt = new InterruptIn(inPins[pin]);
    inpin->mode(PullDown);
    //Set up callbacks for the port interrupts
    inpin_interrupt->rise(this, &MBEDDigitalIn::interrupt_up_callback);
    inpin_interrupt->fall(this, &MBEDDigitalIn::interrupt_down_callback);
}

int MBEDDigitalIn::read() {
    return inpin->read();
}

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);
}