Sooner Competitive Robotics / Mbed 2 deprecated IEEE_14_Freescale

Dependencies:   mbed

Fork of IEEE_14_Freescale by IEEE 2014 Mbed

Committer:
soonerbot
Date:
Fri Nov 22 18:00:18 2013 +0000
Revision:
7:3b2cf7efe5d1
Parent:
1:c28fac16a109
Child:
9:aff48e331147
Commented most things

Who changed what in which revision?

UserRevisionLine numberNew contents of line
soonerbot 1:c28fac16a109 1 #include "remoteEnc.h"
soonerbot 1:c28fac16a109 2 #include "dbgprint.h"
soonerbot 1:c28fac16a109 3
soonerbot 1:c28fac16a109 4
soonerbot 1:c28fac16a109 5 /*private:
soonerbot 1:c28fac16a109 6 SPI &spi;
soonerbot 1:c28fac16a109 7 DigitalIn cs;
soonerbot 1:c28fac16a109 8 int referenceCounts[4];
soonerbot 1:c28fac16a109 9 int latestCount[4];
soonerbot 1:c28fac16a109 10 int outState;
soonerbot 1:c28fac16a109 11 public:
soonerbot 1:c28fac16a109 12 remoteEnc(SPI &spiIn, PinName cspin);
soonerbot 1:c28fac16a109 13 const int* getVals();
soonerbot 1:c28fac16a109 14 int setPins(int mask);
soonerbot 1:c28fac16a109 15 int setPin(int pin, int state);
soonerbot 1:c28fac16a109 16 int getPinState();
soonerbot 1:c28fac16a109 17 int reset(int slot);
soonerbot 1:c28fac16a109 18 int getLastVal(int slot);*/
soonerbot 1:c28fac16a109 19
soonerbot 1:c28fac16a109 20 remoteEnc::remoteEnc(SPI &spiIn, PinName cspin) : spi(spiIn), cs(cspin){
soonerbot 1:c28fac16a109 21 cs=1;
soonerbot 1:c28fac16a109 22 spi.format(8,0);
soonerbot 1:c28fac16a109 23 spi.frequency(100000);
soonerbot 1:c28fac16a109 24 direction[0]=direction[1]=direction[2]=direction[3]=1;
soonerbot 1:c28fac16a109 25 int i;
soonerbot 1:c28fac16a109 26 for(i=0;i<4;i++){
soonerbot 1:c28fac16a109 27 referenceCounts[i]=0;
soonerbot 1:c28fac16a109 28 latestQuadrant[i]=0;
soonerbot 1:c28fac16a109 29 }
soonerbot 1:c28fac16a109 30 getVals();
soonerbot 1:c28fac16a109 31 for(i=0;i<4;i++){
soonerbot 1:c28fac16a109 32 latestQuadrant[i]=latestActual[i]&(~0x3FFF);
soonerbot 1:c28fac16a109 33 DBGPRINT("{%x,%x}",latestQuadrant[i],latestActual[i]);
soonerbot 1:c28fac16a109 34 }
soonerbot 1:c28fac16a109 35 getVals();
soonerbot 1:c28fac16a109 36 for(i=0;i<4;i++){
soonerbot 1:c28fac16a109 37 referenceCounts[i]=latestCount[i];
soonerbot 1:c28fac16a109 38 DBGPRINT("-]%x,%x[-",latestQuadrant[i],latestActual[i]);
soonerbot 1:c28fac16a109 39 }
soonerbot 1:c28fac16a109 40 //DBGPRINT("reset to %d, %d, %d, %d\r\n",referenceCounts[0],referenceCounts[1],referenceCounts[2],referenceCounts[3]);
soonerbot 1:c28fac16a109 41
soonerbot 1:c28fac16a109 42 //setPins(0);
soonerbot 1:c28fac16a109 43 outState=0;
soonerbot 1:c28fac16a109 44 }
soonerbot 1:c28fac16a109 45
soonerbot 7:3b2cf7efe5d1 46 // this handles getting the encoder values and returns an array of 4 integers which are the offsets since last reset
soonerbot 7:3b2cf7efe5d1 47 // I think there's a memory leak here, since the array that is returned is never freed
soonerbot 1:c28fac16a109 48 const int* remoteEnc::getVals(){
soonerbot 1:c28fac16a109 49 int charBuf[8];
soonerbot 1:c28fac16a109 50 cs=0;
soonerbot 1:c28fac16a109 51 spi.write(0);
soonerbot 1:c28fac16a109 52 spi.write(1);
soonerbot 1:c28fac16a109 53 int i;
soonerbot 1:c28fac16a109 54 for(i=2;i<=9;i++)
soonerbot 1:c28fac16a109 55 charBuf[i-2]=spi.write(i);
soonerbot 1:c28fac16a109 56 cs=1;
soonerbot 1:c28fac16a109 57 for(i=0;i<4;i++){
soonerbot 1:c28fac16a109 58 latestActual[i]=(charBuf[2*i]+(charBuf[2*i+1]<<8))*direction[i];
soonerbot 1:c28fac16a109 59 //DBGPRINT("[%d, %d]",i,latestActual[i]);
soonerbot 7:3b2cf7efe5d1 60
soonerbot 7:3b2cf7efe5d1 61
soonerbot 7:3b2cf7efe5d1 62 // this allows the encoder counter to overflow safely, as long as we have at least one poll per quadrant
soonerbot 7:3b2cf7efe5d1 63 //
soonerbot 7:3b2cf7efe5d1 64 // since we only get 16bit values out of the remote device, overflow is a concern
soonerbot 7:3b2cf7efe5d1 65 // this code deals with it by dividing the 2^16 possible integers into 4 quadrants
soonerbot 7:3b2cf7efe5d1 66 // when we move from one quadrant to the next (one of the two most significant bits change)
soonerbot 7:3b2cf7efe5d1 67 // this picks up on the direction and updated 'latestQuadrant' which is a 32 bit integer
soonerbot 7:3b2cf7efe5d1 68 // which is used for the top 18 bits of the final result
soonerbot 1:c28fac16a109 69 if((latestActual[i]&0xC000)!=(latestQuadrant[i]&0xC000)){
soonerbot 1:c28fac16a109 70 DBGPRINT("*%x and %x to ",latestActual[i],latestQuadrant[i]);
soonerbot 1:c28fac16a109 71 if((latestActual[i]&0xC000)==((latestQuadrant[i]+0x4000)&0xC000)){
soonerbot 1:c28fac16a109 72 latestQuadrant[i]+=0x4000;
soonerbot 1:c28fac16a109 73 } else if ((latestActual[i]&0xC000)==((latestQuadrant[i]-0x4000)&0xC000)){
soonerbot 1:c28fac16a109 74 latestQuadrant[i]-=0x4000;
soonerbot 1:c28fac16a109 75 }
soonerbot 1:c28fac16a109 76 DBGPRINT("%x and %x\r\n",latestActual[i],latestQuadrant[i]);
soonerbot 1:c28fac16a109 77 }
soonerbot 1:c28fac16a109 78 //latestCount[i]=charBuf[2*i]+(charBuf[2*i+1]<<8)-referenceCounts[i];
soonerbot 1:c28fac16a109 79 latestCount[i]=latestQuadrant[i]+(latestActual[i]&0x3FFF)-referenceCounts[i];
soonerbot 1:c28fac16a109 80 }
soonerbot 1:c28fac16a109 81 return latestCount;
soonerbot 1:c28fac16a109 82 }
soonerbot 1:c28fac16a109 83
soonerbot 1:c28fac16a109 84 int remoteEnc::getLastVal(int slot){
soonerbot 1:c28fac16a109 85 return latestCount[slot];
soonerbot 1:c28fac16a109 86 }
soonerbot 1:c28fac16a109 87
soonerbot 1:c28fac16a109 88 int remoteEnc::getSingleValue(int slot){
soonerbot 1:c28fac16a109 89 cs=0;
soonerbot 1:c28fac16a109 90 spi.write(slot*2);
soonerbot 1:c28fac16a109 91 spi.write(slot*2+1);
soonerbot 1:c28fac16a109 92 int lowbit=spi.write(0);
soonerbot 1:c28fac16a109 93 int highbit=spi.write(0);
soonerbot 1:c28fac16a109 94 cs=1;
soonerbot 1:c28fac16a109 95 latestActual[slot]=(lowbit+(highbit<<8))*direction[slot];
soonerbot 1:c28fac16a109 96 //DBGPRINT("[%d, %d]",slot,latestActual[slot]);
soonerbot 1:c28fac16a109 97 if((latestActual[slot]&0xC000)!=(latestQuadrant[slot]&0xC000)){
soonerbot 1:c28fac16a109 98 DBGPRINT("*%x and %x to ",latestActual[slot],latestQuadrant[slot]);
soonerbot 7:3b2cf7efe5d1 99 //same as the discription in getVals() (might want to make function)
soonerbot 1:c28fac16a109 100 if((latestActual[slot]&0xC000)==((latestQuadrant[slot]+0x4000)&0xC000)){
soonerbot 1:c28fac16a109 101 latestQuadrant[slot]+=0x4000;
soonerbot 1:c28fac16a109 102 } else if ((latestActual[slot]&0xC000)==((latestQuadrant[slot]-0x4000)&0xC000)){
soonerbot 1:c28fac16a109 103 latestQuadrant[slot]-=0x4000;
soonerbot 1:c28fac16a109 104 }
soonerbot 1:c28fac16a109 105 DBGPRINT("%x and %x\r\n",latestActual[slot],latestQuadrant[slot]);
soonerbot 1:c28fac16a109 106 }
soonerbot 1:c28fac16a109 107 //latestCount[slot]=charBuf[2*slot]+(charBuf[2*slot+1]<<8)-referenceCounts[slot];
soonerbot 1:c28fac16a109 108 latestCount[slot]=latestQuadrant[slot]+(latestActual[slot]&0x3FFF)-referenceCounts[slot];
soonerbot 1:c28fac16a109 109 return latestCount[slot];
soonerbot 1:c28fac16a109 110 }
soonerbot 1:c28fac16a109 111
soonerbot 7:3b2cf7efe5d1 112 // allows for the universal reversal of the inputs from an encoder, so directions can be switched in software
soonerbot 1:c28fac16a109 113 int remoteEnc::setDirections(int dir1, int dir2, int dir3, int dir4){
soonerbot 1:c28fac16a109 114 direction[0]= (dir1 == -1)? -1: 1;
soonerbot 1:c28fac16a109 115 direction[1]= (dir2 == -1)? -1: 1;
soonerbot 1:c28fac16a109 116 direction[2]= (dir3 == -1)? -1: 1;
soonerbot 1:c28fac16a109 117 direction[3]= (dir4 == -1)? -1: 1;
soonerbot 7:3b2cf7efe5d1 118
soonerbot 7:3b2cf7efe5d1 119 // need to reinitalize the internal memory of the encoders
soonerbot 1:c28fac16a109 120 int i;
soonerbot 1:c28fac16a109 121 for(i=0;i<4;i++){
soonerbot 1:c28fac16a109 122 referenceCounts[i]=0;
soonerbot 1:c28fac16a109 123 latestQuadrant[i]=0;
soonerbot 1:c28fac16a109 124 }
soonerbot 1:c28fac16a109 125 getVals();
soonerbot 1:c28fac16a109 126 for(i=0;i<4;i++){
soonerbot 1:c28fac16a109 127 latestQuadrant[i]=latestActual[i]&(~0x3FFF);
soonerbot 1:c28fac16a109 128 //DBGPRINT("{%x,%x}",latestQuadrant[i],latestActual[i]);
soonerbot 1:c28fac16a109 129 }
soonerbot 1:c28fac16a109 130 getVals();
soonerbot 1:c28fac16a109 131 for(i=0;i<4;i++){
soonerbot 1:c28fac16a109 132 referenceCounts[i]=latestCount[i];
soonerbot 1:c28fac16a109 133 //DBGPRINT("{{%x,%x}}",latestQuadrant[i],latestActual[i]);
soonerbot 1:c28fac16a109 134 }
soonerbot 1:c28fac16a109 135 return 1;
soonerbot 1:c28fac16a109 136 }
soonerbot 1:c28fac16a109 137
soonerbot 1:c28fac16a109 138 int remoteEnc::reset(int slot){
soonerbot 1:c28fac16a109 139 referenceCounts[slot] += getSingleValue(slot);
soonerbot 1:c28fac16a109 140 return 1;
soonerbot 1:c28fac16a109 141 }
soonerbot 1:c28fac16a109 142
soonerbot 1:c28fac16a109 143 int remoteEnc::resetAll(){
soonerbot 1:c28fac16a109 144 const int *buf = getVals();
soonerbot 1:c28fac16a109 145 int i;
soonerbot 1:c28fac16a109 146 for(i=0;i<4;i++)
soonerbot 1:c28fac16a109 147 referenceCounts[i] += buf[i];
soonerbot 1:c28fac16a109 148 return 1;
soonerbot 1:c28fac16a109 149 }
soonerbot 1:c28fac16a109 150
soonerbot 1:c28fac16a109 151
soonerbot 1:c28fac16a109 152 int remoteEnc::setPins(int mask){
soonerbot 1:c28fac16a109 153 cs=0;
soonerbot 1:c28fac16a109 154 spi.write((mask&0x3F)|0x80);
soonerbot 1:c28fac16a109 155 spi.write(0x01);
soonerbot 1:c28fac16a109 156 //DBGPRINT("%X,%X: %d\r\n",mask,(mask&0x3F)|0x80, spi.write(0x01));
soonerbot 1:c28fac16a109 157 //DBGPRINT("%X,%X: %d\r\n",mask,(mask&0x3F)|0x80, spi.write(0x01));
soonerbot 1:c28fac16a109 158 //DBGPRINT("%X,%X: %d\r\n",mask,(mask&0x3F)|0x80, spi.write(0x01));
soonerbot 1:c28fac16a109 159 cs=1;
soonerbot 1:c28fac16a109 160 outState=mask;
soonerbot 1:c28fac16a109 161 return 1;
soonerbot 1:c28fac16a109 162 }
soonerbot 1:c28fac16a109 163
soonerbot 1:c28fac16a109 164
soonerbot 1:c28fac16a109 165 int remoteEnc::setPin(int pin, int state){
soonerbot 1:c28fac16a109 166 if(state==0){
soonerbot 1:c28fac16a109 167 outState &=~ (1<<pin);
soonerbot 1:c28fac16a109 168 } else {
soonerbot 1:c28fac16a109 169 outState |= (1<<pin);
soonerbot 1:c28fac16a109 170 }
soonerbot 1:c28fac16a109 171 setPins(outState);
soonerbot 1:c28fac16a109 172 return 1;
soonerbot 1:c28fac16a109 173 }
soonerbot 1:c28fac16a109 174