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

Dependencies:   mbed

Revision:
0:18d7499b82f3
Child:
1:b430b4401fc4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Feb 27 14:53:45 2013 +0000
@@ -0,0 +1,602 @@
+#define COMPILE_MAIN_CODE_ROSSERIAL
+#ifdef  COMPILE_MAIN_CODE_ROSSERIAL
+
+//include files
+#include "include/eposCmd.h"
+
+//SPI RxTx FIFO bits
+#define TNF 0x02
+#define TFE 0x01
+#define RNE 0x04
+
+SPISlave device(p5, p6, p7, p8); // mosi, miso, sclk, ssel
+DigitalOut myled(LED1);
+DigitalIn sync_master(p25);
+
+//trs_mbed::MotorCommand motorCmdBuffer[CMD_BUFFER_SIZE];
+
+DigitalOut logicPin(p26); //to record with Logic analyser on an event, pin high.
+Timer timer;
+
+
+uint8_t writeBufferSPI[NUMBER_MSG_PER_PACKET][NUMBER_BYTES_PER_MSG];
+uint8_t readBufferSPI[NUMBER_MSG_PER_PACKET][NUMBER_BYTES_PER_MSG];
+
+int counter = 0;
+
+//5 variables for median poti position
+//int16_t potiVal[NB_SAMPLES_MEDIAN];
+//int16_t sortVal[NB_SAMPLES_MEDIAN];
+
+int16_t forceVal[NB_SAMPLES_MEDIAN];
+int16_t sortForceVal[NB_SAMPLES_MEDIAN];
+//int16_t lastForceVal[NUMBER_EPOS2_BOARDS][NB_SAMPLES_MEDIAN];
+
+/*
+int16_t getMedianPotiVal(const int8_t nodeID) 
+{        
+    //read poti
+    for(int m=0; m<NB_SAMPLES_MEDIAN; m++)
+    {
+        getPotiPosition(nodeID);
+        wait_us(1000);
+        
+        potiVal[m] = potiPosArray[nodeID - 1];        
+        sortVal[m] = potiVal[m];
+
+        wait_us(100);
+    }
+    
+    //sort values
+    for(int m=1; m<NB_SAMPLES_MEDIAN; ++m)
+    {
+        int16_t n;
+        n = sortVal[m];
+        int p;
+
+        for(p = m-1; (p >=0) && (n<sortVal[p]); p--)
+        {
+            sortVal[p+1] = sortVal[p];
+        }
+        sortVal[p+1] = n;
+    }
+       
+    return sortVal[2];
+}
+*/
+
+int16_t getMedianForceVal(const int8_t nodeID) 
+{         
+    logicPin = 1;
+    
+    for(int m=0; m<NB_SAMPLES_MEDIAN; m++)
+    {          
+        sortForceVal[m] = getForce(nodeID);
+        wait_us(100); //adjust this
+    }
+    
+    //sort values
+    for(int m=1; m<NB_SAMPLES_MEDIAN; ++m)
+    {
+        int16_t n = sortForceVal[m];
+        int p;
+
+        for(p = m-1; (p >=0) && (n<sortForceVal[p]); p--)
+        {
+            sortForceVal[p+1] = sortForceVal[p];
+        }
+        sortForceVal[p+1] = n;
+    }
+    
+    logicPin = 0;
+       
+    return sortForceVal[2];
+}
+
+/*** INTERRUPT (for catching Emergency error frames) ***/
+void interrupt() 
+{
+    CANMessage canmsg;
+    int64_t data = 0x0000000000000000;     
+    int8_t nodeID = 0;
+    int16_t cobID = 0;
+        
+    //read the can message that has triggered the interrupt
+    cantoepos.read(canmsg);   
+    
+    //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]);
+
+    nodeID = 0x00F & canmsg.id;
+    cobID = 0x0FF0 & canmsg.id;
+
+    for(int i=0; i<=canmsg.len; i++)
+    {
+        data = data | (canmsg.data[i]<<i*8);        
+    }
+    
+    //check nodeID first
+    if((nodeID >= 0) && (nodeID <= NUMBER_EPOS2_BOARDS))
+    {        
+        switch(cobID)
+        {       
+            case COB_ID_TRANSMIT_PDO_1_ENABLE : //getPosition
+                //pc.printf("getPosition Node ID : [%d], PDO COB-ID [%02X], data = %d\n", nodeID, cobID, data);
+                encPosition[nodeID - 1] = data;
+                break;
+                
+            case COB_ID_TRANSMIT_PDO_2_ENABLE : //getCurrent averaged
+                //pc.printf("getCurrent Node ID : [%d], PDO COB-ID [%02X], data = %d\n", nodeID, cobID, data);
+                avgCurrent[nodeID - 1] = data;
+                break;
+                
+            case COB_ID_TRANSMIT_PDO_3_ENABLE : //getVelocity
+                //pc.printf("getVelocity Node ID : [%d], PDO COB-ID [%02X], data = %d\n", nodeID, cobID, data);
+                velocity[nodeID - 1] = data;
+                break;
+                
+            case COB_ID_TRANSMIT_PDO_4_ENABLE : //getPotiPosition
+                //pc.printf("getPotiPosition Node ID : [%d], PDO COB-ID [%02X], data = %d\n", nodeID, cobID, data);
+                potiPosArray[nodeID - 1] = data;
+                break; 
+             
+            case COB_ID_EMCY_DEFAULT : //Emergency frame
+                //pc.printf("Emergency frame, Node ID : [%d], PDO COB-ID [%02X], data = %02X\n", nodeID, cobID, data);
+                //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]);
+                pc.printf("EF%02X-%02X%02X\n\r", canmsg.id, canmsg.data[1], canmsg.data[0]);
+                ledchain[1] = 1;            
+                //nh.logerror("Emergency frame");
+                boardStatus[nodeID-1] = 1;                
+                //first step : fault reset on controlword
+                //pc.printf("Node %d - STEP 1 - faultResetControlword\n", nodeID);
+                faultResetControlword(nodeID);                 
+                break;  
+                
+            case COB_ID_SDO_SERVER_TO_CLIENT_DEFAULT : //SDO Acknoledgement frame
+                int32_t regData = 0x00000000;
+                regData = (int32_t)data;
+                
+                //pc.printf("Node %d - regData [%02X]\n", nodeID, regData);
+                                
+                if(regData == 0x00604060) //Controlword
+                {
+                    if(boardStatus[nodeID-1] == 1)
+                    {
+                        boardStatus[nodeID-1] = 2;                      
+                        //second step : shutdown controlword
+                        //pc.printf("Node %d - STEP 2 - shutdownControlwordIT\n", nodeID);
+                        shutdownControlwordIT(nodeID);
+                    }
+                    else if(boardStatus[nodeID-1] == 2)
+                    {
+                        boardStatus[nodeID-1] = 3;                      
+                        //third step : Switch On & Enable Operation on Controlword
+                        //pc.printf("Node %d - STEP 3 - switchOnEnableOperationControlwordIT\n", nodeID);
+                        switchOnEnableOperationControlwordIT(nodeID);
+                    }
+                    else if(boardStatus[nodeID-1] == 3)
+                    {
+                        boardStatus[nodeID-1] = 4;
+                        //ask for statusword to check if the board has reset well
+                        //pc.printf("Node %d - STEP 4 - getStatusword\n", nodeID);
+                        getStatusword(nodeID);
+                    }
+                } 
+                else if(regData == 0x0060414B) //read Statusword
+                {
+                    int32_t swData = 0x00000000;
+                    
+                    //pc.printf("Node %d - Statusword [%02X]\n", nodeID, canmsg.data[4]);
+                    //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]);
+                    
+                    if(boardStatus[nodeID-1] == 4)
+                    {
+                        //swData = data >> 32;
+                        int8_t fault = 0x00;
+                        fault = (canmsg.data[4] & 0x08) >> 3;
+                                               
+                        if(fault == 0) //reset OK
+                        {
+                            boardStatus[nodeID-1] = 0; //Board is reset and enable OK
+                            pc.printf("%d OK\n\r", nodeID);
+                            ledchain[1] = 0;
+                        }
+                        else //try to reset again
+                        {
+                            //pc.printf("Node %d - try to reset again\n", nodeID);
+                            boardStatus[nodeID-1] = 1;                
+                            //go back to first step : fault reset on controlword
+                            //pc.printf("Node %d - STEP 1 - faultResetControlword\n", nodeID);
+                            faultResetControlword(nodeID);                        
+                        }
+                    }  
+                }                                            
+                break;  
+                           
+            default :
+                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]);                            
+        } //end switch
+    }
+    else
+    {
+        pc.printf("NODEID ERROR\n\r");    
+    }
+} //end interrupt
+
+void commandPlayer() //called in main every 20ms
+{/*
+    for(int i= 0; i<CMD_BUFFER_SIZE; i++)
+    {        
+        if(motorCmdBuffer[i].beatDelay != -1) 
+        {       
+            switch (motorCmdBuffer[i].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);                    
+                    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);
+                    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);
+                    break;
+                default:
+                    break;
+            }
+            
+            //decrement only cmd with delay != -1, so cmd that has not been played yet.
+            motorCmdBuffer[i].beatDelay = motorCmdBuffer[i].beatDelay - 1;
+        }
+    }*/
+}
+
+void initBufferSPI()
+{
+    //init the SPI arrays
+    for(int i=0; i<NUMBER_MSG_PER_PACKET; i++)
+    { 
+        for(int j=0; j<NUMBER_BYTES_PER_MSG; j++)
+        {             
+            //writeBufferSPI[i][j] = 0x00;
+            readBufferSPI[i][j] = 0x00;            
+        }
+    }
+    
+    for(int n=0; n<NUMBER_MSG_PER_PACKET; n++)
+    {
+        writeBufferSPI[n][0] = n+1; //CANnodeID
+        writeBufferSPI[n][1] = 2; //mode of command
+        
+        writeBufferSPI[n][2] = 0xA0+n; 
+        writeBufferSPI[n][3] = 0xB0+n; 
+        writeBufferSPI[n][4] = 0xC0+n; 
+        writeBufferSPI[n][5] = 0xD0+n;         
+        writeBufferSPI[n][6] = 0xE0+n;      
+    }
+}
+
+int main() 
+{          
+    pc.baud(115200); //115200 //57600
+    pc.printf("*** Start Slave Main ***\n\r");
+    
+    logicPin = 0;
+    timer.start();
+    uint64_t begin = 0;
+    uint64_t end = 0;
+    int64_t pauseTime = 0;
+    //int8_t node = 0; //test 
+    
+    initBufferSPI();
+    //sync_master = 0;
+    char rByte = 0x00;
+    
+    char threeArrows = 0;
+    char closeArrowChar = 0x62; //>
+    bool startReceiving = false;
+    bool threeArrowsFound = false;
+    bool slaveSelected = false;
+    
+    int i = 0; //msg
+    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); 
+    } 
+        
+    ledchain[0] = 1;   
+    
+    pc.printf("--- Enable Interrupts ---\n\r"); 
+    //attach the interrupt function
+    cantoepos.attach(&interrupt);
+    __enable_irq();
+    
+    device.reply(0x62); //Prime SPI with first reply
+    
+ /*                   
+    pc.printf("--- Get poti positions for calibration...");
+    //set the nodeID and potiPosition field of motorDataSet_msg          
+    for(int i=0; i<NUMBER_EPOS2_BOARDS; i++)
+    {
+        uint8_t node_id = i+1;
+        if(node_id!=5)
+        {                                       
+            motorDataSet_msg.motorData[i].encPosition = 0;
+            motorDataSet_msg.motorData[i].potiPosition = getMedianPotiVal(node_id);
+            motorDataSet_msg.motorData[i].current = 0 ;   
+            motorDataSet_msg.motorData[i].force = -1; 
+        }
+        else
+        {
+            motorDataSet_msg.motorData[i].encPosition = 0;
+            motorDataSet_msg.motorData[i].potiPosition = 9999;
+            motorDataSet_msg.motorData[i].current = 0 ;   
+            motorDataSet_msg.motorData[i].force = -1; 
+        }
+    }
+    
+    pc.printf("...OK\n\r");
+*/
+
+    //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);                                           
+        }            
+    }
+      
+    //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]; 
+        }           
+    }
+    
+    
+    
+    //then start the main loop
+    pc.printf("--- Start main loop ---\n\r"); 
+    
+    //setModeOfOperationPDO(1, VALUE_CURRENT_MODE);
+    //setCurrent(1, 150);
+    
+    uint8_t my_val;
+              
+    while(1) 
+    {         
+        //begin = timer.read_us();
+        //logicPin = 1;     
+        
+        //pc.printf("1\n\r");           
+             
+        
+        
+        //wait, the master will put the pin high at some point, for 10us
+        while(sync_master == 0)
+        {
+            wait_us(1);  
+        }
+        
+        slaveSelected = true;
+        
+        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
+        
+        //reset for a new message
+        i = 0;
+        j = 0;
+        threeArrows = 0;
+        threeArrowsFound = false;
+        
+        logicPin = 1;
+        
+        //pc.printf("START - ");
+        
+        __disable_irq();
+        
+        while(slaveSelected)
+        {
+            //SPI polling
+            if(device.receive()) 
+            {/*
+                //pc.printf("startReceiving = true\n\r");
+                startReceiving = true;
+                //logicPin = 1;
+                rByte = device.read(); 
+                //pc.printf("0x%02X ", rByte);
+                //logicPin = 0;
+                
+                if(rByte == 0x60) 
+                {   
+                    threeArrows++;  
+                    //pc.printf("3Arrows++ before while\n\r");
+                }
+                
+                device.reply(0x00);
+                wait_us(1);
+                            
+                while(startReceiving) 
+                {
+                    //pc.printf("2\n"); 
+                    if(device.receive()) 
+                    {*/
+                        //logicPin = 1;   
+                        rByte = device.read();   // Read byte from master
+                        //pc.printf("0x%02X ", rByte);
+                        //wait_ms(100);
+                        //logicPin = 0;
+                        
+                        if(threeArrows < 3)
+                        {
+                            if(rByte == 0x60) 
+                            {   
+                                threeArrows++;  
+                                //pc.printf("3A++\n\r");
+                            }
+                            else 
+                            {
+                                //threeArrows = 0; 
+                                //startReceiving = false;   
+                                //pc.printf("error3A\n");  
+                                //slaveSelected = false; 
+                            }
+                            
+                            if(threeArrows == 3) 
+                            {
+                                device.reply(writeBufferSPI[i][j]);
+                                threeArrowsFound = true;
+                            }
+                            else
+                            {
+                                device.reply(0x62); //close arrow : >
+                            }
+                            
+                            //pc.printf("3Arrows %d \n", threeArrows);
+                            //if(threeArrows == 3) threeArrowsFound = true;       
+                        }
+                        else
+                        {/*
+                            if(threeArrowsFound) //to reset i and j when receiving a new message
+                            {
+                                //pc.printf("3AFound\n\r");
+                                i = 0;
+                                j = 0;
+                                threeArrowsFound = false;
+                            }*/
+                            
+                            //logicPin = 1;
+                            readBufferSPI[i][j] = rByte;
+                            //pc.printf("i=%d j=%d\n", i,j);
+                            //logicPin = 0;
+                                            
+                            j++; //write next byte next time
+                             
+                            if(j >= NUMBER_BYTES_PER_MSG)
+                            {
+                                j = 0;
+                                i++; //next node 
+                                
+                                if(i >= NUMBER_MSG_PER_PACKET)
+                                {
+                                    //pc.printf("\n\r");
+                                    //pc.printf("final i=%d j=%d\n\r", i,j);
+                                    //finished reading the array                        
+                                    /*
+                                    for(int n=0; n<1; n++)
+                                    {
+                                        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]);
+                                    }
+                                    
+                                    pc.printf("\n\r");
+                                    */
+                                    
+                                    //reset
+                                    threeArrows = 0;
+                                    i = 0;
+                                    j = 0;
+                                    //startReceiving = false;
+                                    //mbedID_ok = false;
+                                    slaveSelected = false; //to end the while loop
+                                }             
+                            } 
+                                      
+                            device.reply(writeBufferSPI[i][j]);     
+                        }
+                        
+                        //logicPin = 0;    
+                    //}//if
+                    
+                    //wait_us(1);
+                //}//while startReceiving                 
+            }//if
+            
+            wait_us(1);
+        }//while slaveSelected
+                    
+        __enable_irq();
+        
+        //pc.printf(" - END\n\r");
+        logicPin = 0; 
+        wait_us(10);
+        logicPin = 1;
+        
+        //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);                                           
+            }            
+        }
+          
+        //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; 
+            
+        wait_us(1);
+        
+    /*       
+        //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;
+    /*    
+        //pc.printf("before end\n\r");
+        end = timer.read_us();         
+        pc.printf("end=%d\n", end);
+        pauseTime = LOOP_PERIOD_TIME - end + begin - 12; //12us is the time to compute those 2 lines
+        //pc.printf("pauseTime=%d\n", pauseTime);
+        pc.printf("begin = %d - pause = %d, end = %d\n", begin, pauseTime, end);
+        pc.printf("pauseTime=%d\n", pauseTime);
+        if(pauseTime > 0) wait_us(pauseTime);
+      */  
+        //pc.printf("after end\n\r");                                                       
+    }// main while end           
+}// main end
+
+#endif //COMPILE_MAIN_CODE_ROSSERIAL