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.
Fork of IEEE_14_Freescale by
remoteEnc.cpp
- Committer:
- soonerbot
- Date:
- 2013-11-22
- Revision:
- 7:3b2cf7efe5d1
- Parent:
- 1:c28fac16a109
- Child:
- 9:aff48e331147
File content as of revision 7:3b2cf7efe5d1:
#include "remoteEnc.h" #include "dbgprint.h" /*private: SPI &spi; DigitalIn cs; int referenceCounts[4]; int latestCount[4]; int outState; public: remoteEnc(SPI &spiIn, PinName cspin); const int* getVals(); int setPins(int mask); int setPin(int pin, int state); int getPinState(); int reset(int slot); int getLastVal(int slot);*/ remoteEnc::remoteEnc(SPI &spiIn, PinName cspin) : spi(spiIn), cs(cspin){ cs=1; spi.format(8,0); spi.frequency(100000); direction[0]=direction[1]=direction[2]=direction[3]=1; int i; for(i=0;i<4;i++){ referenceCounts[i]=0; latestQuadrant[i]=0; } getVals(); for(i=0;i<4;i++){ latestQuadrant[i]=latestActual[i]&(~0x3FFF); DBGPRINT("{%x,%x}",latestQuadrant[i],latestActual[i]); } getVals(); for(i=0;i<4;i++){ referenceCounts[i]=latestCount[i]; DBGPRINT("-]%x,%x[-",latestQuadrant[i],latestActual[i]); } //DBGPRINT("reset to %d, %d, %d, %d\r\n",referenceCounts[0],referenceCounts[1],referenceCounts[2],referenceCounts[3]); //setPins(0); outState=0; } // this handles getting the encoder values and returns an array of 4 integers which are the offsets since last reset // I think there's a memory leak here, since the array that is returned is never freed const int* remoteEnc::getVals(){ int charBuf[8]; cs=0; spi.write(0); spi.write(1); int i; for(i=2;i<=9;i++) charBuf[i-2]=spi.write(i); cs=1; for(i=0;i<4;i++){ latestActual[i]=(charBuf[2*i]+(charBuf[2*i+1]<<8))*direction[i]; //DBGPRINT("[%d, %d]",i,latestActual[i]); // this allows the encoder counter to overflow safely, as long as we have at least one poll per quadrant // // since we only get 16bit values out of the remote device, overflow is a concern // this code deals with it by dividing the 2^16 possible integers into 4 quadrants // when we move from one quadrant to the next (one of the two most significant bits change) // this picks up on the direction and updated 'latestQuadrant' which is a 32 bit integer // which is used for the top 18 bits of the final result if((latestActual[i]&0xC000)!=(latestQuadrant[i]&0xC000)){ DBGPRINT("*%x and %x to ",latestActual[i],latestQuadrant[i]); if((latestActual[i]&0xC000)==((latestQuadrant[i]+0x4000)&0xC000)){ latestQuadrant[i]+=0x4000; } else if ((latestActual[i]&0xC000)==((latestQuadrant[i]-0x4000)&0xC000)){ latestQuadrant[i]-=0x4000; } DBGPRINT("%x and %x\r\n",latestActual[i],latestQuadrant[i]); } //latestCount[i]=charBuf[2*i]+(charBuf[2*i+1]<<8)-referenceCounts[i]; latestCount[i]=latestQuadrant[i]+(latestActual[i]&0x3FFF)-referenceCounts[i]; } return latestCount; } int remoteEnc::getLastVal(int slot){ return latestCount[slot]; } int remoteEnc::getSingleValue(int slot){ cs=0; spi.write(slot*2); spi.write(slot*2+1); int lowbit=spi.write(0); int highbit=spi.write(0); cs=1; latestActual[slot]=(lowbit+(highbit<<8))*direction[slot]; //DBGPRINT("[%d, %d]",slot,latestActual[slot]); if((latestActual[slot]&0xC000)!=(latestQuadrant[slot]&0xC000)){ DBGPRINT("*%x and %x to ",latestActual[slot],latestQuadrant[slot]); //same as the discription in getVals() (might want to make function) if((latestActual[slot]&0xC000)==((latestQuadrant[slot]+0x4000)&0xC000)){ latestQuadrant[slot]+=0x4000; } else if ((latestActual[slot]&0xC000)==((latestQuadrant[slot]-0x4000)&0xC000)){ latestQuadrant[slot]-=0x4000; } DBGPRINT("%x and %x\r\n",latestActual[slot],latestQuadrant[slot]); } //latestCount[slot]=charBuf[2*slot]+(charBuf[2*slot+1]<<8)-referenceCounts[slot]; latestCount[slot]=latestQuadrant[slot]+(latestActual[slot]&0x3FFF)-referenceCounts[slot]; return latestCount[slot]; } // allows for the universal reversal of the inputs from an encoder, so directions can be switched in software int remoteEnc::setDirections(int dir1, int dir2, int dir3, int dir4){ direction[0]= (dir1 == -1)? -1: 1; direction[1]= (dir2 == -1)? -1: 1; direction[2]= (dir3 == -1)? -1: 1; direction[3]= (dir4 == -1)? -1: 1; // need to reinitalize the internal memory of the encoders int i; for(i=0;i<4;i++){ referenceCounts[i]=0; latestQuadrant[i]=0; } getVals(); for(i=0;i<4;i++){ latestQuadrant[i]=latestActual[i]&(~0x3FFF); //DBGPRINT("{%x,%x}",latestQuadrant[i],latestActual[i]); } getVals(); for(i=0;i<4;i++){ referenceCounts[i]=latestCount[i]; //DBGPRINT("{{%x,%x}}",latestQuadrant[i],latestActual[i]); } return 1; } int remoteEnc::reset(int slot){ referenceCounts[slot] += getSingleValue(slot); return 1; } int remoteEnc::resetAll(){ const int *buf = getVals(); int i; for(i=0;i<4;i++) referenceCounts[i] += buf[i]; return 1; } int remoteEnc::setPins(int mask){ cs=0; spi.write((mask&0x3F)|0x80); spi.write(0x01); //DBGPRINT("%X,%X: %d\r\n",mask,(mask&0x3F)|0x80, spi.write(0x01)); //DBGPRINT("%X,%X: %d\r\n",mask,(mask&0x3F)|0x80, spi.write(0x01)); //DBGPRINT("%X,%X: %d\r\n",mask,(mask&0x3F)|0x80, spi.write(0x01)); cs=1; outState=mask; return 1; } int remoteEnc::setPin(int pin, int state){ if(state==0){ outState &=~ (1<<pin); } else { outState |= (1<<pin); } setPins(outState); return 1; }