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

Dependencies:   mbed

Revision:
2:7ab1d5918efe
Parent:
1:b430b4401fc4
Child:
3:c16d726670b2
--- a/main.cpp	Wed Mar 06 17:07:47 2013 +0000
+++ b/main.cpp	Fri Mar 08 17:54:03 2013 +0000
@@ -1,5 +1,5 @@
-#define COMPILE_MAIN_CODE_ROSSERIAL
-#ifdef  COMPILE_MAIN_CODE_ROSSERIAL
+#define COMPILE_MAIN_CODE_TRS_SLAVE
+#ifdef  COMPILE_MAIN_CODE_TRS_SLAVE
 
 //include files
 #include "include/eposCmd.h"
@@ -14,7 +14,6 @@
 #define RNE 0x04
 
 SPISlave device(p5, p6, p7, p8); // mosi, miso, sclk, ssel
-DigitalOut myled(LED1);
 DigitalIn sync_master(p25);
 
 DigitalOut logicPin(p26); //to record with Logic analyser on an event, pin high.
@@ -68,7 +67,7 @@
 }
 */
 
-bool verifyChecksum()
+bool verifyChecksum() //check the data comming from the master over SPI
 {      
     for(int i=0; i<NUMBER_MAX_EPOS2_PER_SLAVE; i++)
     {
@@ -79,14 +78,31 @@
     }        
     
     cmdChecksum++; //add 1 to obtain 0x00
+    
+    //pc.printf("sum 0x%02X\n\r", cmdChecksum);
         
     if(cmdChecksum == 0x00) return true;
     else return false;
 }
 
+void calculateSPIChecksum() //compute checksum for the data sent to the master over SPI
+{   
+    int sum = 0;
+           
+    for(int i=0; i<NUMBER_MAX_EPOS2_PER_SLAVE; i++)
+    {
+        for(int j=0; j<NUMBER_BYTES_PER_MSG; j++)
+        {
+            sum += writeBufferSPI[i][j];
+        }
+    }       
+        
+    dataChecksum = (char)(~sum); //reverse 0 and 1, and cast as byte
+}
+
 int16_t getMedianForceVal(const int8_t nodeID) 
 {         
-    logicPin = 1;
+    //logicPin = 1;
     
     for(int m=0; m<NB_SAMPLES_MEDIAN; m++)
     {          
@@ -107,7 +123,7 @@
         sortForceVal[p+1] = n;
     }
     
-    logicPin = 0;
+    //logicPin = 0;
        
     return sortForceVal[2];
 }
@@ -242,34 +258,86 @@
 } //end interrupt
 
 void commandPlayer() //called in main every 20ms
-{/*
-    for(int i= 0; i<CMD_BUFFER_SIZE; i++)
+{
+    //at least one cmd played
+    bool cmdPlayLED = false;
+    
+    for(int i= 0; i<NUMBER_MAX_EPOS2_PER_SLAVE; i++)
     {        
-        if(motorCmdBuffer[i].beatDelay != -1) 
-        {       
-            switch (motorCmdBuffer[i].mode)
+        uint8_t node_ID = readBufferSPI[i][0];
+        uint8_t node_mode = readBufferSPI[i][1];
+        int32_t value = readBufferSPI[i][2] + (readBufferSPI[i][3]<<8) + (readBufferSPI[i][4]<<16) + (readBufferSPI[i][5]<<24);
+                
+        if(node_mode != 0xFF) 
+        {       /*
+            switch (node_mode)
             {                
                 case POSITION: //first change modes of motors that will be triggered later   
-                    if((activMode[motorCmdBuffer[i].nodeID-1] != POSITION) && (motorCmdBuffer[i].beatDelay == 1)) setModeOfOperationPDO(motorCmdBuffer[i].nodeID, VALUE_POSITION_MODE);         
-                    if(motorCmdBuffer[i].beatDelay == 0) setPosition(motorCmdBuffer[i].nodeID, motorCmdBuffer[i].value);                    
+                    if(activMode[node_ID-1] != POSITION) setModeOfOperationPDO(node_ID, VALUE_POSITION_MODE);         
+                    setPosition(node_ID, value);                    
                     break;
                 case CURRENT: //first change modes of motors that will be triggered later (like CURRENT mode needs some time to be active) 
                     //pc.printf("setCurrent(%d, %d)\n", motorCmdBuffer[i].nodeID, motorCmdBuffer[i].value);
-                    if((activMode[motorCmdBuffer[i].nodeID-1] != CURRENT) && (motorCmdBuffer[i].beatDelay == 1)) setModeOfOperationPDO(motorCmdBuffer[i].nodeID, VALUE_CURRENT_MODE);
-                    if(motorCmdBuffer[i].beatDelay == 0) setCurrent(motorCmdBuffer[i].nodeID, motorCmdBuffer[i].value);
+                    if(activMode[node_ID-1] != CURRENT) setModeOfOperationPDO(node_ID, VALUE_CURRENT_MODE);
+                    setCurrent(node_ID, value);
                     break;
                 case VELOCITY: //first change modes of motors that will be triggered later            
-                    if((activMode[motorCmdBuffer[i].nodeID-1] != VELOCITY) && (motorCmdBuffer[i].beatDelay == 1)) setModeOfOperationPDO(motorCmdBuffer[i].nodeID, VALUE_VELOCITY_MODE);         
-                    if(motorCmdBuffer[i].beatDelay == 0) setVelocity(motorCmdBuffer[i].nodeID, motorCmdBuffer[i].value);
+                    if(activMode[node_ID-1] != VELOCITY) setModeOfOperationPDO(node_ID, VALUE_VELOCITY_MODE);         
+                    setVelocity(node_ID, value);
                     break;
                 default:
                     break;
             }
-            
-            //decrement only cmd with delay != -1, so cmd that has not been played yet.
-            motorCmdBuffer[i].beatDelay = motorCmdBuffer[i].beatDelay - 1;
+            */
+            ledchain[3] = 1;    //switch on when cmd is applied
+            cmdPlayLED = true;
+        }
+        else //idle mode 0xFF
+        {
+            if(!cmdPlayLED) ledchain[3] = 0;    //switch off when slave is idle, i.e. all cmd in a set are 0xFF
         }
