Code for the mbed NXP LPC1768 To be used on The Robot Studio Slave Boards License : Simplified BSD

Dependencies:   mbed

Committer:
therobotstudio
Date:
Wed Feb 11 16:18:15 2015 +0000
Revision:
6:8a0250a4877a
Parent:
5:52e3137c2831
v1.0.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
therobotstudio 6:8a0250a4877a 1 /*
therobotstudio 6:8a0250a4877a 2 * Copyright (c) 2013, The Robot Studio
therobotstudio 6:8a0250a4877a 3 * All rights reserved.
therobotstudio 6:8a0250a4877a 4 *
therobotstudio 6:8a0250a4877a 5 * Redistribution and use in source and binary forms, with or without
therobotstudio 6:8a0250a4877a 6 * modification, are permitted provided that the following conditions are met:
therobotstudio 6:8a0250a4877a 7 *
therobotstudio 6:8a0250a4877a 8 * * Redistributions of source code must retain the above copyright notice, this
therobotstudio 6:8a0250a4877a 9 * list of conditions and the following disclaimer.
therobotstudio 6:8a0250a4877a 10 *
therobotstudio 6:8a0250a4877a 11 * * Redistributions in binary form must reproduce the above copyright notice,
therobotstudio 6:8a0250a4877a 12 * this list of conditions and the following disclaimer in the documentation
therobotstudio 6:8a0250a4877a 13 * and/or other materials provided with the distribution.
therobotstudio 6:8a0250a4877a 14 *
therobotstudio 6:8a0250a4877a 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
therobotstudio 6:8a0250a4877a 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
therobotstudio 6:8a0250a4877a 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
therobotstudio 6:8a0250a4877a 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
therobotstudio 6:8a0250a4877a 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
therobotstudio 6:8a0250a4877a 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
therobotstudio 6:8a0250a4877a 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
therobotstudio 6:8a0250a4877a 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
therobotstudio 6:8a0250a4877a 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
therobotstudio 6:8a0250a4877a 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
therobotstudio 6:8a0250a4877a 25 *
therobotstudio 6:8a0250a4877a 26 * Created on: Feb 27, 2013
therobotstudio 6:8a0250a4877a 27 * Author: Cyril Jourdan (cyril.jourdan@therobotstudio.com)
therobotstudio 6:8a0250a4877a 28 */
therobotstudio 6:8a0250a4877a 29
rrknight 2:7ab1d5918efe 30 #define COMPILE_MAIN_CODE_TRS_SLAVE
rrknight 2:7ab1d5918efe 31 #ifdef COMPILE_MAIN_CODE_TRS_SLAVE
rrknight 0:18d7499b82f3 32
therobotstudio 6:8a0250a4877a 33 /*** Includes ***/
rrknight 0:18d7499b82f3 34 #include "include/eposCmd.h"
rrknight 0:18d7499b82f3 35
therobotstudio 6:8a0250a4877a 36 /*** Defines ***/
rrknight 1:b430b4401fc4 37 #define OPEN_ARROW 0x3C //< = 60
rrknight 1:b430b4401fc4 38 #define CLOSE_ARROW 0x3E //< = 62
rrknight 1:b430b4401fc4 39 #define NUMBER_OF_ARROWS 5
rrknight 1:b430b4401fc4 40
rrknight 0:18d7499b82f3 41 //SPI RxTx FIFO bits
rrknight 0:18d7499b82f3 42 #define TNF 0x02
rrknight 0:18d7499b82f3 43 #define TFE 0x01
rrknight 0:18d7499b82f3 44 #define RNE 0x04
rrknight 0:18d7499b82f3 45
rrknight 4:396433e30e64 46 #define CALIB_DELAY 1500
rrknight 5:52e3137c2831 47 #define NUMBER_OF_CALIB 1
rrknight 4:396433e30e64 48
therobotstudio 6:8a0250a4877a 49 /*** Variables ***/
rrknight 0:18d7499b82f3 50 SPISlave device(p5, p6, p7, p8); // mosi, miso, sclk, ssel
rrknight 3:c16d726670b2 51 DigitalIn sync_master(p11); //previously p25
rrknight 0:18d7499b82f3 52
rrknight 4:396433e30e64 53 DigitalIn calibDonePin(p23);
rrknight 1:b430b4401fc4 54 DigitalOut logicPin(p26); //to record with Logic analyser on an event, pin high.
rrknight 3:c16d726670b2 55
rrknight 3:c16d726670b2 56 uint8_t numberEpos2Boards = 1;
rrknight 3:c16d726670b2 57
rrknight 1:b430b4401fc4 58 char dataChecksum = 0x00;
rrknight 1:b430b4401fc4 59 char cmdChecksum = 0x00;
rrknight 0:18d7499b82f3 60
rrknight 1:b430b4401fc4 61 uint8_t writeBufferSPI[NUMBER_MAX_EPOS2_PER_SLAVE][NUMBER_BYTES_PER_MSG];
rrknight 1:b430b4401fc4 62 uint8_t readBufferSPI[NUMBER_MAX_EPOS2_PER_SLAVE][NUMBER_BYTES_PER_MSG];
rrknight 0:18d7499b82f3 63
rrknight 4:396433e30e64 64 int32_t tempCalibEnc[NUMBER_OF_CALIB][NUMBER_MAX_EPOS2_PER_SLAVE];
rrknight 4:396433e30e64 65 int32_t meanCalibEnc[NUMBER_MAX_EPOS2_PER_SLAVE];
rrknight 4:396433e30e64 66 int32_t distanceFromMean[NUMBER_OF_CALIB][NUMBER_MAX_EPOS2_PER_SLAVE];
rrknight 4:396433e30e64 67 int32_t minDistFromMean[NUMBER_MAX_EPOS2_PER_SLAVE];
rrknight 4:396433e30e64 68 int32_t maxDistFromMean[NUMBER_MAX_EPOS2_PER_SLAVE];
rrknight 4:396433e30e64 69
rrknight 4:396433e30e64 70 int32_t calibOffset[NUMBER_MAX_EPOS2_PER_SLAVE];
rrknight 4:396433e30e64 71
rrknight 0:18d7499b82f3 72 int counter = 0;
rrknight 0:18d7499b82f3 73
rrknight 0:18d7499b82f3 74 int16_t forceVal[NB_SAMPLES_MEDIAN];
rrknight 0:18d7499b82f3 75 int16_t sortForceVal[NB_SAMPLES_MEDIAN];
rrknight 0:18d7499b82f3 76 //int16_t lastForceVal[NUMBER_EPOS2_BOARDS][NB_SAMPLES_MEDIAN];
rrknight 0:18d7499b82f3 77
therobotstudio 6:8a0250a4877a 78 /*** Functions ***/
rrknight 2:7ab1d5918efe 79 bool verifyChecksum() //check the data comming from the master over SPI
rrknight 1:b430b4401fc4 80 {
rrknight 1:b430b4401fc4 81 for(int i=0; i<NUMBER_MAX_EPOS2_PER_SLAVE; i++)
rrknight 1:b430b4401fc4 82 {
rrknight 1:b430b4401fc4 83 for(int j=0; j<NUMBER_BYTES_PER_MSG; j++)
rrknight 1:b430b4401fc4 84 {
rrknight 1:b430b4401fc4 85 cmdChecksum += readBufferSPI[i][j];
rrknight 1:b430b4401fc4 86 }
rrknight 1:b430b4401fc4 87 }
rrknight 1:b430b4401fc4 88
rrknight 1:b430b4401fc4 89 cmdChecksum++; //add 1 to obtain 0x00
rrknight 2:7ab1d5918efe 90
rrknight 2:7ab1d5918efe 91 //pc.printf("sum 0x%02X\n\r", cmdChecksum);
rrknight 1:b430b4401fc4 92
rrknight 1:b430b4401fc4 93 if(cmdChecksum == 0x00) return true;
rrknight 1:b430b4401fc4 94 else return false;
rrknight 1:b430b4401fc4 95 }
rrknight 1:b430b4401fc4 96
rrknight 2:7ab1d5918efe 97 void calculateSPIChecksum() //compute checksum for the data sent to the master over SPI
rrknight 2:7ab1d5918efe 98 {
rrknight 2:7ab1d5918efe 99 int sum = 0;
rrknight 2:7ab1d5918efe 100
rrknight 2:7ab1d5918efe 101 for(int i=0; i<NUMBER_MAX_EPOS2_PER_SLAVE; i++)
rrknight 2:7ab1d5918efe 102 {
rrknight 2:7ab1d5918efe 103 for(int j=0; j<NUMBER_BYTES_PER_MSG; j++)
rrknight 2:7ab1d5918efe 104 {
rrknight 2:7ab1d5918efe 105 sum += writeBufferSPI[i][j];
rrknight 2:7ab1d5918efe 106 }
rrknight 2:7ab1d5918efe 107 }
rrknight 2:7ab1d5918efe 108
rrknight 2:7ab1d5918efe 109 dataChecksum = (char)(~sum); //reverse 0 and 1, and cast as byte
rrknight 2:7ab1d5918efe 110 }
rrknight 2:7ab1d5918efe 111
rrknight 0:18d7499b82f3 112 int16_t getMedianForceVal(const int8_t nodeID)
rrknight 0:18d7499b82f3 113 {
rrknight 2:7ab1d5918efe 114 //logicPin = 1;
rrknight 0:18d7499b82f3 115
rrknight 0:18d7499b82f3 116 for(int m=0; m<NB_SAMPLES_MEDIAN; m++)
rrknight 0:18d7499b82f3 117 {
rrknight 0:18d7499b82f3 118 sortForceVal[m] = getForce(nodeID);
rrknight 0:18d7499b82f3 119 wait_us(100); //adjust this
rrknight 0:18d7499b82f3 120 }
rrknight 0:18d7499b82f3 121
rrknight 0:18d7499b82f3 122 //sort values
rrknight 0:18d7499b82f3 123 for(int m=1; m<NB_SAMPLES_MEDIAN; ++m)
rrknight 0:18d7499b82f3 124 {
rrknight 0:18d7499b82f3 125 int16_t n = sortForceVal[m];
rrknight 0:18d7499b82f3 126 int p;
rrknight 0:18d7499b82f3 127
rrknight 0:18d7499b82f3 128 for(p = m-1; (p >=0) && (n<sortForceVal[p]); p--)
rrknight 0:18d7499b82f3 129 {
rrknight 0:18d7499b82f3 130 sortForceVal[p+1] = sortForceVal[p];
rrknight 0:18d7499b82f3 131 }
rrknight 0:18d7499b82f3 132 sortForceVal[p+1] = n;
rrknight 0:18d7499b82f3 133 }
rrknight 0:18d7499b82f3 134
rrknight 2:7ab1d5918efe 135 //logicPin = 0;
rrknight 0:18d7499b82f3 136
rrknight 0:18d7499b82f3 137 return sortForceVal[2];
rrknight 0:18d7499b82f3 138 }
rrknight 0:18d7499b82f3 139
rrknight 0:18d7499b82f3 140 /*** INTERRUPT (for catching Emergency error frames) ***/
rrknight 0:18d7499b82f3 141 void interrupt()
rrknight 0:18d7499b82f3 142 {
rrknight 0:18d7499b82f3 143 CANMessage canmsg;
rrknight 0:18d7499b82f3 144 int64_t data = 0x0000000000000000;
rrknight 0:18d7499b82f3 145 int8_t nodeID = 0;
rrknight 0:18d7499b82f3 146 int16_t cobID = 0;
rrknight 0:18d7499b82f3 147
rrknight 0:18d7499b82f3 148 //read the can message that has triggered the interrupt
rrknight 0:18d7499b82f3 149 cantoepos.read(canmsg);
rrknight 0:18d7499b82f3 150
rrknight 0:18d7499b82f3 151 //pc.printf("Interrupt frame : [%02X] [%02X %02X %02X %02X %02X %02X %02X %02X]\n", canmsg.id, canmsg.data[7], canmsg.data[6], canmsg.data[5], canmsg.data[4], canmsg.data[3], canmsg.data[2], canmsg.data[1], canmsg.data[0]);
rrknight 0:18d7499b82f3 152
rrknight 0:18d7499b82f3 153 nodeID = 0x00F & canmsg.id;
rrknight 0:18d7499b82f3 154 cobID = 0x0FF0 & canmsg.id;
rrknight 0:18d7499b82f3 155
rrknight 0:18d7499b82f3 156 for(int i=0; i<=canmsg.len; i++)
rrknight 0:18d7499b82f3 157 {
rrknight 0:18d7499b82f3 158 data = data | (canmsg.data[i]<<i*8);
rrknight 0:18d7499b82f3 159 }
rrknight 0:18d7499b82f3 160
rrknight 0:18d7499b82f3 161 //check nodeID first
rrknight 3:c16d726670b2 162 if((nodeID >= 1) && (nodeID <= numberEpos2Boards)) //was nodeID >= 0 before ???
rrknight 0:18d7499b82f3 163 {
rrknight 0:18d7499b82f3 164 switch(cobID)
rrknight 0:18d7499b82f3 165 {
rrknight 0:18d7499b82f3 166 case COB_ID_TRANSMIT_PDO_1_ENABLE : //getPosition
rrknight 0:18d7499b82f3 167 //pc.printf("getPosition Node ID : [%d], PDO COB-ID [%02X], data = %d\n", nodeID, cobID, data);
rrknight 0:18d7499b82f3 168 encPosition[nodeID - 1] = data;
rrknight 0:18d7499b82f3 169 break;
rrknight 0:18d7499b82f3 170
rrknight 0:18d7499b82f3 171 case COB_ID_TRANSMIT_PDO_2_ENABLE : //getCurrent averaged
rrknight 0:18d7499b82f3 172 //pc.printf("getCurrent Node ID : [%d], PDO COB-ID [%02X], data = %d\n", nodeID, cobID, data);
rrknight 0:18d7499b82f3 173 avgCurrent[nodeID - 1] = data;
rrknight 0:18d7499b82f3 174 break;
rrknight 0:18d7499b82f3 175
rrknight 0:18d7499b82f3 176 case COB_ID_TRANSMIT_PDO_3_ENABLE : //getVelocity
rrknight 0:18d7499b82f3 177 //pc.printf("getVelocity Node ID : [%d], PDO COB-ID [%02X], data = %d\n", nodeID, cobID, data);
rrknight 0:18d7499b82f3 178 velocity[nodeID - 1] = data;
rrknight 0:18d7499b82f3 179 break;
rrknight 0:18d7499b82f3 180
rrknight 0:18d7499b82f3 181 case COB_ID_TRANSMIT_PDO_4_ENABLE : //getPotiPosition
rrknight 0:18d7499b82f3 182 //pc.printf("getPotiPosition Node ID : [%d], PDO COB-ID [%02X], data = %d\n", nodeID, cobID, data);
rrknight 0:18d7499b82f3 183 potiPosArray[nodeID - 1] = data;
rrknight 0:18d7499b82f3 184 break;
rrknight 0:18d7499b82f3 185
rrknight 0:18d7499b82f3 186 case COB_ID_EMCY_DEFAULT : //Emergency frame
rrknight 0:18d7499b82f3 187 //pc.printf("Emergency frame, Node ID : [%d], PDO COB-ID [%02X], data = %02X\n", nodeID, cobID, data);
rrknight 0:18d7499b82f3 188 //pc.printf("EF [%02X][%02X %02X %02X %02X %02X %02X %02X %02X]\n", canmsg.id, canmsg.data[7], canmsg.data[6], canmsg.data[5], canmsg.data[4], canmsg.data[3], canmsg.data[2], canmsg.data[1], canmsg.data[0]);
rrknight 0:18d7499b82f3 189 pc.printf("EF%02X-%02X%02X\n\r", canmsg.id, canmsg.data[1], canmsg.data[0]);
rrknight 0:18d7499b82f3 190 ledchain[1] = 1;
rrknight 0:18d7499b82f3 191 //nh.logerror("Emergency frame");
rrknight 0:18d7499b82f3 192 boardStatus[nodeID-1] = 1;
rrknight 0:18d7499b82f3 193 //first step : fault reset on controlword
rrknight 0:18d7499b82f3 194 //pc.printf("Node %d - STEP 1 - faultResetControlword\n", nodeID);
therobotstudio 6:8a0250a4877a 195
therobotstudio 6:8a0250a4877a 196 //Debug for fault detection on brachii
therobotstudio 6:8a0250a4877a 197 //faultResetControlword(nodeID);
rrknight 0:18d7499b82f3 198 break;
rrknight 0:18d7499b82f3 199
rrknight 0:18d7499b82f3 200 case COB_ID_SDO_SERVER_TO_CLIENT_DEFAULT : //SDO Acknoledgement frame
rrknight 0:18d7499b82f3 201 int32_t regData = 0x00000000;
rrknight 0:18d7499b82f3 202 regData = (int32_t)data;
rrknight 0:18d7499b82f3 203
rrknight 0:18d7499b82f3 204 //pc.printf("Node %d - regData [%02X]\n", nodeID, regData);
rrknight 0:18d7499b82f3 205
rrknight 0:18d7499b82f3 206 if(regData == 0x00604060) //Controlword
rrknight 0:18d7499b82f3 207 {
rrknight 0:18d7499b82f3 208 if(boardStatus[nodeID-1] == 1)
rrknight 0:18d7499b82f3 209 {
rrknight 0:18d7499b82f3 210 boardStatus[nodeID-1] = 2;
rrknight 0:18d7499b82f3 211 //second step : shutdown controlword
rrknight 0:18d7499b82f3 212 //pc.printf("Node %d - STEP 2 - shutdownControlwordIT\n", nodeID);
rrknight 0:18d7499b82f3 213 shutdownControlwordIT(nodeID);
rrknight 0:18d7499b82f3 214 }
rrknight 0:18d7499b82f3 215 else if(boardStatus[nodeID-1] == 2)
rrknight 0:18d7499b82f3 216 {
rrknight 0:18d7499b82f3 217 boardStatus[nodeID-1] = 3;
rrknight 0:18d7499b82f3 218 //third step : Switch On & Enable Operation on Controlword
rrknight 0:18d7499b82f3 219 //pc.printf("Node %d - STEP 3 - switchOnEnableOperationControlwordIT\n", nodeID);
rrknight 0:18d7499b82f3 220 switchOnEnableOperationControlwordIT(nodeID);
rrknight 0:18d7499b82f3 221 }
rrknight 0:18d7499b82f3 222 else if(boardStatus[nodeID-1] == 3)
rrknight 0:18d7499b82f3 223 {
rrknight 0:18d7499b82f3 224 boardStatus[nodeID-1] = 4;
rrknight 0:18d7499b82f3 225 //ask for statusword to check if the board has reset well
rrknight 0:18d7499b82f3 226 //pc.printf("Node %d - STEP 4 - getStatusword\n", nodeID);
rrknight 0:18d7499b82f3 227 getStatusword(nodeID);
rrknight 0:18d7499b82f3 228 }
rrknight 0:18d7499b82f3 229 }
rrknight 0:18d7499b82f3 230 else if(regData == 0x0060414B) //read Statusword
rrknight 0:18d7499b82f3 231 {
rrknight 1:b430b4401fc4 232 //int32_t swData = 0x00000000;
rrknight 0:18d7499b82f3 233
rrknight 0:18d7499b82f3 234 //pc.printf("Node %d - Statusword [%02X]\n", nodeID, canmsg.data[4]);
rrknight 0:18d7499b82f3 235 //pc.printf("Statusword frame : [%02X] [%02X %02X %02X %02X %02X %02X %02X %02X]\n", canmsg.id, canmsg.data[7], canmsg.data[6], canmsg.data[5], canmsg.data[4], canmsg.data[3], canmsg.data[2], canmsg.data[1], canmsg.data[0]);
rrknight 0:18d7499b82f3 236
rrknight 0:18d7499b82f3 237 if(boardStatus[nodeID-1] == 4)
rrknight 0:18d7499b82f3 238 {
rrknight 0:18d7499b82f3 239 //swData = data >> 32;
rrknight 0:18d7499b82f3 240 int8_t fault = 0x00;
rrknight 0:18d7499b82f3 241 fault = (canmsg.data[4] & 0x08) >> 3;
rrknight 0:18d7499b82f3 242
rrknight 0:18d7499b82f3 243 if(fault == 0) //reset OK
rrknight 0:18d7499b82f3 244 {
rrknight 0:18d7499b82f3 245 boardStatus[nodeID-1] = 0; //Board is reset and enable OK
rrknight 0:18d7499b82f3 246 pc.printf("%d OK\n\r", nodeID);
rrknight 0:18d7499b82f3 247 ledchain[1] = 0;
rrknight 0:18d7499b82f3 248 }
rrknight 0:18d7499b82f3 249 else //try to reset again
rrknight 0:18d7499b82f3 250 {
rrknight 0:18d7499b82f3 251 //pc.printf("Node %d - try to reset again\n", nodeID);
rrknight 0:18d7499b82f3 252 boardStatus[nodeID-1] = 1;
rrknight 0:18d7499b82f3 253 //go back to first step : fault reset on controlword
rrknight 0:18d7499b82f3 254 //pc.printf("Node %d - STEP 1 - faultResetControlword\n", nodeID);
rrknight 0:18d7499b82f3 255 faultResetControlword(nodeID);
rrknight 0:18d7499b82f3 256 }
rrknight 0:18d7499b82f3 257 }
rrknight 0:18d7499b82f3 258 }
rrknight 0:18d7499b82f3 259 break;
rrknight 0:18d7499b82f3 260
rrknight 0:18d7499b82f3 261 default :
rrknight 0:18d7499b82f3 262 pc.printf("Unknown frame [%02X][%02X %02X %02X %02X %02X %02X %02X %02X]\n\r", canmsg.id, canmsg.data[7], canmsg.data[6], canmsg.data[5], canmsg.data[4], canmsg.data[3], canmsg.data[2], canmsg.data[1], canmsg.data[0]);
rrknight 0:18d7499b82f3 263 } //end switch
rrknight 0:18d7499b82f3 264 }
rrknight 0:18d7499b82f3 265 else
rrknight 0:18d7499b82f3 266 {
rrknight 0:18d7499b82f3 267 pc.printf("NODEID ERROR\n\r");
rrknight 0:18d7499b82f3 268 }
rrknight 0:18d7499b82f3 269 } //end interrupt
rrknight 0:18d7499b82f3 270
rrknight 0:18d7499b82f3 271 void commandPlayer() //called in main every 20ms
rrknight 2:7ab1d5918efe 272 {
rrknight 2:7ab1d5918efe 273 //at least one cmd played
rrknight 2:7ab1d5918efe 274 bool cmdPlayLED = false;
rrknight 2:7ab1d5918efe 275
rrknight 2:7ab1d5918efe 276 for(int i= 0; i<NUMBER_MAX_EPOS2_PER_SLAVE; i++)
rrknight 0:18d7499b82f3 277 {
rrknight 2:7ab1d5918efe 278 uint8_t node_ID = readBufferSPI[i][0];
rrknight 2:7ab1d5918efe 279 uint8_t node_mode = readBufferSPI[i][1];
rrknight 2:7ab1d5918efe 280 int32_t value = readBufferSPI[i][2] + (readBufferSPI[i][3]<<8) + (readBufferSPI[i][4]<<16) + (readBufferSPI[i][5]<<24);
rrknight 3:c16d726670b2 281
rrknight 3:c16d726670b2 282 if((node_ID >= 1) && (node_ID <= numberEpos2Boards))
rrknight 3:c16d726670b2 283 {
rrknight 3:c16d726670b2 284 if(node_mode != 0xFF)
rrknight 3:c16d726670b2 285 {
rrknight 3:c16d726670b2 286 switch (node_mode)
rrknight 3:c16d726670b2 287 {
rrknight 3:c16d726670b2 288 //WARNING : changing mode requires 1 cycle, so "else" case has been added, commands needs to be sent at least twice to be applied when the mode change.
rrknight 3:c16d726670b2 289
rrknight 3:c16d726670b2 290 case POSITION: //first change modes of motors that will be triggered later
rrknight 3:c16d726670b2 291 if(activMode[node_ID-1] != POSITION) setModeOfOperationPDO(node_ID, VALUE_POSITION_MODE);
rrknight 4:396433e30e64 292 else setPosition(node_ID, value + calibOffset[node_ID-1]);
rrknight 3:c16d726670b2 293 break;
rrknight 3:c16d726670b2 294 case CURRENT: //first change modes of motors that will be triggered later (like CURRENT mode needs some time to be active)
rrknight 3:c16d726670b2 295 //pc.printf("setCurrent(%d, %d)\n", motorCmdBuffer[i].nodeID, motorCmdBuffer[i].value);
rrknight 3:c16d726670b2 296 if(activMode[node_ID-1] != CURRENT) setModeOfOperationPDO(node_ID, VALUE_CURRENT_MODE);
rrknight 3:c16d726670b2 297 else setCurrent(node_ID, value);
rrknight 3:c16d726670b2 298 break;
rrknight 3:c16d726670b2 299 case VELOCITY: //first change modes of motors that will be triggered later
rrknight 3:c16d726670b2 300 if(activMode[node_ID-1] != VELOCITY) setModeOfOperationPDO(node_ID, VALUE_VELOCITY_MODE);
rrknight 3:c16d726670b2 301 else setVelocity(node_ID, value);
rrknight 3:c16d726670b2 302 break;
rrknight 3:c16d726670b2 303 default:
rrknight 3:c16d726670b2 304 break;
rrknight 3:c16d726670b2 305 }
rrknight 2:7ab1d5918efe 306
rrknight 3:c16d726670b2 307 ledchain[3] = 1; //switch on when cmd is applied
rrknight 3:c16d726670b2 308 cmdPlayLED = true;
rrknight 0:18d7499b82f3 309 }
rrknight 3:c16d726670b2 310 else //idle mode 0xFF
rrknight 3:c16d726670b2 311 {
rrknight 3:c16d726670b2 312 if(!cmdPlayLED) ledchain[3] = 0; //switch off when slave is idle, i.e. all cmd in a set are 0xFF
rrknight 3:c16d726670b2 313 }
rrknight 0:18d7499b82f3 314 }
rrknight 2:7ab1d5918efe 315
rrknight 2:7ab1d5918efe 316 wait_us(10);
rrknight 2:7ab1d5918efe 317 }
rrknight 2:7ab1d5918efe 318 }
rrknight 2:7ab1d5918efe 319
rrknight 2:7ab1d5918efe 320 void updateTxSPIBuffer()
rrknight 2:7ab1d5918efe 321 {
rrknight 3:c16d726670b2 322 for(int i=1; i<=numberEpos2Boards; i++)
rrknight 2:7ab1d5918efe 323 {
rrknight 3:c16d726670b2 324 //uint8_t node_id = i;
rrknight 3:c16d726670b2 325
rrknight 3:c16d726670b2 326 getPosition(i);
rrknight 3:c16d726670b2 327 wait_us(200);
rrknight 3:c16d726670b2 328 getCurrent(i);
rrknight 3:c16d726670b2 329 wait_us(200);
rrknight 3:c16d726670b2 330 //getForce(i);
rrknight 3:c16d726670b2 331 wait_us(200);
rrknight 2:7ab1d5918efe 332 }
rrknight 2:7ab1d5918efe 333
rrknight 2:7ab1d5918efe 334 //build the motorDataSet_msg
rrknight 3:c16d726670b2 335 for(int i=0; i<numberEpos2Boards; i++)
rrknight 2:7ab1d5918efe 336 {
rrknight 2:7ab1d5918efe 337 uint8_t node_id = i+1;
rrknight 4:396433e30e64 338
rrknight 4:396433e30e64 339 int32_t position = encPosition[i] - calibOffset[i];
rrknight 4:396433e30e64 340
rrknight 5:52e3137c2831 341 int16_t force = getForce(11); //get hand force
rrknight 5:52e3137c2831 342
rrknight 4:396433e30e64 343 //position
rrknight 4:396433e30e64 344 writeBufferSPI[i][0] = position;
rrknight 4:396433e30e64 345 writeBufferSPI[i][1] = position>>8;
rrknight 4:396433e30e64 346 writeBufferSPI[i][2] = position>>16;
rrknight 4:396433e30e64 347 writeBufferSPI[i][3] = position>>24;
rrknight 4:396433e30e64 348
rrknight 4:396433e30e64 349 /*
rrknight 2:7ab1d5918efe 350 //position
rrknight 2:7ab1d5918efe 351 writeBufferSPI[i][0] = encPosition[node_id-1];
rrknight 2:7ab1d5918efe 352 writeBufferSPI[i][1] = encPosition[node_id-1]>>8;
rrknight 2:7ab1d5918efe 353 writeBufferSPI[i][2] = encPosition[node_id-1]>>16;
rrknight 2:7ab1d5918efe 354 writeBufferSPI[i][3] = encPosition[node_id-1]>>24;
rrknight 4:396433e30e64 355 */
rrknight 2:7ab1d5918efe 356 //current
rrknight 2:7ab1d5918efe 357 writeBufferSPI[i][4] = avgCurrent[node_id-1];
rrknight 2:7ab1d5918efe 358 writeBufferSPI[i][5] = avgCurrent[node_id-1]>>8;
rrknight 2:7ab1d5918efe 359
rrknight 2:7ab1d5918efe 360 //force
rrknight 5:52e3137c2831 361 //force
rrknight 5:52e3137c2831 362 writeBufferSPI[i][6] = force;
rrknight 5:52e3137c2831 363 writeBufferSPI[i][7] = force>>8;
rrknight 5:52e3137c2831 364 //writeBufferSPI[i][6] = 0;
rrknight 5:52e3137c2831 365 //writeBufferSPI[i][7] = 0;
rrknight 5:52e3137c2831 366 //pc.printf("%d\n", force);
rrknight 2:7ab1d5918efe 367
rrknight 2:7ab1d5918efe 368 //pc.printf("[%d] pos=%d cur=%d\n", node_id, encPosition[node_id-1], avgCurrent[node_id-1]);
rrknight 2:7ab1d5918efe 369 //force = getMedianForceVal(node_id); //medForce[node_id-1];
rrknight 2:7ab1d5918efe 370 }
rrknight 0:18d7499b82f3 371 }
rrknight 0:18d7499b82f3 372
rrknight 0:18d7499b82f3 373 void initBufferSPI()
rrknight 0:18d7499b82f3 374 {
rrknight 0:18d7499b82f3 375 //init the SPI arrays
rrknight 1:b430b4401fc4 376 for(int i=0; i<NUMBER_MAX_EPOS2_PER_SLAVE; i++)
rrknight 0:18d7499b82f3 377 {
rrknight 0:18d7499b82f3 378 for(int j=0; j<NUMBER_BYTES_PER_MSG; j++)
rrknight 0:18d7499b82f3 379 {
rrknight 2:7ab1d5918efe 380 writeBufferSPI[i][j] = 0x00;
rrknight 0:18d7499b82f3 381 readBufferSPI[i][j] = 0x00;
rrknight 0:18d7499b82f3 382 }
rrknight 0:18d7499b82f3 383 }
rrknight 4:396433e30e64 384
rrknight 3:c16d726670b2 385 /*
rrknight 1:b430b4401fc4 386 for(int n=0; n<NUMBER_MAX_EPOS2_PER_SLAVE; n++)
rrknight 0:18d7499b82f3 387 {
rrknight 1:b430b4401fc4 388 //position
rrknight 2:7ab1d5918efe 389 writeBufferSPI[n][0] = 0xA0+n;
rrknight 2:7ab1d5918efe 390 writeBufferSPI[n][1] = 0xB0+n;
rrknight 2:7ab1d5918efe 391 writeBufferSPI[n][2] = 0x00;
rrknight 2:7ab1d5918efe 392 writeBufferSPI[n][3] = 0x00;
rrknight 0:18d7499b82f3 393
rrknight 1:b430b4401fc4 394 //current
rrknight 0:18d7499b82f3 395 writeBufferSPI[n][4] = 0xC0+n;
rrknight 2:7ab1d5918efe 396 writeBufferSPI[n][5] = 0x00;
rrknight 2:7ab1d5918efe 397
rrknight 2:7ab1d5918efe 398 //force
rrknight 2:7ab1d5918efe 399 writeBufferSPI[n][6] = 0xD0+n;
rrknight 2:7ab1d5918efe 400 writeBufferSPI[n][7] = 0x00;
rrknight 3:c16d726670b2 401 }*/
rrknight 0:18d7499b82f3 402 }
rrknight 0:18d7499b82f3 403
rrknight 4:396433e30e64 404 void calibrate()
rrknight 4:396433e30e64 405 {
rrknight 4:396433e30e64 406 pc.printf("- Start Calibration\n\r");
therobotstudio 6:8a0250a4877a 407
rrknight 4:396433e30e64 408 //set all boards to current mode
rrknight 4:396433e30e64 409 for(int i=1; i<=numberEpos2Boards; i++)
rrknight 4:396433e30e64 410 {
rrknight 4:396433e30e64 411 setModeOfOperationPDO(i, VALUE_CURRENT_MODE);
rrknight 4:396433e30e64 412 }
rrknight 5:52e3137c2831 413
therobotstudio 6:8a0250a4877a 414 ledchain[2] = 1;
therobotstudio 6:8a0250a4877a 415
therobotstudio 6:8a0250a4877a 416 wait_ms(20);
rrknight 4:396433e30e64 417
rrknight 5:52e3137c2831 418 for(int j=1; j<=numberEpos2Boards; j++)
rrknight 4:396433e30e64 419 {
therobotstudio 6:8a0250a4877a 420 //pc.printf("- Calibration number %d\n\r", j);
rrknight 4:396433e30e64 421 //trigger current in certain order
therobotstudio 6:8a0250a4877a 422 setCurrent(j, 100);
therobotstudio 6:8a0250a4877a 423 wait_ms(20);
rrknight 5:52e3137c2831 424 }
therobotstudio 6:8a0250a4877a 425
therobotstudio 6:8a0250a4877a 426 ledchain[3] = 1;
therobotstudio 6:8a0250a4877a 427 /*
rrknight 5:52e3137c2831 428 pc.printf("- Offsets will be recorded in 5 sec...");
rrknight 5:52e3137c2831 429 wait_ms(1000);
rrknight 5:52e3137c2831 430 pc.printf("4...");
therobotstudio 6:8a0250a4877a 431 ledchain[0] = 1;
rrknight 5:52e3137c2831 432 wait_ms(1000);
therobotstudio 6:8a0250a4877a 433 ledchain[0] = 0;
therobotstudio 6:8a0250a4877a 434 ledchain[1] = 1;
rrknight 5:52e3137c2831 435 pc.printf("3...");
rrknight 5:52e3137c2831 436 wait_ms(1000);
therobotstudio 6:8a0250a4877a 437 ledchain[1] = 0;
therobotstudio 6:8a0250a4877a 438 ledchain[2] = 1;
rrknight 5:52e3137c2831 439 pc.printf("2...");
rrknight 5:52e3137c2831 440 wait_ms(1000);
therobotstudio 6:8a0250a4877a 441 ledchain[2] = 0;
therobotstudio 6:8a0250a4877a 442 ledchain[3] = 1;
rrknight 5:52e3137c2831 443 pc.printf("1...");
rrknight 5:52e3137c2831 444 wait_ms(1000);
therobotstudio 6:8a0250a4877a 445 ledchain[3] = 0;
rrknight 5:52e3137c2831 446 pc.printf("0...");
therobotstudio 6:8a0250a4877a 447 */
therobotstudio 6:8a0250a4877a 448 /*
rrknight 5:52e3137c2831 449 //save current encoder position as calib offset
rrknight 5:52e3137c2831 450 for(int i=0; i<numberEpos2Boards; i++)
rrknight 5:52e3137c2831 451 {
rrknight 5:52e3137c2831 452 int nodeid = i+1;
rrknight 5:52e3137c2831 453 getPosition(nodeid);
rrknight 5:52e3137c2831 454 wait_us(500);
rrknight 5:52e3137c2831 455 calibOffset[i] = encPosition[i];
rrknight 4:396433e30e64 456
rrknight 5:52e3137c2831 457 //pc.printf("%d\n\r", calibOffset[i]);
rrknight 5:52e3137c2831 458 }
rrknight 5:52e3137c2831 459 pc.printf("OK\n\r");
therobotstudio 6:8a0250a4877a 460 *//*
rrknight 5:52e3137c2831 461 pc.printf("current to zero\n\r");
rrknight 5:52e3137c2831 462 for(int i=0; i<numberEpos2Boards; i++)
rrknight 5:52e3137c2831 463 {
rrknight 5:52e3137c2831 464 int nodeid = i+1;
rrknight 5:52e3137c2831 465 setCurrent(nodeid, 0);
rrknight 5:52e3137c2831 466 wait_us(500);
therobotstudio 6:8a0250a4877a 467 }*/
therobotstudio 6:8a0250a4877a 468 //For case where motor start from zero
rrknight 4:396433e30e64 469 for(int i=0; i<numberEpos2Boards; i++)
therobotstudio 6:8a0250a4877a 470 {
therobotstudio 6:8a0250a4877a 471 calibOffset[i] = 0;
therobotstudio 6:8a0250a4877a 472 }
rrknight 4:396433e30e64 473 }
rrknight 4:396433e30e64 474
therobotstudio 6:8a0250a4877a 475 /*** Main ***/
rrknight 0:18d7499b82f3 476 int main()
rrknight 0:18d7499b82f3 477 {
rrknight 2:7ab1d5918efe 478 pc.baud(115200);
rrknight 3:c16d726670b2 479 pc.printf("*** Start Slave Main - DCX Left Arm ***\n\r");
rrknight 0:18d7499b82f3 480
rrknight 0:18d7499b82f3 481 logicPin = 0;
rrknight 2:7ab1d5918efe 482
rrknight 1:b430b4401fc4 483 uint8_t my_val = 0x00; //to read and empty the SPI FIFO buffer
rrknight 0:18d7499b82f3 484
rrknight 0:18d7499b82f3 485 initBufferSPI();
rrknight 0:18d7499b82f3 486 //sync_master = 0;
rrknight 0:18d7499b82f3 487 char rByte = 0x00;
rrknight 0:18d7499b82f3 488
rrknight 0:18d7499b82f3 489 char threeArrows = 0;
rrknight 0:18d7499b82f3 490 bool threeArrowsFound = false;
rrknight 0:18d7499b82f3 491 bool slaveSelected = false;
rrknight 1:b430b4401fc4 492 bool checksumReceived = false;
rrknight 1:b430b4401fc4 493 bool cmdValid = false;
rrknight 0:18d7499b82f3 494
rrknight 0:18d7499b82f3 495 int i = 0; //msg
rrknight 0:18d7499b82f3 496 int j = 0; //byte number
rrknight 0:18d7499b82f3 497
rrknight 0:18d7499b82f3 498 pc.printf("--- Initialise EPOS2 boards ---\n\r");
rrknight 2:7ab1d5918efe 499
therobotstudio 6:8a0250a4877a 500 ledchain[0] = 1;
rrknight 2:7ab1d5918efe 501
rrknight 3:c16d726670b2 502 while(initEposBoard(numberEpos2Boards) == EPOS2_OK)
rrknight 3:c16d726670b2 503 {
rrknight 3:c16d726670b2 504 numberEpos2Boards++;
rrknight 3:c16d726670b2 505 }
rrknight 3:c16d726670b2 506
rrknight 3:c16d726670b2 507 numberEpos2Boards--; //because it has been increment one time too much at the end of the while loop
rrknight 0:18d7499b82f3 508
therobotstudio 6:8a0250a4877a 509 ledchain[1] = 1;
rrknight 0:18d7499b82f3 510
rrknight 0:18d7499b82f3 511 pc.printf("--- Enable Interrupts ---\n\r");
rrknight 0:18d7499b82f3 512 //attach the interrupt function
rrknight 0:18d7499b82f3 513 cantoepos.attach(&interrupt);
rrknight 0:18d7499b82f3 514 __enable_irq();
rrknight 0:18d7499b82f3 515
rrknight 4:396433e30e64 516 pc.printf("--- Calibrate Arm ---\n\r");
therobotstudio 6:8a0250a4877a 517
rrknight 4:396433e30e64 518 calibrate();
rrknight 4:396433e30e64 519
rrknight 0:18d7499b82f3 520 device.reply(0x62); //Prime SPI with first reply
rrknight 0:18d7499b82f3 521
rrknight 0:18d7499b82f3 522 //gather first pack of data
rrknight 2:7ab1d5918efe 523 //get the sensor values
rrknight 3:c16d726670b2 524 updateTxSPIBuffer();
rrknight 0:18d7499b82f3 525
rrknight 2:7ab1d5918efe 526 //update checksum
rrknight 2:7ab1d5918efe 527 calculateSPIChecksum();
rrknight 0:18d7499b82f3 528
rrknight 0:18d7499b82f3 529 //then start the main loop
rrknight 0:18d7499b82f3 530 pc.printf("--- Start main loop ---\n\r");
therobotstudio 6:8a0250a4877a 531
therobotstudio 6:8a0250a4877a 532 ledchain[0] = 0;
therobotstudio 6:8a0250a4877a 533 ledchain[1] = 0;
therobotstudio 6:8a0250a4877a 534 ledchain[2] = 0;
therobotstudio 6:8a0250a4877a 535 ledchain[3] = 0;
rrknight 1:b430b4401fc4 536
rrknight 0:18d7499b82f3 537 while(1)
rrknight 2:7ab1d5918efe 538 {
rrknight 2:7ab1d5918efe 539 ledchain[0] = 0; //not selected by master
rrknight 2:7ab1d5918efe 540 ledchain[3] = 0; //no commands played
rrknight 2:7ab1d5918efe 541
rrknight 0:18d7499b82f3 542 //wait, the master will put the pin high at some point, for 10us
rrknight 0:18d7499b82f3 543 while(sync_master == 0)
rrknight 0:18d7499b82f3 544 {
rrknight 2:7ab1d5918efe 545 // logicPin = 1;
rrknight 0:18d7499b82f3 546 wait_us(1);
rrknight 2:7ab1d5918efe 547 // logicPin = 0;
rrknight 0:18d7499b82f3 548 }
rrknight 0:18d7499b82f3 549
rrknight 0:18d7499b82f3 550 slaveSelected = true;
rrknight 2:7ab1d5918efe 551 ledchain[0] = 1;
rrknight 0:18d7499b82f3 552
rrknight 2:7ab1d5918efe 553 while(LPC_SSP1->SR & RNE) // While RNE-Bit = 1 (FIFO receive buffer not empty)...
rrknight 0:18d7499b82f3 554 my_val = LPC_SSP1->DR; // Read the byte in the buffer
rrknight 2:7ab1d5918efe 555 /*
rrknight 2:7ab1d5918efe 556 {
rrknight 2:7ab1d5918efe 557 my_val = LPC_SSP1->DR; // Read the byte in the buffer
rrknight 2:7ab1d5918efe 558
rrknight 2:7ab1d5918efe 559 logicPin = 1;
rrknight 2:7ab1d5918efe 560 wait_us(1);
rrknight 2:7ab1d5918efe 561 logicPin = 0;
rrknight 2:7ab1d5918efe 562 }
rrknight 2:7ab1d5918efe 563 */
rrknight 0:18d7499b82f3 564 //reset for a new message
rrknight 0:18d7499b82f3 565 i = 0;
rrknight 0:18d7499b82f3 566 j = 0;
rrknight 0:18d7499b82f3 567 threeArrows = 0;
rrknight 0:18d7499b82f3 568 threeArrowsFound = false;
rrknight 2:7ab1d5918efe 569 checksumReceived = false;
rrknight 0:18d7499b82f3 570
rrknight 1:b430b4401fc4 571 logicPin = 1;
rrknight 0:18d7499b82f3 572
rrknight 0:18d7499b82f3 573 __disable_irq();
rrknight 0:18d7499b82f3 574
rrknight 0:18d7499b82f3 575 while(slaveSelected)
rrknight 2:7ab1d5918efe 576 {
rrknight 0:18d7499b82f3 577 //SPI polling
rrknight 0:18d7499b82f3 578 if(device.receive())
rrknight 1:b430b4401fc4 579 {
rrknight 1:b430b4401fc4 580 rByte = device.read(); // Read byte from master
rrknight 0:18d7499b82f3 581 //pc.printf("0x%02X ", rByte);
rrknight 0:18d7499b82f3 582
rrknight 1:b430b4401fc4 583 if(threeArrows < 3)
rrknight 0:18d7499b82f3 584 {
rrknight 1:b430b4401fc4 585 if(rByte == OPEN_ARROW)
rrknight 1:b430b4401fc4 586 {
rrknight 1:b430b4401fc4 587 threeArrows++;
rrknight 1:b430b4401fc4 588 //pc.printf("3A++\n\r");
rrknight 1:b430b4401fc4 589 }
rrknight 1:b430b4401fc4 590 else
rrknight 1:b430b4401fc4 591 {
rrknight 1:b430b4401fc4 592 //threeArrows = 0;
rrknight 1:b430b4401fc4 593 //startReceiving = false;
rrknight 1:b430b4401fc4 594 //pc.printf("error3A\n");
rrknight 1:b430b4401fc4 595 //slaveSelected = false;
rrknight 1:b430b4401fc4 596 }
rrknight 1:b430b4401fc4 597
rrknight 1:b430b4401fc4 598 if(threeArrows == 3)
rrknight 1:b430b4401fc4 599 {
rrknight 1:b430b4401fc4 600 device.reply(writeBufferSPI[i][j]);
rrknight 1:b430b4401fc4 601 threeArrowsFound = true;
rrknight 1:b430b4401fc4 602 }
rrknight 1:b430b4401fc4 603 else
rrknight 1:b430b4401fc4 604 {
rrknight 1:b430b4401fc4 605 device.reply(0x62); //close arrow : >
rrknight 1:b430b4401fc4 606 }
rrknight 1:b430b4401fc4 607 }
rrknight 1:b430b4401fc4 608 else
rrknight 1:b430b4401fc4 609 {
rrknight 1:b430b4401fc4 610 readBufferSPI[i][j] = rByte;
rrknight 1:b430b4401fc4 611
rrknight 1:b430b4401fc4 612 j++; //write next byte next time
rrknight 1:b430b4401fc4 613
rrknight 1:b430b4401fc4 614 if(j >= NUMBER_BYTES_PER_MSG)
rrknight 1:b430b4401fc4 615 {
rrknight 1:b430b4401fc4 616 j = 0;
rrknight 1:b430b4401fc4 617 i++; //next node
rrknight 0:18d7499b82f3 618
rrknight 1:b430b4401fc4 619 if(i >= NUMBER_MAX_EPOS2_PER_SLAVE)
rrknight 1:b430b4401fc4 620 {
rrknight 1:b430b4401fc4 621 //finished reading the array
rrknight 1:b430b4401fc4 622 /*
rrknight 1:b430b4401fc4 623 for(int n=0; n<1; n++)
rrknight 0:18d7499b82f3 624 {
rrknight 1:b430b4401fc4 625 pc.printf("0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", readBufferSPI[n][0], readBufferSPI[n][1], readBufferSPI[n][2], readBufferSPI[n][3], readBufferSPI[n][4], readBufferSPI[n][5], readBufferSPI[n][6]);
rrknight 1:b430b4401fc4 626 }
rrknight 1:b430b4401fc4 627 */
rrknight 1:b430b4401fc4 628
rrknight 1:b430b4401fc4 629 //reset
rrknight 1:b430b4401fc4 630 threeArrows = 0;
rrknight 1:b430b4401fc4 631 i = 0;
rrknight 1:b430b4401fc4 632 j = 0;
rrknight 1:b430b4401fc4 633 slaveSelected = false; //to end the while loop
rrknight 2:7ab1d5918efe 634 /*
rrknight 2:7ab1d5918efe 635 logicPin = 1;
rrknight 2:7ab1d5918efe 636 wait_us(1);
rrknight 2:7ab1d5918efe 637 logicPin = 0;*/
rrknight 1:b430b4401fc4 638 }
rrknight 1:b430b4401fc4 639 }
rrknight 1:b430b4401fc4 640
rrknight 1:b430b4401fc4 641 if(slaveSelected) device.reply(writeBufferSPI[i][j]);
rrknight 1:b430b4401fc4 642 else device.reply(dataChecksum); //checksum
rrknight 1:b430b4401fc4 643 }
rrknight 0:18d7499b82f3 644 }//if
rrknight 0:18d7499b82f3 645
rrknight 0:18d7499b82f3 646 wait_us(1);
rrknight 0:18d7499b82f3 647 }//while slaveSelected
rrknight 2:7ab1d5918efe 648
rrknight 2:7ab1d5918efe 649 //wait_us(30);
rrknight 2:7ab1d5918efe 650 //logicPin = 1;
rrknight 1:b430b4401fc4 651 //read the checksum
rrknight 1:b430b4401fc4 652 while(!checksumReceived)
rrknight 1:b430b4401fc4 653 {
rrknight 2:7ab1d5918efe 654 //pc.printf("w");
rrknight 1:b430b4401fc4 655 if(device.receive())
rrknight 1:b430b4401fc4 656 {
rrknight 1:b430b4401fc4 657 cmdChecksum = device.read();
rrknight 3:c16d726670b2 658 //pc.printf("%02X\n", cmdChecksum);
rrknight 1:b430b4401fc4 659 cmdValid = verifyChecksum();
rrknight 1:b430b4401fc4 660 checksumReceived = true; //exit while loop
rrknight 1:b430b4401fc4 661 }
rrknight 1:b430b4401fc4 662
rrknight 1:b430b4401fc4 663 wait_us(1);
rrknight 2:7ab1d5918efe 664 }
rrknight 0:18d7499b82f3 665
rrknight 2:7ab1d5918efe 666
rrknight 2:7ab1d5918efe 667 __enable_irq();
rrknight 2:7ab1d5918efe 668
rrknight 2:7ab1d5918efe 669 logicPin = 0;
rrknight 3:c16d726670b2 670 /*
rrknight 3:c16d726670b2 671 //print some data:
rrknight 3:c16d726670b2 672 for(int n=0; n<1; n++)
rrknight 3:c16d726670b2 673 {
rrknight 3:c16d726670b2 674 pc.printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", readBufferSPI[n][0], readBufferSPI[n][1], readBufferSPI[n][2], readBufferSPI[n][3], readBufferSPI[n][4], readBufferSPI[n][5], readBufferSPI[n][6], readBufferSPI[n][7]);
rrknight 3:c16d726670b2 675 }
rrknight 3:c16d726670b2 676 */
rrknight 3:c16d726670b2 677 //pc.printf("%02X\n", readBufferSPI[0][4]);
rrknight 3:c16d726670b2 678
rrknight 2:7ab1d5918efe 679 wait_us(30);
rrknight 3:c16d726670b2 680 /* logicPin = 1;
rrknight 0:18d7499b82f3 681 wait_us(10);
rrknight 2:7ab1d5918efe 682 logicPin = 0;
rrknight 2:7ab1d5918efe 683 wait_us(20);
rrknight 2:7ab1d5918efe 684 */
rrknight 1:b430b4401fc4 685 //if checksum is correct, then play the cmds
rrknight 1:b430b4401fc4 686 if(cmdValid)
rrknight 1:b430b4401fc4 687 {
rrknight 2:7ab1d5918efe 688 logicPin = 1;
rrknight 2:7ab1d5918efe 689 //play the commands
rrknight 2:7ab1d5918efe 690 commandPlayer();
rrknight 1:b430b4401fc4 691 cmdValid = false; //reset for next packet
rrknight 2:7ab1d5918efe 692 logicPin = 0;
rrknight 1:b430b4401fc4 693 }
rrknight 2:7ab1d5918efe 694 /*
rrknight 2:7ab1d5918efe 695 wait_us(20);
rrknight 2:7ab1d5918efe 696 logicPin = 1;
rrknight 1:b430b4401fc4 697 wait_us(10);
rrknight 2:7ab1d5918efe 698 logicPin = 0;
rrknight 2:7ab1d5918efe 699 */
rrknight 2:7ab1d5918efe 700 //get the sensor values ready to be sent for the next loop
rrknight 2:7ab1d5918efe 701 //update the writeBufferSPI
rrknight 3:c16d726670b2 702 updateTxSPIBuffer(); //test with known data first
rrknight 1:b430b4401fc4 703
rrknight 2:7ab1d5918efe 704 //compute checksum
rrknight 2:7ab1d5918efe 705 calculateSPIChecksum();
rrknight 0:18d7499b82f3 706
rrknight 2:7ab1d5918efe 707 //logicPin = 0;
rrknight 2:7ab1d5918efe 708 //ledchain[0] = 0;
rrknight 2:7ab1d5918efe 709 wait_us(10);
rrknight 0:18d7499b82f3 710 }// main while end
rrknight 0:18d7499b82f3 711 }// main end
rrknight 0:18d7499b82f3 712
rrknight 2:7ab1d5918efe 713 #endif //COMPILE_MAIN_CODE_TRS_SLAVE