/** * @file ifs.h * * @date Jul 8, 2019 * @author Shlomo * * @date 26.8.2019 * @author Shai */ #include #include "PMR/Diagnostics/CartridgeSlot.pb-c.h" #include "PMR/Diagnostics/CartridgeTagContent.pb-c.h" #include #include "PMR/IFS/CartridgeState.pb-c.h" #include #include #include "drivers/FPGA/FPGA_GPIO/FPGA_GPIO.h"//#include "FPGA_GPIO.h" // use for FPGA IO #include "drivers/I2C_Communication/ADC_MUX/ADC_MUX.h" #include "StateMachines/Initialization/PowerOffSequence.h" #include #include "include.h" #include "Modules/IDS/ids_ex.h" #include "Modules/IFS/ifs.h" #include "Modules/AlarmHandling/AlarmHandling.h" #include "CartridgeValidationRequest.pb-c.h" #include "CartridgeValidationResponse.pb-c.h" #include "drivers/Valves/Valve.h" #include "../control/control.h" #include "Modules/General/buttons.h" #include "Modules/General/MachineStatus.h" #define CARTRIDGE_EMPTY_QUANTITY_LIMIT 10 #define CARTRIDGE_EMPTY_CALCULATION_TIME 12 #define FIVE_SECONDS 5 //#define IFS_DEBUG int CartridgeInkTimeout = CARTRIDGE_INK_TIMEOUT; int CartridgeCheckTime = FIVE_SECONDS; double midTankCapacity; MidTank_t midTankCartColor; bool prevDoorState; bool doorState; uint8_t inkAuthenticationPass; uint32_t midTankTimeoutCounter = 0; double MidTankEmptyLimit = MidTank_Pressure_EMPTY; MidTankStateEnum midTankState = 0; char CartridgeRequestToken[36+1]; int CartridgeRequestId = 0x31313131; bool RdInkCartridgeSensor() { return Is_Cartridge_Present(CART_1); } bool IFS_CartridgeLowerPresent() { return RdInkCartridgeSensor(); } bool IFS_MidTankFilling(void) { return (midTankTimeoutCounter > 0); } MidTank_t IFS_MidTankIsActive(void) { return midTankCartColor; } uint32_t MidTankReading(void) { if (midTankTimeoutCounter > 0) return ERROR; return OK; } bool MidTankValvesAction(bool action) { bool ret = true; if (action == Cartridge_MidTank_ON) { Enable_MidTank_Pressure_Reading(midTankCartColor); } else { Disable_MidTank_Pressure_Reading(midTankCartColor); } if (IDS_IsHomingActive(midTankCartColor)==false) { Valve_Set(IDS_Id_to_AirValve[midTankCartColor], action); } Valve_Set(IDS_Id_to_CartrideValve[midTankCartColor], action); return ret; } bool DetectIfCartridgeFinished(int int_MidTank_Pressure_1000) { bool ret = false; static int measure_midtank[CARTRIDGE_EMPTY_CALCULATION_TIME] ; static int count_measure_midtank = 0; int i=0; int sum = 0; int average = 0; if (count_measure_midtank == CARTRIDGE_EMPTY_CALCULATION_TIME) count_measure_midtank = 0; measure_midtank[count_measure_midtank] = int_MidTank_Pressure_1000; count_measure_midtank += 1; for (i=0;i= midTankCapacity + CARTRIDGE_CAPATICY) return true; if (CartridgeFinishedCount++>=CartridgeCheckTime ) { CartridgeFinishedCount = 0; Report("IFS_filling ", __FILE__,__LINE__,int_MidTank_Pressure_1000, RpMessage, int_MidTank_Pressure_1000, 0); /**** detect if the MidTank_Pressure is the same, 5 times ****/ if (DetectIfCartridgeFinished(int_MidTank_Pressure_1000)) { //currently sensor work properly only until 1.6 - 1.8 Liter (TBD) Report("DetectIfCartridgeFinished", __FILE__,__LINE__,int_MidTank_Pressure_1000, RpMessage, int_MidTank_Pressure_1000, 0); //return true; } } return false; } #endif int GetCartridgeFillPercent() { double MidTank_Pressure = 0; double percent; #ifdef IFS_DEBUG static int percent = 0; if (midTankState == MidTankStateFilling) { if (percent < 100) { percent += 1; } } else { percent = 0; } return percent; #else MidTank_Pressure = Read_MidTank_Pressure_Sensor(midTankCartColor); percent = (((MidTank_Pressure - midTankCapacity)* 100) / CARTRIDGE_CAPATICY); return percent; #endif } bool midTankCart_door() { bool door; if(Get_COVER_1_State(CartridgesDoor))//to check the polarity { door = OPEN; } else { door = CLOSE; } return door; } uint32_t ReadInkCartridgeData() { //this function triggers reading and validation of the cartridge information // for now it sends a request to the tablet to inquire for the ink color/midtank id MessageContainer responseContainer; CartridgeValidationRequest ValidationReq = CARTRIDGE_VALIDATION_REQUEST__INIT; Cartridge CartridgeData; strcpy(CartridgeRequestToken,"Happy days are coming to us, soonXXX"); memcpy(&CartridgeRequestToken[32],&CartridgeRequestId,sizeof(CartridgeRequestId)); CartridgeRequestId++; cartridge__init(&CartridgeData); CartridgeData.has_slot = true; CartridgeData.slot = CARTRIDGE_SLOT__Ink; CartridgeData.tag = 0; CartridgeData.has_index = false; ValidationReq.has_action = true; ValidationReq.action = CARTRIDGE_ACTION__Inserted; ValidationReq.cartridge = &CartridgeData; responseContainer = createContainer(MESSAGE_TYPE__CartridgeValidationRequest, CartridgeRequestToken, true, &ValidationReq, &cartridge_validation_request__pack, &cartridge_validation_request__get_packed_size); //------------------------------------------------------------------------------------------- uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); ReportWithPackageFilter(WasteFilter,"------------ IFS: send message_container__pack -----------------", __FILE__, __LINE__, CARTRIDGE_ACTION__Inserted, RpMessage, 0, 0); my_free(responseContainer.data.data); SendChars((char*)container_buffer, container_size); return OK; } bool CartridgeValidationResponseFunc(MessageContainer* requestContainer) { bool ret = ERROR; CartridgeValidationResponse* response = cartridge_validation_response__unpack(NULL, requestContainer->data.len, requestContainer->data.data); // check the message: // 1. the pointer is not NULL !!! // 2. the index is out of rang if (response == NULL) { Report("IFS_filling message from PPC is null!!!", __FILE__,__LINE__,0, RpMessage, 0, 0); return ret; } if (response->index < NUM_OF_MIDTANKS) { midTankCartColor = response->index; // midtank 1-8 Report("IFS get message response->index is", __FILE__, __LINE__, response->index, RpMessage, 0, 0); inkAuthenticationPass = true; } else { Report("IFS get message response->index is out of rang", __FILE__, __LINE__, response->index, RpMessage, 0, 0); inkAuthenticationPass = false; } return OK; } void ResponseDemo(int MidtankId) { inkAuthenticationPass = true; midTankCartColor = MidtankId; } void midTankStateMachine(void) { static int init = 1; static int authenticationTimeOutCounter = 0; uint32_t rc; if (init) { doorState = midTankCart_door(); prevDoorState = doorState; init = 0; } else { #ifndef IFS_DEBUG doorState = midTankCart_door(); #endif } if (!RdInkCartridgeSensor()) { // cartridge not presence Pannel_Leds( CART_1, MODE_OFF); cart1.color = colorOFF; } else { // cartridge presence if (cart1.color == colorOFF) { Pannel_Leds( CART_1, MODE_ON); cart1.color = colorON; } } switch (midTankState) { case MidTankStateIdle: if ((doorState == CLOSE) && (prevDoorState == OPEN)) { //check if power down in process if (PowerOffInProcessGetState()) { Report("Power-down in process", __FILE__, __LINE__, 0, RpMessage, 0, 0); break; } // check if cartridge presence if (!RdInkCartridgeSensor()) { break; } //check RFID - check cartridge OK if ((rc = RFID_Get_Identification_Status(READER_1)) != OK) { Report("RFID_Get_Identification_Status failed", __FILE__, __LINE__, rc, RpMessage, 0, 0); break; } // send request for validation to ppc inkAuthenticationPass = 2; //not defined authenticationTimeOutCounter = 0; ReadInkCartridgeData(); //move to next state midTankState = MidTankStateWait; Report("move to midTankStateWait", __FILE__, prevDoorState, doorState, RpMessage, midTankState, 0); } if (doorState != prevDoorState) { prevDoorState = doorState; Report("Door state change", __FILE__, __LINE__, doorState, RpMessage, prevDoorState, 0); } break; case MidTankStateWait: if (inkAuthenticationPass == 2) { authenticationTimeOutCounter++; Report("MidTank Cartridge authentication wait...", __FILE__, __LINE__, authenticationTimeOutCounter, RpMessage, 0, 0); if (authenticationTimeOutCounter > 60) { midTankState = MidTankStateIdle; CartridgeStateUpdate(CARTRIDGE_SLOT__Ink, midTankCartColor, CARTRIDGE_STATE__Error, 0); } break; } if (inkAuthenticationPass == false) { Report("MidTank Cartridge authentication fail", __FILE__, __LINE__, 0, RpMessage, 0, 0); CartridgeStateUpdate(CARTRIDGE_SLOT__Ink, midTankCartColor, CARTRIDGE_STATE__Error, 0); midTankState = MidTankStateIdle; break; } // Cartridge status received from user - assume cartridge is full CartridgeStateUpdate(CARTRIDGE_SLOT__Ink, midTankCartColor, CARTRIDGE_STATE__Inserted, 0); midTankCapacity = Get_MidTank_Pressure_Sensor(midTankCartColor); if ((midTankCapacity > MidTankEmptyLimit)&&(midTankCartColor!=MIDTANK_8))//enable lubricant filling in two stages { Pannel_Leds(CART_1, MODE_ON); cart1.color = fastBILNK; Report("Mid-tank not empty", __FILE__, __LINE__, midTankCapacity, RpMessage, MidTankEmptyLimit, 0); midTankState = MidTankStateIdle; CartridgeStateUpdate(CARTRIDGE_SLOT__Ink, midTankCartColor, CARTRIDGE_STATE__Error, 0); break; } Report("Mid-tank filling in process", __FILE__,__LINE__,(int)(MidTankEmptyLimit*1000), RpMessage, (int)(midTankCapacity*1000), 0); Pannel_Leds(CART_1, MODE_ON); cart1.color = BLINK; CartridgeStateUpdate(CARTRIDGE_SLOT__Ink, midTankCartColor, CARTRIDGE_STATE__Filling, 0); if (midTankCartColor == MIDTANK_8) { CartridgeInkTimeout = CARTRIDGE_INK_TIMEOUT*10; CartridgeCheckTime = FIVE_SECONDS*3; } // set valve selection MidTankValvesAction(Cartridge_MidTank_ON); Report("midTankStateWait set valve", __FILE__, __LINE__, 0, RpMessage, 0, 0); // RFID change status - inkUsed, inkFill rc = RFID_Update_Ink_Fill(); Report("RFID_Update_Ink_Fill", __FILE__, __LINE__, rc, RpMessage, 0, 0); rc = RFID_Update_Ink_Used(); Report("RFID_Update_Ink_Used", __FILE__, __LINE__, rc, RpMessage, 0, 0); // set count down midTankTimeoutCounter = 1; //start filling midTankState = MidTankStateFilling; break; case MidTankStateFilling: if (!RdInkCartridgeSensor()) { // cartridge not presence MidTankValvesAction(Cartridge_MidTank_OFF); Report("Cartridge extracted during filling!!!", __FILE__, __LINE__, midTankState, RpMessage, 0, 0); Report("Mid-tank # filling fail", __FILE__, __LINE__, midTankState, RpMessage, 0, 0); midTankState = MidTankStateIdle; CartridgeStateUpdate(CARTRIDGE_SLOT__Ink, midTankCartColor, CARTRIDGE_STATE__Absent, GetCartridgeFillPercent()); } // if time out or emptying done - idle if (midTankTimeoutCounter++ > CartridgeInkTimeout) { midTankTimeoutCounter = 0; Pannel_Leds(CART_1, MODE_ON); cart1.color = fastBILNK; MidTankValvesAction(Cartridge_MidTank_OFF); Report("Mid-tank # filling fail", __FILE__, __LINE__, midTankState, RpMessage, 0, 0); Report("Call customer support", __FILE__, __LINE__, midTankState, RpMessage, 0, 0); CartridgeStateUpdate(CARTRIDGE_SLOT__Ink, midTankCartColor, CARTRIDGE_STATE__Error, GetCartridgeFillPercent()); midTankState = MidTankStateIdle; } else if (CartridgeInkFull()) { midTankTimeoutCounter = 0; Pannel_Leds(CART_1, MODE_OFF); cart1.color = colorOFF; MidTankValvesAction(Cartridge_MidTank_OFF); Report("Mid-tank # filling done", __FILE__, __LINE__, midTankState, RpMessage, 0, 0); midTankState = MidTankStateIdle; // RFID change status - inkEmpty rc = RFID_Update_Ink_Empty(); Report("RFID_Update_Ink_Empty", __FILE__, __LINE__, rc, RpMessage, 0, 0); CartridgeStateUpdate(CARTRIDGE_SLOT__Ink, midTankCartColor, CARTRIDGE_STATE__FillingCompleted, 100.0); } if (midTankState == MidTankStateFilling) CartridgeStateUpdate(CARTRIDGE_SLOT__Ink, midTankCartColor, CARTRIDGE_STATE__Filling, GetCartridgeFillPercent()); break; default: Report("wrong state", __FILE__, __LINE__, midTankState, RpMessage, 0, 0); break; } }