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
FPGAcomms.h
00001 #include "mbed.h" 00002 #include "colourProcessing.h" 00003 //////////////////////////// 00004 // START OF I/O DEFINITIONS 00005 //////////////////////////// 00006 //Setup pins to FPGA 00007 DigitalOut startSort(p5); //A positive edge tells the FPGA to start sorting. 00008 DigitalIn sortComplete(p16); //FPGA sets to 1 once complete until another signal is recieved. 00009 /* 00010 The command codes for the three sort select bits(ColourBit1,ColourBit2,ColourBit3) 00011 See datasheet for furter information. 00012 000 Sort red chip 00013 001 Sort green chip 00014 010 Sort blue chip 00015 011 Bin the chip 00016 100 Recycle the chip 00017 101 Nothing 00018 110 Nothing 00019 111 Nothing 00020 */ 00021 00022 DigitalOut colourBit1(p6); //The 3 bits below are select bits for the sorter. 00023 DigitalOut colourBit2(p7); 00024 DigitalOut colourBit3(p8); 00025 DigitalOut startDispense(p18); //A positive edge tells the FPGA to start dispensing. 00026 /* 00027 00 Dispense red chip 00028 01 Dispense green chip 00029 10 Dispense blue chip 00030 11 Nothing 00031 */ 00032 00033 DigitalOut dispenseBit1(p19); //The 2 bits below are select bits for the dispenser. 00034 DigitalOut dispenseBit2(p20); 00035 00036 DigitalIn dispenseComplete(p11); //FPGA sets to 1 once complete until another signal is recieved. 00037 DigitalOut select(p15); //0 for control, 1 for maintenance. 00038 00039 //////////////////////////// 00040 // END OF I/O DEFINITIONS 00041 //////////////////////////// 00042 00043 /* Set the select lines for when the FPGA is in maintenance mode. 00044 * The same pins have different functions in operation mode and maintenance mode on the FPGA. 00045 */ 00046 void setMaintenanceSelect(bool bit6, bool bit5, bool bit4, bool bit3, bool bit2, bool bit1) 00047 { 00048 startSort = bit1; 00049 colourBit1 = bit2; 00050 colourBit2 = bit3; 00051 colourBit3 = bit4; 00052 startDispense = bit5; 00053 dispenseBit1 = bit6; 00054 } 00055 00056 //Set the maintenance start bit. 00057 void setMaintenanceStart(bool value) 00058 { 00059 dispenseBit2 = value; 00060 } 00061 00062 //Wait for the FPGA to complete a maintenance operation and return a complete signal. 00063 void waitForMaintenanceComplete() 00064 { 00065 while(!sortComplete) { 00066 00067 } 00068 00069 } 00070 00071 //Set the select lines for a dispense operation for when the FPGA is in operation mode. 00072 void setDispenseSelect(bool dBit1, bool dBit2) 00073 { 00074 dispenseBit1 = dBit1; 00075 dispenseBit2 = dBit2; 00076 } 00077 00078 //Set the select lines for a sorting operation for when the FPGA is in operation mode. 00079 void setSortSelect(bool sBit1, bool sBit2, bool sBit3) 00080 { 00081 colourBit1 = sBit1; 00082 colourBit2 = sBit2; 00083 colourBit3 = sBit3; 00084 } 00085 00086 /* maintain(StateMachine statemachine) 00087 * Carries out a maintenance operation depending on the value of the StateMachine input parameter. 00088 */ 00089 void maintain(StateMachine maintainState) 00090 { 00091 select = 1; //setting FPGA to maintenance mode. 00092 00093 /* Reset select pins to ensure FPGA carries out one operation. 00094 * The FPGA triggers whenever the select lines change. 00095 * Setting all bits high ensure a 'do nothing' state on the FPGA, 00096 * so it won't do anything. 00097 */ 00098 setMaintenanceSelect(true,true,true,true,true,true); 00099 switch(maintainState) { //Set the maintenanc select values depending on value of maintainState. 00100 case RB_LEFT: 00101 setMaintenanceSelect(false,false,false,true,false,true); 00102 break; 00103 case RB_CENTRE: 00104 setMaintenanceSelect(false,false,false,true,true,false); 00105 break; 00106 case RB_RIGHT: 00107 setMaintenanceSelect(false,false,false,true,true,true); 00108 break; 00109 case GO_UP: 00110 setMaintenanceSelect(false,false,true,false,false,false); 00111 break; 00112 case GO_CENTRE: 00113 setMaintenanceSelect(false,false,true,false,false,true); 00114 break; 00115 case GO_DOWN: 00116 setMaintenanceSelect(false,false,true,false,true,false); 00117 break; 00118 case BR_LEFT: 00119 setMaintenanceSelect(false,false,true,false,true,true); 00120 break; 00121 case BR_RIGHT: 00122 setMaintenanceSelect(false,false,true,true,false,false); 00123 break; 00124 case R_PUSH: 00125 setMaintenanceSelect(false,false,true,true,false,true); 00126 break; 00127 case R_HOME: 00128 setMaintenanceSelect(false,false,true,true,true,false); 00129 break; 00130 case GB_LEFT: 00131 setMaintenanceSelect(false,false,true,true,true,true); 00132 break; 00133 case GB_CENTRE: 00134 setMaintenanceSelect(false,true,false,false,false,false); 00135 break; 00136 case GB_RIGHT: 00137 setMaintenanceSelect(false,true,false,false,false,true); 00138 break; 00139 case maintenanceEND: 00140 setMaintenanceSelect(false,true,false,false,true,false); 00141 break; 00142 default: 00143 break; 00144 } 00145 setMaintenanceStart(true); //Tell the FPGA to start the maintenance operation 00146 waitForMaintenanceComplete(); //Wait for the FPGA to complete the maintenance operation. 00147 setMaintenanceStart(false); //Set the start bit low. 00148 setMaintenanceSelect(true,false,true,true,true,false); //Set select bits back to 'do nothing' state. 00149 } 00150 00151 //Wait for the FPGA to complete a dispense operation and send a complete signal. 00152 void waitForDispenseComplete() 00153 { 00154 while(!dispenseComplete) { 00155 } 00156 } 00157 00158 /* dispense(Colour colour) 00159 * Carries out a dispense operation for the colour defined by 'colour' which is a Colour. 00160 */ 00161 void dispense(Colour colour) 00162 { 00163 startDispense = false; //Set start dispense to false, it should be false already. 00164 bool validDispense = false; //Set up a boolean to record whether the dispense is valid or not. 00165 select = 0; //Set the FPGA to operation mode. 00166 setDispenseSelect(true,true); //Set the dispense selcect bits to 'no nothing' state. 00167 // A dispense operation can only take place if there are chips 00168 00169 switch(colour) { //Carry out a dispense operation for the colour defined by 'colour'. 00170 case RED: 00171 00172 if(redAmount > 0 || operationMode == false) { //Ensure dispense is valid 00173 setDispenseSelect(false,false); //Set select lines for RED dispense 00174 if(operationMode)redAmount--; //Decrement tube amount if in operation mode 00175 validDispense = true; 00176 } 00177 break; 00178 case GREEN: 00179 if(greenAmount > 0 || operationMode == false) { //Ensure dispense is valid 00180 setDispenseSelect(true,false); //Set select lines for GREEN dispense 00181 if(operationMode)greenAmount--; //Decrement tube amount if in operation mode 00182 validDispense = true; 00183 } 00184 break; 00185 case BLUE: 00186 if(blueAmount > 0 || operationMode == false) { //Ensure dispense is valid 00187 setDispenseSelect(false,true); //Set select lines for BLUE dispense 00188 if(operationMode)blueAmount--; //Decrement tube amount if in operation mode 00189 validDispense = true; 00190 } 00191 break; 00192 } 00193 00194 if(operationMode)writeFile(redAmount,greenAmount,blueAmount,recycleAmount); //Store new tube values if in operation mode. 00195 /* If this is a valid dispense (enough chips in storage tubes) then 00196 * set the start bit, wait for complete signal, then reset start bit, 00197 * and select lines. 00198 */ 00199 if(validDispense || operationMode == false) { 00200 startDispense = true; //set the startDispense line high. 00201 waitForDispenseComplete(); 00202 startDispense = false; 00203 setDispenseSelect(true,true); 00204 } 00205 } 00206 00207 /* dispenseOrder(int r, int g, int b) 00208 * Dispenses a certain amount of each coloured chip, 00209 * depending on the three input values (one input for each colour). 00210 */ 00211 void dispenseOrder(int r, int g, int b) 00212 { 00213 for(int i = r; i > 0; i--) { 00214 dispense(RED); 00215 wait(0.2); 00216 Thread::wait(200); 00217 } 00218 for(int i = g; i > 0; i--) { 00219 dispense(GREEN); 00220 } 00221 for(int i = b; i > 0; i--) { 00222 dispense(BLUE); 00223 } 00224 } 00225 //Wait for the FPGA to complete a sort operation and send a complete signal. 00226 void waitForSortComplete() 00227 { 00228 while(!sortComplete) {} 00229 } 00230 /* lift() 00231 * Communicate with the FPGA to carry out a lift operation. 00232 */ 00233 void lift() 00234 { 00235 select = 0; //Setting to operation mode just in case it has not been set. 00236 setSortSelect(true,true,true); //Setting sort select to 'no nothing' state. 00237 setSortSelect(true,false,true); //Setting sort select to 'lift' state. 00238 startSort = true; //Tell the FPGA to start the lift operation 00239 waitForSortComplete(); //Wait for the FPGA to complete the lift operation 00240 startSort = false; //Turn off startSort 00241 setSortSelect(true,true,true); //Return sort select to 'no nothing' state. 00242 } 00243 00244 00245 /* recycle() 00246 * Communicate with the FPGA to carry out a recycle operation. 00247 */ 00248 void recycle() 00249 { 00250 if(redAmount >= tubeSize && greenAmount >= tubeSize && blueAmount >= tubeSize && operationMode){ 00251 return; 00252 } 00253 select = 0; //Setting to operation mode just in case it has not been set. 00254 setSortSelect(true,true,true); //Setting sort select to 'no nothing' state. 00255 setSortSelect(false,false,true); //Setting sort select to 'recycle' state. 00256 if(operationMode)recycleAmount++; //Increment the amount of chips in the lift, if we are in operation mode. 00257 startSort = true; //Tell the FPGA to start the recycle operation. 00258 waitForSortComplete(); //Wait for the FPGA to complete the recycle operation 00259 startSort = false; //Turn off startSort. 00260 setSortSelect(true,true,true); //Return sort select to 'no nothing' state. 00261 if(recycleAmount >= 5) { //Check whether the lift is full. 00262 Thread::wait(1000); //Carry out a lift operation if the recycle tube is full. 00263 lift(); 00264 Thread::wait(1000); 00265 recycleAmount = 0; 00266 } 00267 } 00268 00269 00270 /* sort(Colour colour) 00271 * Sort a token into a storage tube. The storage tube is selected using the Colour input 'colour'. 00272 */ 00273 void sort(Colour colour) 00274 { 00275 if(colour == NONE) { //Return if no colour is given. 00276 return; 00277 } else { 00278 startSort = false; //just in case it is high for some reason. 00279 select = 0; //Setting to operation mode just in case it has not been set. 00280 setSortSelect(true,true,true); //Set sort select to 'no nothing' state. 00281 switch(colour) { 00282 case RED: 00283 if(redAmount >= tubeSize && operationMode) { //Recycle if red tube full 00284 recycle(); 00285 return; 00286 } 00287 setSortSelect(false,false,false); //Set sort select for red sort 00288 if(operationMode) redAmount++; 00289 break; 00290 case GREEN: 00291 if(greenAmount >= tubeSize && operationMode) { //Recycle if green tube full 00292 recycle(); 00293 return; 00294 } 00295 setSortSelect(true,false,false); //Set sort select for green sort 00296 if(operationMode) greenAmount++; 00297 break; 00298 case BLUE: 00299 if(blueAmount >= tubeSize && operationMode) { //Recycle if blue tube full 00300 recycle(); 00301 return; 00302 } 00303 setSortSelect(false,true,false); //Set sort select for blue sort 00304 if(operationMode) blueAmount++; 00305 break; 00306 case BIN: 00307 setSortSelect(true,true,false); //Set sort select for bin 00308 break; 00309 } 00310 startSort = true; //Tell the FPGA to start the sort 00311 waitForSortComplete(); //Wait for the FPGA to complete sort operation and send complete signal 00312 startSort = false; 00313 setSortSelect(true,true,true); //Return sort select to 'do nothing' state. 00314 //Save tube values to file if in operation mode. 00315 if(operationMode) writeFile(redAmount,greenAmount,blueAmount,recycleAmount); 00316 } 00317 } 00318 00319 00320 /* dispenseAll() 00321 * Dispense all the tokens in the three tubes, according to the stored values. 00322 */ 00323 void dispenseAll() 00324 { 00325 dispenseOrder(redAmount,greenAmount,blueAmount); 00326 redAmount = 0; greenAmount = 0; blueAmount = 0; 00327 writeFile(redAmount,greenAmount,blueAmount,recycleAmount); 00328 }
Generated on Thu Jul 14 2022 19:06:18 by 1.7.2