The MBED firmware used on the Chipin sorter, developed over 12 weeks for a 3rd year university systems project. Chipin is a token sorter, it sorts tokens by colours and dispenses them to order through an online booking system and card reader. This program interfaces with an FPGA, PC and LCD screen to control the sorter. The sorter has an operation mode where it can process orders when a card is entered into the machine. There is also a maintenance mode where the device responds to maintenance instructions such as 'dispense all'. More information at http://www.ionsystems.uk/

Dependencies:   MCP23017 TCS3472_I2C WattBob_TextLCD mbed-rtos mbed

Revision:
24:8868101d01d0
Parent:
23:f9e7e64784be
Child:
25:7f5d764d8e34
--- a/FPGAcomms.h	Sat Nov 29 16:32:57 2014 +0000
+++ b/FPGAcomms.h	Wed Dec 03 17:49:41 2014 +0000
@@ -1,13 +1,14 @@
 #include "mbed.h"
-//#include "Colour.h"
 #include "colourProcessing.h"
-
+////////////////////////////
+//  START OF I/O DEFINITIONS
+////////////////////////////
 //Setup pins to FPGA
 DigitalOut startSort(p5);       //A positive edge tells the FPGA to start sorting.
-DigitalIn sortComplete(p16);
+DigitalIn sortComplete(p16);    //FPGA sets to 1 once complete until another signal is recieved.
 /*
-  The command codes for the three sort select bits(ColourBit1 - ColourBit2)
-  See datasheet for furter information
+  The command codes for the three sort select bits(ColourBit1,ColourBit2,ColourBit3)
+  See datasheet for furter information.
     000     Sort red chip
     001     Sort green chip
     010     Sort blue chip
@@ -21,7 +22,7 @@
 DigitalOut colourBit1(p6);      //The 3 bits below are select bits for the sorter.
 DigitalOut colourBit2(p7);
 DigitalOut colourBit3(p8);
-DigitalOut startDispense(p18);   //A positive edge tells the FPGA to start dispensing. p9
+DigitalOut startDispense(p18);   //A positive edge tells the FPGA to start dispensing.
 /*
     00      Dispense red chip
     01      Dispense green chip
@@ -29,13 +30,19 @@
     11      Nothing
 */
 
-DigitalOut dispenseBit1(p19);  //The 2 bits below are select bits for the dispenser.p10
-DigitalOut dispenseBit2(p20); //p11
+DigitalOut dispenseBit1(p19);  //The 2 bits below are select bits for the dispenser.
+DigitalOut dispenseBit2(p20); 
 
 DigitalIn dispenseComplete(p11);    //FPGA sets to 1 once complete until another signal is recieved.
 DigitalOut select(p15); //0 for control, 1 for maintenance.
 
+////////////////////////////
+//  END OF I/O DEFINITIONS
+////////////////////////////
 
+/*  Set the select lines for when the FPGA is in maintenance mode.
+ *  The same pins have different functions in operation mode and maintenance mode on the FPGA.
+*/
 void setMaintenanceSelect(bool bit6, bool bit5, bool bit4, bool bit3, bool bit2, bool bit1)
 {
     startSort = bit1;
@@ -46,10 +53,13 @@
     dispenseBit1 = bit6;
 }
 
+//Set the maintenance start bit.
 void setMaintenanceStart(bool value)
 {
     dispenseBit2 = value;
 }