-    }*/
+        
+        wait_us(10);
+    }
+}
+
+void updateTxSPIBuffer()
+{
+    for(int i=0; i<NUMBER_EPOS2_BOARDS; i++)
+    {
+        uint8_t node_id = i+1;
+        //if(node_id!=5)
+        //{                        
+            getPosition(node_id);
+            wait_us(200);   
+            getCurrent(node_id);
+            wait_us(200);
+            //if((node_id >= 2) && (node_id <= 9)) getMedianForceVal(node_id);                                           
+        //}            
+    }
+      
+    //build the motorDataSet_msg          
+    for(int i=0; i<NUMBER_EPOS2_BOARDS; i++)
+    {    
+        uint8_t node_id = i+1;
+                    
+        //position
+        writeBufferSPI[i][0] = encPosition[node_id-1];
+        writeBufferSPI[i][1] = encPosition[node_id-1]>>8;
+        writeBufferSPI[i][2] = encPosition[node_id-1]>>16;
+        writeBufferSPI[i][3] = encPosition[node_id-1]>>24;
+        
+        //current
+        writeBufferSPI[i][4] = avgCurrent[node_id-1];
+        writeBufferSPI[i][5] = avgCurrent[node_id-1]>>8;
+        
+        //force       
+        writeBufferSPI[i][6] = 0;
+        writeBufferSPI[i][7] = 0;
+                
+        //pc.printf("[%d] pos=%d cur=%d\n", node_id, encPosition[node_id-1], avgCurrent[node_id-1]);                        
+        //force = getMedianForceVal(node_id); //medForce[node_id-1];                  
+    }
 }
 
 void initBufferSPI()
@@ -279,7 +347,7 @@
     { 
         for(int j=0; j<NUMBER_BYTES_PER_MSG; j++)
         {             
-            //writeBufferSPI[i][j] = 0x00;
+            writeBufferSPI[i][j] = 0x00;
             readBufferSPI[i][j] = 0x00;            
         }
     }
