Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mbedInterface/mbedInterface.cpp
- Committer:
- mkarlsso
- Date:
- 2015-10-10
- Revision:
- 3:d7b0a0890d96
- Parent:
- 0:8dbd6bd9167f
- Child:
- 4:abee20c0bf2a
File content as of revision 3:d7b0a0890d96:
#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 = 30;
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;
//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
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)
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
//PinName outPins[NUMPORTS] = {p11,p13,p15,p18,p21,p23,p25,p29,p20};
PinName outPins[NUMPORTS] = {p18,p15,p13,p11,p29,p25,p23,p21,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 (clockSlave) {
//The function is called every 100 us
uSec_SinceLastClockInc = uSec_SinceLastClockInc+100;
uSec_SinceLastReset = uSec_SinceLastReset+100;
} else {
//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;
}
}
}
}
//-----------------------------------------------------------------------
MBEDSystem::MBEDSystem():
clockResetInt(p5),
clockExternalIncrement(p8) {
clockResetInt.rise(this, &MBEDSystem::externalClockReset);
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 < 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::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 < 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() {
//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) {
LPC_TIM0->TCR = 0x02; // reset timer
externalIncrementCounter = 0;
immediateClockReset();
}*/
}
void MBEDSystem::setStandAloneClock() {
clockSlave = false;
NVIC_DisableIRQ(TIMER0_IRQn); // Disable the interrupt
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;
NVIC_DisableIRQ(TIMER0_IRQn); // Disable the interrupt
//timerinit(); //set up and enable interrupt
clockExternalIncrement.rise(this, &MBEDSystem::incrementClock);
//clockExternalIncrement.fall(&externalClockIncDown);
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) {
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);
}
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;
}