+
+//Wait for the FPGA to complete a maintenance operation and return a complete signal.
 void waitForMaintenanceComplete()
 {
     while(!sortComplete) {
@@ -58,12 +68,14 @@
    
 }
 
+//Set the select lines for a dispense operation for when the FPGA is in operation mode.
 void setDispenseSelect(bool dBit1, bool dBit2)
 {
     dispenseBit1 = dBit1;
     dispenseBit2 = dBit2;
 }
 
+//Set the select lines for a sorting operation for when the FPGA is in operation mode.
 void setSortSelect(bool sBit1, bool sBit2, bool sBit3)
 {
     colourBit1 = sBit1;
@@ -71,11 +83,20 @@
     colourBit3 = sBit3;
 }
 
+/*  maintain(StateMachine statemachine)
+ *  Carries out a maintenance operation depending on the value of the StateMachine input parameter.
+ */
 void maintain(StateMachine maintainState)
 {
     select = 1; //setting FPGA to maintenance mode.
+    
+    /*  Reset select pins to ensure FPGA carries out one operation.
+     *  The FPGA triggers whenever the select lines change.
+     *  Setting all bits high ensure a 'do nothing' state on the FPGA,
+     *  so it won't do anything.
+     */ 
     setMaintenanceSelect(true,true,true,true,true,true);
-    switch(maintainState) {
+    switch(maintainState) { //Set the maintenanc select values depending on value of maintainState. 
         case RB_LEFT:
             setMaintenanceSelect(false,false,false,true,false,true);
             break;
@@ -121,67 +142,80 @@
         default:
             break;
     }
-    setMaintenanceStart(true);
-    waitForMaintenanceComplete();
-    setMaintenanceStart(false);
-    setMaintenanceSelect(true,false,true,true,true,false);
+    setMaintenanceStart(true);      //Tell the FPGA to start the maintenance operation
+    waitForMaintenanceComplete();   //Wait for the FPGA to complete the maintenance operation.
+    setMaintenanceStart(false);     //Set the start bit low.
+    setMaintenanceSelect(true,false,true,true,true,false); //Set select bits back to 'do nothing' state.
 }
 
+//Wait for the FPGA to complete a dispense operation and send a complete signal.
 void waitForDispenseComplete()
 {
     while(!dispenseComplete) {
-        
     }
     
 }
 
+/*  dispense(Colour colour)
+ *  Carries out a dispense operation for the colour defined by 'colour' which is a Colour.
+ */
 void dispense(Colour colour)
 {
-    startDispense = false;    
-    bool validDispense = false;
-    select = 0;
-    setDispenseSelect(true,true);
+    startDispense = false;      //Set start dispense to false, it should be false already.
+    bool validDispense = false; //Set up a boolean to record whether the dispense is valid or not.
+    select = 0;                    //Set the FPGA to operation mode.
+    setDispenseSelect(true,true);   //Set the dispense selcect bits to 'no nothing' state.
     // A dispense operation can only take place if there are chips
    
-    switch(colour) {
+    switch(colour) {    //Carry out a dispense operation for the colour defined by 'colour'.
         case RED:
-            if(redAmount > 0 || operationMode == false) {
-                setDispenseSelect(false,false);
-                redAmount--;
-                validDispense = true;
+            
+            if(redAmount > 0 || operationMode == false) {           //Ensure dispense is valid
+                setDispenseSelect(false,false);                     //Set select lines for RED dispense
+                if(operationMode)redAmount--;                       //Decrement tube amount if in operation mode
+                validDispense = true;                               
             }
             break;
         case GREEN:
-            if(greenAmount > 0 || operationMode == false) {
-                setDispenseSelect(true,false);
-                greenAmount--;
+            if(greenAmount > 0 || operationMode == false) {         //Ensure dispense is valid
+                setDispenseSelect(true,false);                      //Set select lines for GREEN dispense
+                if(operationMode)greenAmount--;                     //Decrement tube amount if in operation mode
                 validDispense = true;
             }
             break;
         case BLUE:
-            if(blueAmount > 0 || operationMode == false) {
-                setDispenseSelect(false,true);
-                blueAmount--;
+            if(blueAmount > 0 || operationMode == false) {          //Ensure dispense is valid
+                setDispenseSelect(false,true);                      //Set select lines for BLUE dispense
+                if(operationMode)blueAmount--;                      //Decrement tube amount if in operation mode
                 validDispense = true;
             }
             break;
     }
     
-    writeFile(redAmount,greenAmount,blueAmount,recycleAmount);
-    if(validDispense || operationMode == false) {
+    if(operationMode)writeFile(redAmount,greenAmount,blueAmount,recycleAmount); //Store new tube values if in operation mode.
+    /*  If this is a valid dispense (enough chips in storage tubes) then
+     *  set the start bit, wait for complete signal, then reset start bit,
+     *  and select lines.
+     */
+    if(validDispense || operationMode == false) {   
         startDispense = true; //set the startDispense line high.
-        waitForDispenseComplete();
-        
+        waitForDispenseComplete();       
         startDispense = false;
         setDispenseSelect(true,true);
     }
 }
+
+/*  
+ *  
+ */ 
 void dispenseOrder(int r, int g, int b)
 {
 //TODO: Check if there are enough chips of each colour to dispense the order.
-    operationMode = false;
-    for(int i = r; i > 0; i--) {
+    //operationMode = false;
+    for(int i = r; i > 0; i--) {        
         dispense(RED);
+        wait(0.2);
+        Thread::wait(200);
     }
     for(int i = g; i > 0; i--) {
         dispense(GREEN);
@@ -189,7 +223,7 @@
     for(int i = b; i > 0; i--) {
         dispense(BLUE);
     }
-    operationMode = true;
+    //operationMode = true;
 }
 
 void waitForSortComplete()
@@ -212,18 +246,21 @@
 
 void recycle()
 {
+    if(redAmount >= tubeSize && greenAmount >= tubeSize && blueAmount >= tubeSize && operationMode){
+        return;
+        }
     select = 0; //Setting to operation mode just in case it has not been set.
     setSortSelect(true,true,true);
     setSortSelect(false,false,true);
-    recycleAmount++;
+    if(operationMode)recycleAmount++;
     startSort = true; //set the startDispense line high.
     waitForSortComplete();
     startSort = false;
     setSortSelect(true,true,true);
     if(recycleAmount >= 5) {
-        wait(1);
+        Thread::wait(1000);
         lift();
-        wait(1);
+        Thread::wait(1000);
         recycleAmount = 0;
     }
 }
@@ -239,29 +276,29 @@
         select = 0; //Setting to operation mode just in case it has not been set.
         setSortSelect(true,true,true);
         switch(colour) {
-            case RED:
-                if(redAmount >= tubeSize) {
+            case RED:                
+                if(redAmount >= tubeSize && operationMode) {
                     recycle();
                     return;
                 }
                 setSortSelect(false,false,false);
-                redAmount++;
+                if(operationMode) redAmount++;
                 break;
             case GREEN:
-                if(greenAmount >= tubeSize) {
+                if(greenAmount >= tubeSize && operationMode) {
                     recycle();
                     return;
                 }
                 setSortSelect(true,false,false);
-                greenAmount++;
+                if(operationMode) greenAmount++;
                 break;
             case BLUE:
-                if(blueAmount >= tubeSize) {
+                if(blueAmount >= tubeSize && operationMode) {
                     recycle();
                     return;
                 }
                 setSortSelect(false,true,false);
-                blueAmount++;
+                if(operationMode) blueAmount++;
                 break;
             case BIN:
                 setSortSelect(true,true,false);
@@ -271,8 +308,8 @@
         waitForSortComplete();
         startSort = false;
         setSortSelect(true,true,true);
-        writeFile(redAmount,greenAmount,blueAmount,recycleAmount);
-        wait(0.3);
+        if(operationMode) writeFile(redAmount,greenAmount,blueAmount,recycleAmount);
+       
     }
 }
 
@@ -281,6 +318,6 @@
 void dispenseAll()
 {
     dispenseOrder(redAmount,greenAmount,blueAmount);
-    redAmount=0; blueAmount=0; greenAmount=0;
+    redAmount = 0; greenAmount = 0; blueAmount = 0;
     writeFile(redAmount,greenAmount,blueAmount,recycleAmount);
 }
\ No newline at end of file