@@ -287,29 +355,28 @@
     for(int n=0; n<NUMBER_MAX_EPOS2_PER_SLAVE; n++)
     {
         //position
-        writeBufferSPI[n][0] = 0x60+n; 
-        writeBufferSPI[n][1] = 0x70+n;       
-        writeBufferSPI[n][2] = 0x80+n; 
-        writeBufferSPI[n][3] = 0x90+n; 
+        writeBufferSPI[n][0] = 0xA0+n; 
+        writeBufferSPI[n][1] = 0xB0+n;       
+        writeBufferSPI[n][2] = 0x00; 
+        writeBufferSPI[n][3] = 0x00; 
         
         //current
         writeBufferSPI[n][4] = 0xC0+n; 
-        writeBufferSPI[n][5] = 0xD0+n;         
-        writeBufferSPI[n][6] = 0xE0+n;
-        writeBufferSPI[n][7] = 0xF0+n;      
+        writeBufferSPI[n][5] = 0x00;  
+        
+        //force       
+        writeBufferSPI[n][6] = 0xD0+n;
+        writeBufferSPI[n][7] = 0x00;      
     }
 }
 
 int main() 
 {          
-    pc.baud(115200); //115200 //57600
+    pc.baud(115200);
     pc.printf("*** Start Slave Main ***\n\r");
     
     logicPin = 0;
-    //timer.start();
-    //uint64_t begin = 0;
-    //uint64_t end = 0;
-    //int64_t pauseTime = 0;
+    
     uint8_t my_val = 0x00; //to read and empty the SPI FIFO buffer 
     
     initBufferSPI();
@@ -317,8 +384,6 @@
     char rByte = 0x00;
     
     char threeArrows = 0;
-    //char closeArrowChar = 0x62; //>
-    //bool startReceiving = false;
     bool threeArrowsFound = false;
     bool slaveSelected = false;
     bool checksumReceived = false;
@@ -328,12 +393,17 @@
     int j = 0; //byte number
         
     pc.printf("--- Initialise EPOS2 boards ---\n\r");    
+    
+    /*
     for(int i=1; i<=NUMBER_EPOS2_BOARDS; i++)
     {
-        if(i!=5) initEposBoard(i); 
+        initEposBoard(i); 
     } 
+    */
+    
+    //initEposBoard(0);
         
-    ledchain[0] = 1;   
+    //ledchain[0] = 1;   
     
     pc.printf("--- Enable Interrupts ---\n\r"); 
     //attach the interrupt function
@@ -343,67 +413,55 @@
     device.reply(0x62); //Prime SPI with first reply
 
     //gather first pack of data
-    //get the sensor values          
-    for(int i=0; i<NUMBER_EPOS2_BOARDS; i++)
-    {
-        uint8_t node_id = i+1;
-        if(node_id!=5)
-        {                        
-            getPosition(node_id);
-            wait_us(300);   
-            getCurrent(node_id);
-            wait_us(300);
-            //if((node_id >= 2) && (node_id <= 9)) getMedianForceVal(node_id);                                           
-        }            
-    }
+    //get the sensor values       
+    //updateTxSPIBuffer();      
       
-    //build the motorDataSet_msg          
-    for(int i=0; i<NUMBER_EPOS2_BOARDS; i++)
-    {
-        uint8_t node_id = i+1;
-        if(node_id!=5)
-        { 
-            //pc.printf("[%d] pos=%d cur=%d\n", node_id, encPosition[node_id-1], avgCurrent[node_id-1]);
-            
-            //motorDataSet_msg.motorData[i].encPosition = encPosition[node_id-1];    
-            //motorDataSet_msg.motorData[i].current = avgCurrent[node_id-1];
-            //if((node_id >= 2) && (node_id <= 9)) motorDataSet_msg.motorData[i].force = getMedianForceVal(node_id); //medForce[node_id-1]; 
-        }           
-    }
-    
-    
+    //update checksum
+    calculateSPIChecksum();    
     
     //then start the main loop
     pc.printf("--- Start main loop ---\n\r"); 
-    
-    setModeOfOperationPDO(1, VALUE_POSITION_MODE);
-    //setCurrent(1, 150);
            
     while(1) 
-    {                
+    {   
+        ledchain[0] = 0; //not selected by master
+        ledchain[3] = 0; //no commands played
+                     
         //wait, the master will put the pin high at some point, for 10us
         while(sync_master == 0)
         {
+           // logicPin = 1;
             wait_us(1);  
+           // logicPin = 0;
         }
         
         slaveSelected = true;
+        ledchain[0] = 1; 
         
-        while (LPC_SSP1->SR & RNE)          // While RNE-Bit = 1 (FIFO receive buffer not empty)...
+        while(LPC_SSP1->SR & RNE)                  // While RNE-Bit = 1 (FIFO receive buffer not empty)...
         my_val = LPC_SSP1->DR;          // Read the byte in the buffer
-        
+       /*
+        {
+            my_val = LPC_SSP1->DR;          // Read the byte in the buffer
+            
+            logicPin = 1;
+            wait_us(1);  
+            logicPin = 0;
+        }
+        */
         //reset for a new message
         i = 0;
         j = 0;
         threeArrows = 0;
         threeArrowsFound = false;
+        checksumReceived = false;
         
         logicPin = 1;        
         
         __disable_irq();
         
         while(slaveSelected)
-        {
+        {                            
             //SPI polling
             if(device.receive()) 
             {
@@ -461,6 +519,10 @@
                             i = 0;
                             j = 0;
                             slaveSelected = false; //to end the while loop
+                           /* 
+                            logicPin = 1;
+                            wait_us(1);  
+                            logicPin = 0;*/
                         }             
                     } 
                                                   
@@ -471,104 +533,62 @@
             
             wait_us(1);
         }//while slaveSelected
-        
+                        
+        //wait_us(30);
+        //logicPin = 1;
         //read the checksum
         while(!checksumReceived)
         {
+            //pc.printf("w");
             if(device.receive()) 
             {
                 cmdChecksum = device.read();
+                //pc.printf("cmdChecksum 0x%02X\n", cmdChecksum);
                 cmdValid = verifyChecksum();                 
                 checksumReceived = true; //exit while loop
             }
             
             wait_us(1);
-        }           
-        
-        __enable_irq();
+        }  
         
-        logicPin = 0;
+         
+        __enable_irq();
+     
+        logicPin = 0; 
+     
+      /*     
+        wait_us(30);
+        logicPin = 1;
         wait_us(10);
-        logicPin = 1;
-        
+        logicPin = 0;
+        wait_us(20);
+        */
         //if checksum is correct, then play the cmds
         if(cmdValid)
         {
-            //play the commands        
-            for(int i=0; i<NUMBER_MAX_EPOS2_PER_SLAVE; i++)
-            {
-                uint8_t node_ID = readBufferSPI[i][0];
-                uint8_t node_mode = readBufferSPI[i][1];
-                int position = readBufferSPI[i][2] + (readBufferSPI[i][3]<<8) + (readBufferSPI[i][4]<<16) + (readBufferSPI[i][5]<<24);
-                
-                //uint8_t cmd_delay = readBufferSPI[i][6]; //TODO delay
-                
-                //pc.printf("Cmd[%d][%d][%d][%d]\n", node_ID, node_mode, position, cmd_delay);
-                
-                if(node_mode == 1)
-                setPosition(node_ID, position); //test
-                
-                wait_us(10);
-            } 
-            
+            logicPin = 1;
+            //play the commands     
+            commandPlayer();     
             cmdValid = false; //reset for next packet  
+            logicPin = 0;
         }
-        
-        logicPin = 0;  
+        /*
+        wait_us(20);
+        logicPin = 1;  
         wait_us(10);
-        logicPin = 1;
-        
+        logicPin = 0;
+          */              
+        //get the sensor values ready to be sent for the next loop   
+        //update the writeBufferSPI
+        //updateTxSPIBuffer();    //test with known data first
         
-        //get the sensor values          
-        for(int i=0; i<NUMBER_EPOS2_BOARDS; i++)
-        {
-            uint8_t node_id = i+1;
-            //if(node_id!=5)
-            //{                        
-            getPosition(node_id);
-            wait_us(200);
-            getCurrent(node_id);
-            wait_us(200);
-                //if((node_id >= 2) && (node_id <= 9)) getMedianForceVal(node_id);                                           
-            //}            
-        }
-        
-        //update the writeBufferSPI
-        
-        //compute checksum
-        
-        
-    /*      
-        //build the motorDataSet_msg          
-        for(int i=0; i<NUMBER_EPOS2_BOARDS; i++)
-        {
-            uint8_t node_id = i+1;
-            //if(node_id!=5)
-            //{ 
-                //pc.printf("[%d] pos=%d cur=%d\n", node_id, encPosition[node_id-1], avgCurrent[node_id-1]);
-                
-                //motorDataSet_msg.motorData[i].encPosition = encPosition[node_id-1];    
-                //motorDataSet_msg.motorData[i].current = avgCurrent[node_id-1];
-                //if((node_id >= 2) && (node_id <= 9)) motorDataSet_msg.motorData[i].force = getMedianForceVal(node_id); //medForce[node_id-1]; 
-            //}           
-        }
-    */    
-        logicPin = 0; 
+        //compute checksum        
+        calculateSPIChecksum();
             
-        wait_us(10);
-        
-    /*       
-        //disable interrupts and publish it        
-        __disable_irq();
-        motorDataSetPub.publish(&motorDataSet_msg);                 
-        //this check if there are some msg published on the topics, and excecute the cb functions        
-        nh.spinOnce();
-        __enable_irq();
-     */   
-        //this will excecute cmds of the array that are ready (delay 0)         
-        //commandPlayer();   
-                                                               
+        //logicPin = 0; 
+        //ledchain[0] = 0;    
+        wait_us(10);                                            
     }// main while end           
 }// main end
 
-#endif //COMPILE_MAIN_CODE_ROSSERIAL
+#endif //COMPILE_MAIN_CODE_TRS_SLAVE