diff options
| author | Shlomo Hecht <shlomo@twine-s.com> | 2019-04-02 15:16:32 +0300 |
|---|---|---|
| committer | Shlomo Hecht <shlomo@twine-s.com> | 2019-04-02 15:16:32 +0300 |
| commit | 3f6aecd92ceca69ffa5fc07ea0bbe93fd4097c85 (patch) | |
| tree | a0e69764fe4eca3fc445f44e1f963a2a72e4327f /Software/Embedded_SW | |
| parent | 3713f74d0d811b869af5522a576e36f7e6a0ed2e (diff) | |
| download | Tango-3f6aecd92ceca69ffa5fc07ea0bbe93fd4097c85.tar.gz Tango-3f6aecd92ceca69ffa5fc07ea0bbe93fd4097c85.zip | |
Embedded SW Release note - Version 1.3.8.2
File upload: prevent on job, reduce priority (watchdog)
Report: packages filters introduced, please feel free to use them.
robustness in communication improved
large number of segments and gradient support - initial
at the end of job the screw does not return back
rockers - adjust values before and after loading the cart
Diffstat (limited to 'Software/Embedded_SW')
21 files changed, 915 insertions, 236 deletions
diff --git a/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c b/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c index d57d3b14b..3357cfc06 100644 --- a/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c +++ b/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c @@ -55,6 +55,7 @@ int32_t FileSentLength = 0; static char g_cCwdBuf[50] = "/"; uint32_t WrittenBytes = 0; uint32_t ReadBytes = 0; +Task_Handle CommRxTaskHandle; ErrorCode getErrorCode(FRESULT Fresult) @@ -81,27 +82,34 @@ uint32_t FileUploadRequestFunc(MessageContainer* requestContainer) FileUploadResponse response = FILE_UPLOAD_RESPONSE__INIT; WrittenBytes=0; - UploadFileHandle = my_malloc(sizeof(FIL)); - if (UploadFileHandle == 0) + if (JobIsActive()) Fresult = FR_DENIED; else { - Fresult = f_open(UploadFileHandle,request->path,FA_READ | FA_WRITE |FA_OPEN_ALWAYS| FA_CREATE_ALWAYS); - if (Fresult == FR_OK) - { - FileLength = request->length; - response.has_maxchunklength = true; - response.maxchunklength = MAX_CHUNK_LENGTH; - strcpy(FileHandleChar, "1234"); - response.uploadid = FileHandleChar; //supporting only single file at each time. - } + UploadFileHandle = my_malloc(sizeof(FIL)); + if (UploadFileHandle == 0) + Fresult = FR_DENIED; else { - free (UploadFileHandle); - UploadFileHandle = 0; - } + Fresult = f_open(UploadFileHandle,request->path,FA_READ | FA_WRITE | FA_OPEN_ALWAYS | FA_CREATE_ALWAYS); + if (Fresult == FR_OK) + { + FileLength = request->length; + response.has_maxchunklength = true; + response.maxchunklength = MAX_CHUNK_LENGTH; + strcpy(FileHandleChar, "1234"); + response.uploadid = FileHandleChar; //supporting only single file at each time. + } + else + { + free (UploadFileHandle); + UploadFileHandle = 0; + } + } } + CommRxTaskHandle = Task_self(); + Task_setPri(CommRxTaskHandle, 4); responseContainer = createContainer(MESSAGE_TYPE__FileUploadResponse, requestContainer->token, false, &response, &file_upload_response__pack, &file_upload_response__get_packed_size); @@ -123,6 +131,7 @@ uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; FRESULT Fresult = FR_OK; + bool FileDone = false; MessageContainer responseContainer; @@ -142,6 +151,7 @@ uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) if(Fresult != FR_OK) { LOG_ERROR (Fresult,"f_write error"); + FileDone = true; } else { @@ -152,6 +162,7 @@ uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) f_close(ReceivedFileHandle); free (UploadFileHandle); FileReceivedLength = 0; + FileDone = true; } else { @@ -161,6 +172,7 @@ uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) f_close(ReceivedFileHandle); free (UploadFileHandle); FileReceivedLength = 0; + FileDone = true; } } } @@ -185,6 +197,8 @@ uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) file_chunk_upload_request__free_unpacked(request,NULL); my_free(responseContainer.data.data); SendChars(container_buffer, container_size); + if (FileDone == true) + Task_setPri(CommRxTaskHandle, 9); return OK; } @@ -504,7 +518,7 @@ uint32_t GetFilesRequestFunc(MessageContainer* requestContainer) #define MAX_NUM_OF_FILES 10 DIR dir; FILINFO* fno[MAX_NUM_OF_FILES]; - char FullPath[MAX_NUM_OF_FILES][50]; + char FullPath[MAX_NUM_OF_FILES][100]; int i,NumOfFiles = 0; FRESULT Fresult = FR_OK; @@ -580,11 +594,14 @@ uint32_t GetFilesRequestFunc(MessageContainer* requestContainer) } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); - size_t container_size = message_container__pack(&responseContainer, container_buffer); + if (container_buffer) + { + size_t container_size = message_container__pack(&responseContainer, container_buffer); + SendChars(container_buffer, container_size); + } my_free(responseContainer.data.data); my_free(FilesInfo); get_files_request__free_unpacked(request,NULL); - SendChars(container_buffer, container_size); for (i = 0;i < NumOfFiles;i++) { if (fno[i]) diff --git a/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.c b/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.c index 456c30290..a31f4bef8 100644 --- a/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.c +++ b/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.c @@ -21,6 +21,7 @@ #include <Communication/PMR/FirmwareUpgrade/VersionFileDescriptor.pb-c.h> #include <Communication/PMR/FirmwareUpgrade/VersionPackageDescriptor.pb-c.h> +#include "drivers/FPGA/FPGA_GPIO/FPGA_GPIO.h" #include "drivers/FPGA/Full_Vme/FPGA_Programming_Up.h" #include "drivers/FPGA/Full_Vme/ispvme/vmopcode.h" #include "Common/Utilities/Utils.h" diff --git a/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c b/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c index e037f2bad..7f22a613a 100644 --- a/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c +++ b/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c @@ -20,7 +20,7 @@ typedef struct } TangoVersion_t; -TangoVersion_t _gTangoVersion = {1,3,8,12}; +TangoVersion_t _gTangoVersion = {1,3,8,2}; #define BUILD_DATE __DATE__ char Dat[50] = BUILD_DATE; char _gTangoName [MAX_STRING_LEN] = "Tango01 ";//d diff --git a/Software/Embedded_SW/Embedded/Common/report/distributor.c b/Software/Embedded_SW/Embedded/Common/report/distributor.c index c026ad4d2..f011653ec 100644 --- a/Software/Embedded_SW/Embedded/Common/report/distributor.c +++ b/Software/Embedded_SW/Embedded/Common/report/distributor.c @@ -242,7 +242,7 @@ Void reportService(UArg arg0, UArg arg1) ReportInitParams InitParams; InitParams.DistributorQueueMaxMsgs = 30; InitParams.DistributorTaskPriority = 6; - InitParams.MaxNumOfFilterNames = 1;//30 + InitParams.MaxNumOfFilterNames = 30; InitParams.MaxNumberOfPrivateDistributors = 2; ReportInit (InitParams); diff --git a/Software/Embedded_SW/Embedded/DataDef.h b/Software/Embedded_SW/Embedded/DataDef.h index 424eff1d8..1b5f000f2 100644 --- a/Software/Embedded_SW/Embedded/DataDef.h +++ b/Software/Embedded_SW/Embedded/DataDef.h @@ -400,7 +400,7 @@ Supports diagnostic <id> (--diag_suppress, - pds) #define HEAD6_PT100 TEMP_SENSE_AN_ENCLOSURETEMP3 #define MIXER_PT100 TEMP_SENSE_ANALOG_MIXCHIP_TEMP -/* + extern PackageHandle ControlFilter; extern PackageHandle HeatersFilter; extern PackageHandle JobFilter ; @@ -415,6 +415,6 @@ extern PackageHandle FPGAFilter; extern PackageHandle LoadFilter; extern PackageHandle InitFilter; extern PackageHandle MaintFilter; -*/ + #endif /* DATADEF_H */ diff --git a/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c b/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c index 637c91e7d..ac1cff75e 100644 --- a/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c +++ b/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c @@ -33,7 +33,7 @@ uint32_t ReadAppAndProgram(uint32_t ui32FlashStart,uint32_t ui32FileSize,void* b uint32_t ui32ProgAddr; uint32_t ui32BufferAddr; volatile uint32_t ui32Idx; - uint32_t ui32FlashEnd; + //uint32_t ui32FlashEnd; // @@ -41,7 +41,7 @@ uint32_t ReadAppAndProgram(uint32_t ui32FlashStart,uint32_t ui32FileSize,void* b // If reserved space is configured, then the ending address is reduced // by the amount of the reserved block. // - ui32FlashEnd = ui32FlashStart + ui32FileSize; + //ui32FlashEnd = ui32FlashStart + ui32FileSize; // @@ -68,7 +68,7 @@ uint32_t ReadAppAndProgram(uint32_t ui32FlashStart,uint32_t ui32FileSize,void* b // stick updater). // ui32ProgAddr = ui32FlashStart; - ui32BufferAddr = buffer; + ui32BufferAddr = (uint32_t)buffer; ui32Remaining = ui32FileSize; while(ui32Remaining) { diff --git a/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c b/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c index 7c0f9a6c1..8e76badfe 100644 --- a/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c +++ b/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c @@ -337,7 +337,7 @@ const AlarmHandlingItemStruc HardCodedAlarmItem[MAX_SYSTEM_ALARMS]={ char AlarmStorePath[25] ="0://SysInfo//AlarmPrm.cfg"; -bool DispenserInUse[MAX_SYSTEM_DISPENSERS] = {false,false,false,false,false,false,false,false}; +//bool DispenserInUse[MAX_SYSTEM_DISPENSERS] = {false,false,false,false,false,false,false,false}; bool EventsNotificationRequestAccepted = false; //read dispensers limit switches. 25 - send warning. up - stop job and send alarm //Cone missing @@ -471,7 +471,7 @@ uint32_t AlarmHandlingConsequentActions(uint32_t AlarmId, DebugLogCategory Sever MotorStop(HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1+Disp_i,Hard_Hiz); if (JobIsActive()) { - if (DispenserInUse[Disp_i] == false) + if (DispenserUsedInJob[Disp_i] == false) AlarmItem[AlarmId].Severity = DEBUG_LOG_CATEGORY__Info; } } @@ -481,7 +481,7 @@ uint32_t AlarmHandlingConsequentActions(uint32_t AlarmId, DebugLogCategory Sever MotorStop(HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1+Disp_i,Hard_Hiz); if (JobIsActive()) { - if (DispenserInUse[Disp_i] == false) + if (DispenserUsedInJob[Disp_i] == false) AlarmItem[AlarmId].Severity = DEBUG_LOG_CATEGORY__Info; } break; @@ -505,24 +505,26 @@ uint32_t AlarmHandlingConsequentActions(uint32_t AlarmId, DebugLogCategory Sever } JobEndReasonEnum AlarmHandlingPrepareJob(void *CurrentJob) { - JobTicket* JobTicket = CurrentJob; + //JobTicket* JobTicket = CurrentJob; EventType HeaterEventType[MAX_HEATERS_NUM*2] = {EVENT_TYPE__DRYER_ZONE_1_OVERTEMPERATURE,EVENT_TYPE__DRYER_ZONE_2_OVERTEMPERATURE,EVENT_TYPE__DRYER_ZONE_1_OVERTEMPERATURE,EVENT_TYPE__DYEING_HEAD_ZONE_1_OVERTEMPERATURE,EVENT_TYPE__DYEING_HEAD_ZONE_2_OVERTEMPERATURE, EVENT_TYPE__DYEING_HEAD_ZONE_3_OVERTEMPERATURE,EVENT_TYPE__DYEING_HEAD_ZONE_4_OVERTEMPERATURE,EVENT_TYPE__DYEING_HEAD_ZONE_5_OVERTEMPERATURE,EVENT_TYPE__DYEING_HEAD_ZONE_6_OVERTEMPERATURE, EVENT_TYPE__MIXER_OVERTEMPERATURE}; EventType HeaterEventTypeUnder[MAX_HEATERS_NUM*2] = {EVENT_TYPE__DRYER_ZONE_1_UNDERTEMPERATURE_B,EVENT_TYPE__DRYER_ZONE_2_UNDERTEMPERATURE_B,EVENT_TYPE__DRYER_ZONE_1_UNDERTEMPERATURE_B,EVENT_TYPE__DYEING_HEAD_ZONE_1_UNDERTEMPERATURE_B,EVENT_TYPE__DYEING_HEAD_ZONE_2_UNDERTEMPERATURE_B, EVENT_TYPE__DYEING_HEAD_ZONE_3_UNDERTEMPERATURE_B,EVENT_TYPE__DYEING_HEAD_ZONE_4_UNDERTEMPERATURE_B,EVENT_TYPE__DYEING_HEAD_ZONE_5_UNDERTEMPERATURE_B,EVENT_TYPE__DYEING_HEAD_ZONE_6_UNDERTEMPERATURE_B, EVENT_TYPE__MIXER_UNDERTEMPERATURE_B}; - int Segment_i,Brush_i,Dispenser_i,DispenserId,Alarm_i,Heater_i,AlarmId=0; + int Dispenser_i,Alarm_i,Heater_i,AlarmId=0; HeaterState HeaterState; - for (Dispenser_i = 0;Dispenser_i < MAX_SYSTEM_DISPENSERS;Dispenser_i++) - { - DispenserInUse[Dispenser_i] = false; - } + //for (Dispenser_i = 0;Dispenser_i < MAX_SYSTEM_DISPENSERS;Dispenser_i++) + //{ + // DispenserInUse[Dispenser_i] = false; + //} JobEndReasonEnum status = JOB_OK; - if (JobTicket->n_segments == 0) + IDS_MapDispenserUsedinJob(CurrentJob); + if (n_segments == 0) return OK; - for (Segment_i=0;Segment_i<JobTicket->n_segments;Segment_i++) + + /*for (Segment_i=0;Segment_i<JobTicket->n_segments;Segment_i++) { for (Brush_i=0;Brush_i<JobTicket->segments[Segment_i]->n_brushstops;Brush_i++) { @@ -540,11 +542,12 @@ JobEndReasonEnum AlarmHandlingPrepareJob(void *CurrentJob) }//if dispensers }//for brush }//for segments + */ if (Configured[Module_IDS]) { for (Dispenser_i=0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++) { - if (DispenserInUse[Dispenser_i] == true) + if (DispenserUsedInJob[Dispenser_i] == true) { for (Alarm_i = 0;Alarm_i<MAX_SYSTEM_ALARMS;Alarm_i++) { @@ -664,7 +667,6 @@ void AlarmHandlingInternalSetAlarm(uint32_t AlarmId, bool value) { if (AlarmState[Alarm_i].Status != value) { - AlarmState[Alarm_i].Status = value; if (value == true) { // no need to call consequent actionsAlarmHandlingConsequentActions(Alarm_i, AlarmItem[Alarm_i].Severity); @@ -676,12 +678,14 @@ void AlarmHandlingInternalSetAlarm(uint32_t AlarmId, bool value) AlarmState[Alarm_i].EventPtr->has_type = true; AlarmState[Alarm_i].EventPtr->type = AlarmItem[Alarm_i].EventType; AlarmState[Alarm_i].EventPtr->message = AlarmItem[Alarm_i].EventName; + AlarmState[Alarm_i].Status = value; Report("Alarm ON ", __FILE__,__LINE__,AlarmItem[Alarm_i].EventType, RpMessage, value, Alarm_i); } } else { Report("Alarm OFF ", __FILE__,__LINE__,AlarmItem[Alarm_i].EventType, RpMessage, value, Alarm_i); + AlarmState[Alarm_i].Status = value; if (AlarmState[Alarm_i].EventPtr) my_free(AlarmState[Alarm_i].EventPtr); } @@ -1017,20 +1021,33 @@ void SendEventNotifications(void) response.n_events++; } } - response.events = (Event **)my_malloc(sizeof(Event*)*response.n_events); - if(response.events) + + if (response.n_events) { - for (i = 0;i<MAX_SYSTEM_ALARMS;i++) + response.events = (Event **)my_malloc(sizeof(Event*)*response.n_events); + if(response.events) { - if (AlarmState[i].Status == true) + for (i = 0;i<MAX_SYSTEM_ALARMS;i++) { - if (AlarmState[i].EventPtr) + if (AlarmState[i].Status == true) { - response.events[e]=AlarmState[i].EventPtr; - e++; + if (AlarmState[i].EventPtr) + { + response.events[e]=AlarmState[i].EventPtr; + e++; + } } } } + else + { + LOG_ERROR(response.n_events,"events malloc error"); + return ERROR; + } + } + else + { + response.events = NULL; } responseContainer = createAllocatedContainer(MESSAGE_TYPE__StartEventsNotificationResponse, AlarmHandlingToken, false, &response, &start_events_notification_response__pack, &start_events_notification_response__get_packed_size,&alarm_response_buffer); responseContainer.continuous = true; diff --git a/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c b/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c index 738f59686..d34ac9ff9 100644 --- a/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c +++ b/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c @@ -484,6 +484,7 @@ uint32_t MillisecLowLoop(uint32_t tick) if (watchdogCriticalAlarm == false) { Control_WD(ENABLE,5); //activate heaters/dispenser watchdog, 0.5 seconds + //LOG_ERROR (1111, "Control_WD"); } } } diff --git a/Software/Embedded_SW/Embedded/Modules/Diagnostics/DiagnosticsHoming.c b/Software/Embedded_SW/Embedded/Modules/Diagnostics/DiagnosticsHoming.c index 16ec83b16..8ddc2f84d 100644 --- a/Software/Embedded_SW/Embedded/Modules/Diagnostics/DiagnosticsHoming.c +++ b/Software/Embedded_SW/Embedded/Modules/Diagnostics/DiagnosticsHoming.c @@ -33,6 +33,7 @@ #include "StateMachines/Printing/PrintingSTM.h" char HomingToken[NUM_OF_MOTORS][36+1]={0}; + /******************************************************************************** * Motor Homing ********************************************************************************/ @@ -40,12 +41,6 @@ uint32_t MotorHomingRequestCallback(uint32_t deviceID, uint32_t ReadValue) { MessageContainer responseContainer; MotorHomingResponse response = MOTOR_HOMING_RESPONSE__INIT; - if((deviceID == HARDWARE_MOTOR_TYPE__MOTO_LLOADING)||(deviceID == HARDWARE_MOTOR_TYPE__MOTO_RLOADING)) - { - MotorSetMicroStep(deviceID, MotorsCfg[deviceID].microstep); - MotorSetKvalRun(deviceID, MotorsCfg[deviceID].kvalrun); - Task_sleep(10); - } responseContainer = createContainer(MESSAGE_TYPE__MotorHomingResponse, HomingToken[deviceID], true, &response, &motor_homing_response__pack, &motor_homing_response__get_packed_size); responseContainer.continuous = true; @@ -100,13 +95,6 @@ uint32_t MotorHomingRequestFunc(MessageContainer* requestContainer) } else { - if((MotorId == HARDWARE_MOTOR_TYPE__MOTO_LLOADING)||(MotorId == HARDWARE_MOTOR_TYPE__MOTO_RLOADING)) - { - MotorSetMicroStep(MotorId, 1); - MotorSetKvalRun(MotorId, 35); - Task_sleep(10); - } - if ( Motor_Id_to_LS_IdUp[MotorId] != MAX_GPI) { MotorMovetoLimitSwitch (MotorId,MotorsCfg[MotorId].directionthreadwize, speed, Motor_Id_to_LS_IdDown[MotorId], MotorHomingRequestCallback,10000); diff --git a/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c b/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c index 74f8c8746..f5aec59f6 100644 --- a/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c +++ b/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c @@ -175,7 +175,7 @@ uint32_t EmbeddedParametersInit(void) LoadConfigurationParameters(Params); DataUpdated=true; free (buffer); - configuration_parameters__free_unpacked(NULL,Params); + configuration_parameters__free_unpacked(Params,NULL); } else { diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h b/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h index ba08101f8..80a55d63e 100644 --- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h +++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h @@ -5,6 +5,7 @@ #include "drivers/motors/motor.h" #include "ids_ex.h" +extern uint32_t CurrentDispenserSpeed[MAX_SYSTEM_DISPENSERS]; extern uint32_t DispenserIdToMotorId[MAX_SYSTEM_DISPENSERS]; extern float DispenserPressure[MAX_SYSTEM_DISPENSERS]; uint32_t DispenserConfigMessage(HardwareDispenser * request); diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c index 0fcd73b59..3eaa2f9c2 100644 --- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c +++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c @@ -238,7 +238,7 @@ void IDS_Dispenser_Content_Init (void) IDS_Dispenser_Data[i].has_nanolitterperpulse = true; } free (buffer); - dispenser_data__free_unpacked(NULL,StoredDispenserData); + dispenser_data__free_unpacked(StoredDispenserData,NULL); } return; diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h index ded3642a0..2e8d33e1a 100644 --- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h +++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h @@ -33,6 +33,8 @@ extern bool EnableLubrication; extern bool EnableIntersegment; extern double IntersegmentLength; +extern bool DispenserUsedInJob[MAX_SYSTEM_DISPENSERS]; +bool IDS_MapDispenserUsedinJob(void *JobDetails); void IDS_ModuleInit (void); void Calculateinit(void); @@ -68,6 +70,7 @@ uint32_t IDS_Dispenser_Start_Motor_and_Open_Valve(int DispenserId, int MotorSpee void IDS_Dispenser_Content_Calculation (char DispenserId); +uint32_t IDS_MapDispenserUsedinFileJob(void *JobDetails); float CalculateDispenserPressure (int DispenserId); float GetDispenserPressure(int DispenserId); diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c index 9e9c82131..1bdf15b29 100644 --- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c +++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c @@ -84,7 +84,6 @@ uint32_t IDS_HomeDispenserBackMoveCallback(uint32_t deviceID, uint32_t ReadValue if ((GetDispenserPressure(DispenserId)>=InitialDispenserPressure)||(DispenserHomingTime[DispenserId]>InitialDispenserTimeout)) { MotorStop(deviceID,Hard_Hiz); - MotorSetMicroStep(deviceID, MotorsCfg[deviceID].microstep); HomingActive[DispenserId]= false; Report("End backlash",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)DispenserHomingTime[DispenserId],0); @@ -169,6 +168,7 @@ uint32_t IDS_Dispenser_Alarm_On (uint8_t deviceID) Enable_MidTank_Pressure_Reading(deviceID); status |= MotorSetMicroStep(deviceID, MotorsCfg[deviceID].microstep); status |= MotorStop(deviceID, Hard_Hiz); + JobEndReason = JOB_OUT_OF_DYE; return status; } uint32_t IDS_Dispenser_Alarm_Off (uint8_t deviceID) diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c index 38c139141..d868354dd 100644 --- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c +++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c @@ -12,10 +12,18 @@ #include "../thread/thread.h" #include "PMR/Hardware/Hardwaremotor.pb-c.h" #include "PMR/Hardware/HardwareDispenser.pb-c.h" +#include "PMR/Printing/JobDescriptionFileBrushStop.pb-c.h" +#include "PMR/Printing/JobDescriptionFileSegment.pb-c.h" +#include "PMR/Printing/JobUploadStrategy.pb-c.h" +#include "PMR/Printing/JobSegment.pb-c.h" +#include "PMR/Printing/JobTicket.pb-c.h" #include "StateMachines/Printing/printingSTM.h" #include "drivers/motors/motor.h" #include "drivers/valves/valve.h" +#include "Common/SWUpdate/FileSystem.h" +#include "drivers/Flash_Memory/fatfs/ff.h" + #include "modules/heaters/heaters.h" #include "drivers/Flash_ram/FlashProgram.h" @@ -33,7 +41,8 @@ typedef struct }DispenserControlConfig_t; HardwarePidControl *DispensersControl;// = (HardwarePidControl *)GENHWCFG_MAP_IN_FLASH + 0x4000; #define LUBRICANT_DISPENSER 7 -#define MAX_DYE_DISPENSERS 7 +#define CLEANER_DISPENSER 7 +#define MAX_DYE_DISPENSERS 6 int32_t DispenserSamples[MAX_SYSTEM_DISPENSERS][MAX_CONTROL_SAMPLES] = {0}; int DispenserSamplePointer[MAX_SYSTEM_DISPENSERS] = {0}; double DispenserNormalizedErrorCoEfficient[MAX_SYSTEM_DISPENSERS] = {0}; @@ -45,7 +54,8 @@ bool IDS_Active = false; /******************** STRUCTURES AND ENUMs ********************************************/ uint32_t IDS_Valve_DistanceToSpoolReady(uint32_t deviceID, uint32_t ReadValue); uint32_t IDS_Valve_PresegmentReady(uint32_t deviceID, uint32_t ReadValue); -bool IDS_isDispenserUsedNextSegment(void *JobDetails,int DispenserId, int SegmentId); +uint32_t IDSBrushStopRestartCallback(uint32_t IfIndex, uint32_t readValue); +//bool IDS_isDispenserUsedNextSegment(void *JobDetails,int DispenserId, int SegmentId); /******************** GLOBAL PARAMETERS ********************************************/ DispenserControlConfig_t DispenserControlConfig[MAX_SYSTEM_DISPENSERS]; uint32_t ControlIdtoDispenserId [MAX_SYSTEM_DISPENSERS] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; @@ -122,7 +132,7 @@ void DispenserPrepareReady(void) return; //not all configured Dispensers are ready } } - REPORT_MSG(Module_IDS,"DispenserPrepareReady"); + REPORT_MSG(Module_IDS,"All Dispensers Prepare Ready"); PrepareReady(Module_IDS,ModuleDone); } //******************************************************************************************************************** @@ -137,45 +147,296 @@ void DispenserPrepareReady(void) return OK; // all configured heaters are ready } - bool IDS_MapDispenserUsedinJob(void *JobDetails) +/* + void OpenJobFile(); +void CloseJobFile(); +JobDescriptionFileSegment *GetNextSegmentFromJobFile(); +void FreeSegmentFileData(JobDescriptionFileSegment *Segment); +JobDescriptionFileBrushStop *GetNextBrushStopFromJobFile(); +void FreeBrushStopFileData(JobDescriptionFileBrushStop *BrushStop); + + */ + /************************************************************************************************************************************/ + uint32_t IDS_MapDispenserUsedinFileJobshort(void *JobDetails) + { + JobDescriptionFileBrushStop *BrushStop; + JobDescriptionFileSegment *Segment; + int Dispenser_i, Brush_i,DispenserId; + FRESULT Fresult = FR_OK; + uint32_t status = OK; + + for (Dispenser_i = 0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++) + { + DispenserUsedInJob[Dispenser_i] = false; + } + Fresult = OpenJobFile(); + if (Fresult == FR_OK) + { + Segment = GetNextSegmentFromJobFile(); + while(Segment) + { + if ((Segment->has_brushstopscount)&&(Segment->brushstopscount)) + { + for (Brush_i=0;Brush_i<Segment->brushstopscount;Brush_i++) + { + BrushStop = GetNextBrushStopFromJobFile(); + if (BrushStop) + { + if (BrushStop->n_dispensers) + { + for (Dispenser_i = 0;Dispenser_i < BrushStop->n_dispensers;Dispenser_i++) + { + //prepare the SW structures + DispenserId = BrushStop->dispensers[Dispenser_i]->index; + if (BrushStop->dispensers[Dispenser_i]->nanolitterpersecond>0.0) + { + DispenserUsedInJob[DispenserId] = true; + /*if(DispenserId == LUBRICANT_DISPENSER) + { + lubricant_speed = JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond/ + JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanoliterperpulse; + REPORT_MSG (lubricant_speed*100, "LUBRICANT_SPEED*100"); + }*/ + } + }//for dispenser + }//if dispensers + else + { + LOG_ERROR (BrushStop->index, "no dispensers in brushstop"); + } + FreeBrushStopFileData(BrushStop); + BrushStop = NULL; + } + else + { + LOG_ERROR (BrushStop, "malloc error"); + status = ERROR; + } + }//for brushstops + }// if brush stop count + FreeSegmentFileData(Segment); + Segment = GetNextSegmentFromJobFile(); + } + FreeSegmentFileData(Segment); + CloseJobFile(); + } + return status; + + } + /************************************************************************************************************************************/ + uint32_t IDS_MapDispenserUsedinFileJob(void *JobDetails) { JobTicket* JobTicket = JobDetails; - int Dispenser_i, Segment_i,Brush_i,DispenserId; + uint8_t *SegmentPtr = 0, *BrushStopPtr = 0; + JobDescriptionFileBrushStop *BrushStop; + JobDescriptionFileSegment *Segment; + int Dispenser_i, Brush_i,DispenserId; + uint32_t Bytes = 0,readBytes = 0,ImmediateRead = 0,SegmentSize = 0,BrushStopSize = 0; + uint32_t status = OK; + FRESULT Fresult = FR_OK; + FIL *FileHandle = 0; //the system supports a single active file + +/* + Parsing the job description file. +The job description file simply contains an array of segments and their brush stops. +The job description file is meant to be read brush stop by brush stop while the job is in progress. +The following diagram represents a single job description file segment structure. +The process of reading the whole file is simply repeating that reading order. + +Each JobDescriptionFileSegment contains a “BrushStopsCount” field that should be used to determine how many brush stops are associated +with the current segment and how many times the process of reading brush stops should be repeated. +1. 32bit integer containing the next JobFileDescriptionSegment message byte count +2. JobDescriptionFileSegment message +3. 32bit integer containing the next JobDescriptionFileBrushStop message byte count +4. JobDescriptionFileBrushStop message +1. Read segment message length. +2. Read segment message. +a. Read brush stop message length. +b. Read brush stop message. +c. Go to step 2.a x Segment.BrushStopsCount. +3. Go to step 1 until end of file. + */ for (Dispenser_i = 0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++) { DispenserUsedInJob[Dispenser_i] = false; } - if (JobTicket->n_segments == 0) - return false; + n_segments = 0; + if (JobTicket->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + FileHandle = my_malloc(sizeof(FIL)); - for (Segment_i=0;Segment_i<JobTicket->n_segments;Segment_i++) + Fresult = FileOpen(JobTicket->jobdescriptionfile, &Bytes, FileHandle); + if (Fresult == FR_OK) { - for (Brush_i=0;Brush_i<JobTicket->segments[Segment_i]->n_brushstops;Brush_i++) + while((readBytes < Bytes)&&(status == OK)) { - if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers) + Fresult = f_read(FileHandle,&SegmentSize,4,&ImmediateRead ); + if (Fresult == FR_OK) { - for (Dispenser_i = 0;Dispenser_i < JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers;Dispenser_i++) + readBytes += ImmediateRead; + SegmentPtr = my_malloc (SegmentSize); + if (SegmentPtr) { - //prepare the SW structures - DispenserId = JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->index; - if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->nanolitterpersecond>0.0) + Fresult = f_read(FileHandle,SegmentPtr,SegmentSize,&ImmediateRead ); + if (Fresult == FR_OK) { - DispenserUsedInJob[DispenserId] = true; - if(DispenserId == LUBRICANT_DISPENSER) + readBytes += ImmediateRead; + n_segments++; + Segment = job_description_file_segment__unpack(NULL, SegmentSize, SegmentPtr); + if ((Segment->has_brushstopscount)&&(Segment->brushstopscount)) { - lubricant_speed = JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond/ - JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanoliterperpulse; - REPORT_MSG (lubricant_speed*100, "LUBRICANT_SPEED*100"); + REPORT_MSG (Segment->brushstopscount, "Segment->brushstopscount"); + for (Brush_i=0;Brush_i<Segment->brushstopscount;Brush_i++) + { + if (status == ERROR) + break; + Fresult = f_read(FileHandle,&BrushStopSize,4,&ImmediateRead ); + if (Fresult == FR_OK) + { + readBytes += ImmediateRead; + BrushStopPtr = my_malloc (BrushStopSize); + if (BrushStopPtr) + { + Fresult = f_read(FileHandle,BrushStopPtr,BrushStopSize,&ImmediateRead ); + if (Fresult == FR_OK) + { + readBytes += ImmediateRead; + BrushStop = job_description_file_brush_stop__unpack(NULL, BrushStopSize, BrushStopPtr); + REPORT_MSG (BrushStopSize, "BrushStop"); + if (BrushStop->n_dispensers) + { + for (Dispenser_i = 0;Dispenser_i < BrushStop->n_dispensers;Dispenser_i++) + { + //prepare the SW structures + DispenserId = BrushStop->dispensers[Dispenser_i]->index; + if (BrushStop->dispensers[Dispenser_i]->nanolitterpersecond>0.0) + { + DispenserUsedInJob[DispenserId] = true; + } + }//for dispenser + }//if dispensers + else + { + LOG_ERROR (BrushStop->index, "no dispensers in brushstop"); + } + job_description_file_brush_stop__free_unpacked (BrushStop,NULL); + BrushStop = NULL; + } //read brush stop data + else + { + LOG_ERROR (Fresult, "f_read error"); + status = ERROR; + } + my_free(BrushStopPtr); + BrushStopPtr = NULL; + }//brushstop malloc ok + else + { + LOG_ERROR (BrushStopPtr, "malloc error"); + status = ERROR; + } + }//brushstop size read ok + else + { + LOG_ERROR (Fresult, "f_read error"); + status = ERROR; + } + }//for brushstops + }// if brush stop count + else + { + LOG_ERROR (0, "no brushstops error"); + status = ERROR; } + job_description_file_segment__free_unpacked(Segment,NULL); + Segment = NULL; + }// read segment data + my_free(SegmentPtr); + SegmentPtr = NULL; + Task_sleep(10); + }//segment malloc + else + { + LOG_ERROR (SegmentPtr, "malloc error"); + status = ERROR; + } + }//segment read size + else + { + LOG_ERROR (Fresult, "f_read error"); + status = ERROR; + } + }//while(readBytes < Bytes) + } + else + { + LOG_ERROR (Fresult, "FileOpen error"); + status = ERROR; + } + }//file job - } - }//for dispenser - }//if dispensers - }//for brush - }//for segments + if (SegmentPtr) + my_free(SegmentPtr); + if (BrushStopPtr) + my_free(BrushStopPtr); + if (Segment != NULL) + job_description_file_segment__free_unpacked(Segment,NULL); + if (BrushStop != NULL) + job_description_file_brush_stop__free_unpacked (BrushStop,NULL); + Fresult = f_close(FileHandle); + REPORT_MSG (n_segments, "Finished checking the file"); + return status; + + } +/************************************************************************************************************************************/ + bool IDS_MapDispenserUsedinJob(void *JobDetails) + { + JobTicket* JobTicket = JobDetails; + int Dispenser_i, Segment_i,Brush_i,DispenserId; + + if (JobTicket->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + return (IDS_MapDispenserUsedinFileJob(JobDetails)); + //return (IDS_MapDispenserUsedinFileJobshort(JobDetails)); + } + else + { + for (Dispenser_i = 0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++) + { + DispenserUsedInJob[Dispenser_i] = false; + } + if (n_segments == 0) + return false; - return false; + for (Segment_i=0;Segment_i<n_segments;Segment_i++) + { + for (Brush_i=0;Brush_i<JobTicket->segments[Segment_i]->n_brushstops;Brush_i++) + { + if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers) + { + for (Dispenser_i = 0;Dispenser_i < JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers;Dispenser_i++) + { + //prepare the SW structures + DispenserId = JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->index; + if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->nanolitterpersecond>0.0) + { + DispenserUsedInJob[DispenserId] = true; + if(DispenserId == LUBRICANT_DISPENSER) + { + lubricant_speed = JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond/ + JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanoliterperpulse; + REPORT_MSG (lubricant_speed*100, "LUBRICANT_SPEED*100"); + } + + } + }//for dispenser + }//if dispensers + }//for brush + }//for segments + } + + return true; } @@ -214,7 +475,7 @@ void DispenserPrepareReady(void) //ValveCommand (Enable,MixerDirection); } //set 3 dancers to the profile positions - IDS_MapDispenserUsedinJob(JobDetails); + //IDS_MapDispenserUsedinJob(JobDetails); for (i = 0; i < MAX_SYSTEM_DISPENSERS; i++) { if (DispenserUsedInJob[i] == true) //we actually should check for all dispensers @@ -229,32 +490,6 @@ void DispenserPrepareReady(void) DispenserPrepareReady(); return OK; } -bool IDS_isDispenserUsedNextSegment(void *SegmentDetails,int DispenserId, int SegmentId) -{ - JobSegment* Segment = SegmentDetails; - int Dispenser_i,n_dispensers; - if (Segment->brushstops[0]->n_dispensers) - { - n_dispensers = Segment->brushstops[0]->n_dispensers; - for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++) - { - if (DispenserId == Segment->brushstops[0]->dispensers[Dispenser_i]->index) //dispenser is in use next segment - { - if (Segment->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond>0) - { - return true; - } - else - { - return false; - } - } - } - } - - return false; - -} //******************************************************************************************************************** uint32_t IDS_Valve_PresegmentValveReady(uint32_t deviceID, uint32_t ReadValue) { @@ -287,8 +522,17 @@ bool IDS_isDispenserUsedNextSegment(void *SegmentDetails,int DispenserId, int Se int lInterSegmentLength = 0; int InterSegmentStepsLimit = 0,InterSegmentStepsCount = 0; - int InterSegmentWFCFTime; + uint32_t InterSegmentStartSprayCleaner; + uint32_t InterSegmentStartRocking; + uint32_t InterSegmentCenterRockers; + uint32_t InterSegmentStartWFCFDispensers; + bool EnableCleaning = false; + + uint32_t DispenserPreSegmentControlId = 0xFF; + uint32_t BrushStopControlId = 0xFF; + uint32_t PreSegmentControlId = 0xFF; + //******************************************************************************************************************** uint32_t IDSPreSegmentStateCallbackRunner(uint32_t IfIndex, uint32_t ReadValue) @@ -313,19 +557,49 @@ This means that for each Pre-segment we must calculate: TW,TU,Tending, This means that for each segment we must calculate: Tx,Ty. */ +/*uint32_t InterSegmentStartSprayCleaner = 500; +uint32_t InterSegmentStartRocking = 1000; +uint32_t InterSegmentCenterRockers = 3000; +uint32_t InterSegmentStartWFCFDispensers = lInterSegmentLength-1500;*/ //InterSegmentStepsLimit = lInterSegmentLength*10;//100 millisec steps - InterSegmentStepsCount++; - if (InterSegmentStepsCount == InterSegmentStepsLimit) + InterSegmentStepsCount+=100; + if (InterSegmentStepsCount == lInterSegmentLength) { - IDS_Valve_PresegmentReady(1,0); + //IDS_Valve_PresegmentReady(1,0); + Report("End of Pre-segment Handling",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0); SafeRemoveControlCallback(DispenserPreSegmentControlId,IDSPreSegmentStateCallbackRunner); } + if (EnableCleaning == true) + { + if (InterSegmentStartSprayCleaner == InterSegmentStepsCount) + { + Report("Start Spray Cleaner",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0); + //startClenerSpray(speed); + } + if (InterSegmentStartRocking == InterSegmentStepsCount) + { + Report("Start cleaning rockers",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0); + //startRocking(leftspeed,rightspeed); + } + if (InterSegmentCenterRockers == InterSegmentStepsCount) + { + Report("Stop spray and center rockers",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0); + //stopClenerSpray(speed); + //centerRockers(); + } + } + if (InterSegmentStartWFCFDispensers == InterSegmentStepsCount) + { + Report("start dispensers at rate * WFCF",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0); + //startDispensersAtSegmentSpeed*1=WFCFClenerSpray(speed); + } return OK; } - +JobDescriptionFileBrushStop * FileBrushStop; uint32_t IDSPreSegmentState(void *SegmentDetails, int SegmentId) { JobSegment* Segment = SegmentDetails; + JobDispenser **Dispensers; //set the speed only before the first segment, speed is constant accros job int Dispenser_i,n_dispensers,DispenserId; TimerMotors_t HW_Motor_Id; @@ -339,7 +613,9 @@ uint32_t IDSPreSegmentState(void *SegmentDetails, int SegmentId) REPORT_MSG(SegmentId,"IDSPreSegmentState"); if (JobBrushStopId>=Segment->n_brushstops) { - LOG_ERROR(JobBrushStopId,"Error JobBrushStopId"); + LOG_ERROR(Segment->n_brushstops,"Error JobBrushStopId"); + JobEndReason = JOB_OUT_OF_DYE; + PreSegmentReady(Module_IDS,ModuleFail); return ERROR; } @@ -347,148 +623,248 @@ uint32_t IDSPreSegmentState(void *SegmentDetails, int SegmentId) if ((EnableIntersegment == true)&&(IntersegmentLength>0)) { Valve_Set(VALVE_MIXCHIP_WASTECH, Mixer_Waste); //if intersegment is defined throw the ink away - lInterSegmentLength = ((IntersegmentLength*100)/dyeingspeed); - InterSegmentStepsLimit = lInterSegmentLength*10;//100 millisec steps - InterSegmentStepsCount = 0; - /*DispenserPreSegmentControlId = AddControlCallback( IDSPreSegmentStateCallbackRunner, 100,TemplateDataReadCBFunction ,0, 0, 0 ); - if (DispenserPreSegmentControlId == 0xFF) + if (SegmentId>0) { - Report("Add control callback failed",__FILE__,__LINE__,(int)InterSegmentLength,RpWarning,(int)0,0); - return ERROR; - }*/ + lInterSegmentLength = ((IntersegmentLength*100)*1000/dyeingspeed); + lInterSegmentLength-=(lInterSegmentLength%100); //round to a 100 multiplication + InterSegmentStepsCount = 0; + DispenserPreSegmentControlId = AddControlCallback( IDSPreSegmentStateCallbackRunner, 100,TemplateDataReadCBFunction ,0, 0, 0 ); + if (DispenserPreSegmentControlId == 0xFF) + { + Report("Add control callback failed",__FILE__,__LINE__,(int)100,RpWarning,(int)0,0); + return ERROR; + } + Report("Add control callback ",__FILE__,__LINE__,(int)100,RpWarning,(int)IntersegmentLength,0); + if (EnableCleaning == true) + { + InterSegmentStartSprayCleaner = 500; + InterSegmentStartRocking = 1000; + InterSegmentCenterRockers = 3000; + } + InterSegmentStartWFCFDispensers = lInterSegmentLength-1500; + } } - if (Segment->brushstops[JobBrushStopId]->n_dispensers) + if (uploadstrategy == JOB_UPLOAD_STRATEGY__Default) { + Dispensers = Segment->brushstops[JobBrushStopId]->dispensers; n_dispensers = Segment->brushstops[JobBrushStopId]->n_dispensers; + } + else + { + if (BrushStopControlId != 0xFF) + { + RemoveControlCallback(BrushStopControlId,IDSBrushStopRestartCallback); + BrushStopControlId = 0xFF; + } + FileBrushStop = GetNextBrushStopFromJobFile(); + if (FileBrushStop) + { + REPORT_MSG(FileBrushStop->index,"BrushStopRead Index"); + Dispensers = FileBrushStop->dispensers; + n_dispensers = FileBrushStop->n_dispensers; + } + else + { + LOG_ERROR(FileBrushStop,"BrushStopReadError"); + JobEndReason = JOB_OUT_OF_DYE; + SegmentReady(Module_IDS,ModuleFail); + } + } + if (n_dispensers) + { for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++) { - DispenserId = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->index; - HW_Motor_Id = DispenserIdToMotorId[DispenserId]; - if (MotorsCfg[HW_Motor_Id].hardwaremotortype != DispenserIdToMotorId[DispenserId])//unconfigured dispenser - { - REPORT_MSG(DispenserId,"Dispenser PreSegment not configured"); - continue; - } + DispenserId = Dispensers[Dispenser_i]->index; DispenserPreSegmentReady[DispenserId] = false; } for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++) { - DispenserId = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->index; + DispenserId = Dispensers[Dispenser_i]->index; HW_Motor_Id = DispenserIdToMotorId[DispenserId]; if (MotorsCfg[HW_Motor_Id].hardwaremotortype != DispenserIdToMotorId[DispenserId])//unconfigured dispenser { REPORT_MSG(DispenserId,"Dispenser PreSegment not configured"); + DispenserPreSegmentReady[DispenserId] = true; //27/03/19 check if job should be stopped continue; } REPORT_MSG(DispenserId,"IDS_Valve_Presegment start"); IDS_Dispenser_Set_Flow_Params(DispenserId,0,0); - if (Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision != DISPENSER_STEP_DIVISION__Auto) + if (Dispensers[Dispenser_i]->dispenserstepdivision != DISPENSER_STEP_DIVISION__Auto) { - MotorSetMicroStep(HW_Motor_Id, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision); + MotorSetMicroStep(HW_Motor_Id, Dispensers[Dispenser_i]->dispenserstepdivision); } else { MotorSetMicroStep(HW_Motor_Id, MotorsCfg[HW_Motor_Id].microstep); } + MotorStop(HW_Motor_Id,Hard_Hiz); //26/03/19 test without valves + CurrentDispenserSpeed[DispenserId] = 0; + IDS_Valve_PresegmentReady(DispenserId,0); //27/03/19 to be removed when the presegment handler will be added + //REPORT_MSG(DispenserId,"Dispenser stopped pre Segment"); + } + } - if (Segment->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond==0) + return OK; +} +//******************************************************************************************************************** + + char IdsMessage[100]; +uint32_t SegmentNumOfBrushStops = 0; +double BrushStopTime = 0; + +void IDS_StartBrushStop(int n_dispensers, JobDispenser** Dispensers) +{ + int Dispenser_i,DispenserId; + TimerMotors_t HW_Motor_Id; + double segmentfirst_speed; + Report("IDS_StartBrushStop",__FILE__,__LINE__,(int)JobBrushStopId,RpWarning,(int)0,0); + + if (n_dispensers) + { + for (Dispenser_i = 0; Dispenser_i < n_dispensers; Dispenser_i++) + { + DispenserId = Dispensers[Dispenser_i]->index; + HW_Motor_Id = DispenserIdToMotorId[DispenserId]; + if (MotorsCfg[HW_Motor_Id].hardwaremotortype + != DispenserIdToMotorId[DispenserId]) + continue; + + //(Speed*uStep*PPR)/((2*PI*Dispenser_Radius) + segmentfirst_speed = Dispensers[Dispenser_i]->nanolitterpersecond + / Dispensers[Dispenser_i]->nanoliterperpulse; + if (Dispensers[Dispenser_i]->dispenserstepdivision + != DISPENSER_STEP_DIVISION__Auto) { - MotorStop(HW_Motor_Id,Hard_Hiz); //26/03/19 test without valves - IDS_Valve_PresegmentReady(DispenserId,0); - //Control3WayValvesWithCallback ((Valves_t)DispenserId, MidTank_Dispenser, IDS_Valve_PresegmentValveReady); //direction: MidTank_Dispenser or Dispenser_Mixer - //IDS_Dispenser_Close_Valve_And_Stop_Motor(DispenserId,IDS_Valve_PresegmentValveReady); - REPORT_MSG(DispenserId,"Dispenser Not Used Next Segment"); + //MotorSetMicroStep(HW_Motor_Id, Dispensers[Dispenser_i]->dispenserstepdivision); + segmentfirst_speed /= + Dispensers[Dispenser_i]->dispenserstepdivision; //the dye supply is calculated based on a 1/8 microstep + IDS_Dispenser_Set_Flow_Params( + DispenserId, Dispensers[Dispenser_i]->nanoliterperpulse, + Dispensers[Dispenser_i]->dispenserstepdivision); } else { - if (IntersegmentLength&&(SegmentId>0)) //there is an intersegment, stop all the dispensers. otherwise stop only dispensers that are not in use in the next segment. - { - //Control3WayValvesWithCallback ((Valves_t)DispenserId, MidTank_Dispenser, IDS_Valve_PresegmentValveReady); //direction: MidTank_Dispenser or Dispenser_Mixer - MotorStop(HW_Motor_Id,Hard_Hiz); //26/03/19 test without valves - IDS_Valve_PresegmentReady(DispenserId,0); - //IDS_Dispenser_Close_Valve_And_Stop_Motor(DispenserId,IDS_Valve_PresegmentValveReady); - REPORT_MSG(DispenserId,"Dispenser Used Next Segment with intersegment"); - } - else - { - IDS_Valve_PresegmentReady(DispenserId,0); - } - REPORT_MSG(DispenserId,"Dispenser is Used Next Segment"); + //segmentfirst_speed/=MotorsCfg[HW_Motor_Id].microstep; //the dye supply is calculated based on a 1/8 microstep + IDS_Dispenser_Set_Flow_Params( + DispenserId, Dispensers[Dispenser_i]->nanoliterperpulse, + MotorsCfg[HW_Motor_Id].microstep); + } + if ((int) segmentfirst_speed > 0) + { + DispenserSegmentReady[DispenserId] = false; + //Control3WayValvesWithCallback (DispenserId, Dispenser_Mixer, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer + IDS_Dispenser_Start_Motor_and_Open_Valve(DispenserId, + segmentfirst_speed, + NULL); + usnprintf(IdsMessage, 80, + "Dispenser %d nl/sec %d nl/pulse %d speed %d", + DispenserId, + (int) Dispensers[Dispenser_i]->nanolitterpersecond, + (int) Dispensers[Dispenser_i]->nanoliterperpulse, + (int) segmentfirst_speed); + //REPORT_MSG(segmentfirst_speed,IdsMessage); + Report(IdsMessage, __FILE__, __LINE__, Dispenser_i, RpWarning, segmentfirst_speed, 0); + SendJobProgress(0.0, 0, false, IdsMessage); } } } +} +uint32_t IDSBrushStopRestartCallback(uint32_t IfIndex, uint32_t readValue) +{ + JobDispenser **Dispensers = NULL; + int n_dispensers = 0; + JobSegment* Segment = (void *)IfIndex; + if (uploadstrategy == JOB_UPLOAD_STRATEGY__Default) + { + Dispensers = Segment->brushstops[JobBrushStopId]->dispensers; + n_dispensers = Segment->brushstops[JobBrushStopId]->n_dispensers; + } + else + { + if (FileBrushStop) + FreeBrushStopFileData(FileBrushStop); + FileBrushStop = GetNextBrushStopFromJobFile(); + if (FileBrushStop) + { + REPORT_MSG(FileBrushStop->index,"BrushStopRead Index"); + Dispensers = FileBrushStop->dispensers; + n_dispensers = FileBrushStop->n_dispensers; + } + else + { + LOG_ERROR(FileBrushStop,"BrushStopReadError"); + JobEndReason = JOB_OUT_OF_DYE; + SegmentReady(Module_IDS,ModuleFail); + } + } + if (n_dispensers) + { + IDS_StartBrushStop(n_dispensers, Dispensers); + } + JobBrushStopId++; + Report("brushstop",__FILE__,__LINE__,(int)JobBrushStopId,RpWarning,(int)SegmentNumOfBrushStops,0); + if (JobBrushStopId >= SegmentNumOfBrushStops) + { + Report("last brushstop",__FILE__,__LINE__,(int)JobBrushStopId,RpWarning,(int)SegmentNumOfBrushStops,0); + SafeRemoveControlCallback(BrushStopControlId,IDSBrushStopRestartCallback); + BrushStopControlId = 0Xff; + } return OK; } //******************************************************************************************************************** - - uint32_t IDS_Valve_SegmentReady(uint32_t deviceID, uint32_t ReadValue) - { - int i; - DispenserSegmentReady[deviceID] = true; - for (i=0;i<MAX_SYSTEM_DISPENSERS;i++) - { - if (DispenserSegmentReady[i] == false) - { - return OK; //not all configured heaters are ready - } - } - SegmentReady(Module_IDS,ModuleDone); - return OK; // all configured heaters are ready - } - - char IdsMessage[100]; -//******************************************************************************************************************** uint32_t IDSSegmentState(void *SegmentDetails, int SegmentId) { JobSegment* Segment = SegmentDetails; - int Dispenser_i,n_dispensers,DispenserId; - TimerMotors_t HW_Motor_Id; - double segmentfirst_speed; + JobDispenser **Dispensers; + int n_dispensers; Valve_Set(VALVE_MIXCHIP_WASTECH, Mixer_Head); - if (Segment->brushstops[JobBrushStopId]->n_dispensers) + + SegmentNumOfBrushStops = Segment->n_brushstops; + BrushStopTime = Segment->length/SegmentNumOfBrushStops; //brushstop in meters + BrushStopTime = ((BrushStopTime*100)/dyeingspeed);//brushstop in seconds + BrushStopTime *= 1000; //brushstop in millisecond + Report("IDSSegmentState",__FILE__,__LINE__,(int)BrushStopTime,RpWarning,(int)SegmentNumOfBrushStops,0); + if (uploadstrategy == JOB_UPLOAD_STRATEGY__Default) { + Dispensers = Segment->brushstops[JobBrushStopId]->dispensers; n_dispensers = Segment->brushstops[JobBrushStopId]->n_dispensers; - for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++) + } + else + { + if (FileBrushStop) { - DispenserId = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->index; - HW_Motor_Id = DispenserIdToMotorId[DispenserId]; - if (MotorsCfg[HW_Motor_Id].hardwaremotortype != DispenserIdToMotorId[DispenserId])//unconfigured dispenser - continue; - //(Speed*uStep*PPR)/((2*PI*Dispenser_Radius) - segmentfirst_speed = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanolitterpersecond/ - Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse; - if (Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision != DISPENSER_STEP_DIVISION__Auto) - { - //MotorSetMicroStep(HW_Motor_Id, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision); - segmentfirst_speed/=Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision; //the dye supply is calculated based on a 1/8 microstep - IDS_Dispenser_Set_Flow_Params ( DispenserId, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse - , Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision); - } - else - { - //segmentfirst_speed/=MotorsCfg[HW_Motor_Id].microstep; //the dye supply is calculated based on a 1/8 microstep - IDS_Dispenser_Set_Flow_Params ( DispenserId, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse - ,MotorsCfg[HW_Motor_Id].microstep); - } - if ((int)segmentfirst_speed > 0) - { - DispenserSegmentReady[DispenserId] = false; - //Control3WayValvesWithCallback (DispenserId, Dispenser_Mixer, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer - IDS_Dispenser_Start_Motor_and_Open_Valve(DispenserId,segmentfirst_speed,NULL); - usnprintf(IdsMessage, 80, "Dispenser %d nl/sec %d nl/pulse %d speed %d",Dispenser_i,(int)Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanolitterpersecond, - (int)Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse,(int)segmentfirst_speed); - //REPORT_MSG(segmentfirst_speed,IdsMessage); - Report(IdsMessage,__FILE__,__LINE__,Dispenser_i,RpWarning,segmentfirst_speed,0); - SendJobProgress(0.0,0,false, IdsMessage); - - - } + Dispensers = FileBrushStop->dispensers; + n_dispensers = FileBrushStop->n_dispensers; + } + else + { + LOG_ERROR(FileBrushStop,"BrushStopReadError"); } } + IDS_StartBrushStop(n_dispensers, Dispensers); + JobBrushStopId++; + if ((BrushStopTime)&&(SegmentNumOfBrushStops > 1)) + { + BrushStopControlId = AddControlCallback( IDSBrushStopRestartCallback, BrushStopTime,TemplateDataReadCBFunction ,SegmentDetails, 0, 0 ); + if (BrushStopControlId == 0xFF) + { + Report("Add control callback failed",__FILE__,__LINE__,(int)BrushStopTime,RpWarning,(int)0,0); + return ERROR; + } + Report("Add control callback ",__FILE__,__LINE__,(int)BrushStopTime,RpWarning,(int)n_dispensers,0); + + } + else + { + if (FileBrushStop) + FreeBrushStopFileData(FileBrushStop); + FileBrushStop = NULL; + } + return OK; } //******************************************************************************************************************** @@ -513,6 +889,7 @@ uint32_t IDSSegmentState(void *SegmentDetails, int SegmentId) return OK; //not all configured heaters are ready } } + REPORT_MSG(deviceID,"IDS_Valve_DistanceToSpoolReady End called"); DistanceToSpoolReady(Module_IDS,ModuleDone); return OK; // all configured heaters are ready } @@ -551,6 +928,14 @@ uint32_t IDSSegmentState(void *SegmentDetails, int SegmentId) IDS_Active = false; Valve_Set(VALVE_MIXCHIP_WASTECH, Mixer_Waste); REPORT_MSG(0,"Dispenser End Start"); + if (BrushStopControlId != 0xFF) + { + RemoveControlCallback(BrushStopControlId,IDSBrushStopRestartCallback); + BrushStopControlId = 0xFF; + } + if (FileBrushStop) + FreeBrushStopFileData(FileBrushStop); + FileBrushStop = NULL; for ( Dispenser_i = 0;Dispenser_i < MAX_SYSTEM_DISPENSERS;Dispenser_i++) { if (DispenserUsedInJob[Dispenser_i] == true) diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_Winder.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_Winder.c index d8564963c..1f7836ea5 100644 --- a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_Winder.c +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_Winder.c @@ -288,7 +288,7 @@ uint32_t Screw100msecDirectionChange(uint32_t deviceID, uint32_t BusyFlag) //Report(TempScrewStr,__FILE__,__LINE__,0,RpWarning,0, 0); //Report(ScrewStr,__FILE__,__LINE__,ScrewCurrentDirection,RpWarning,CalculationDirectionChangeCounter, 0); //REPORT_MSG(temp , "new winder speed"); - Report("new winder speed",__FILE__,ScrewNumberOfSteps,temp,RpWarning,ScrewSpeed,0); +// Report("new winder speed",__FILE__,ScrewNumberOfSteps,temp,RpWarning,ScrewSpeed,0); } /********************************************************************************/ @@ -382,8 +382,8 @@ uint32_t Winder_End(void) CurrentControlledSpeed[SCREW_MOTOR] = 0; ScrewsStopControlTimer(); //move the cart to the edge so the spool can be easily replaced - MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_SCREW,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_SCREW].directionthreadwize, 1000, GPI_LS_SCREW_RIGHT, NULL,0); - + //MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_SCREW,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_SCREW].directionthreadwize, 1000, GPI_LS_SCREW_RIGHT, NULL,0); + MotorStop(HARDWARE_MOTOR_TYPE__MOTO_SCREW,Hard_Hiz); return OK; } void Winder_ScrewHomeLimitSwitchInterrupt(void) diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c index 9f5ece15a..07a32b2a6 100644 --- a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c @@ -83,6 +83,11 @@ void ThreadInterSegmentEnded(void); void ThreadDistanceToSpoolEnded(void); uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue); +bool SegmentState = false; +bool PreSegmentState = false; +bool DTSState = false; +void SendSegmentFail(void); + double KeepNormalizedError = 0; bool ThreadControlActive = false; ////////////////////////Slow Motor State//////////////////////////////////// @@ -128,6 +133,7 @@ uint32_t Poolerinitialpos = 0xFFFF; void ThreadUpdateProcessLength (double length, void *Funcptr) { + REPORT_MSG(length,"ThreadUpdateProcessLength"); CurrentRequestedLength = length*100;//Centimetres CurrentProcessedLength = 0; ProcessedLengthFuncPtr = (ProcessedLengthFunc)Funcptr; @@ -436,7 +442,7 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue) JobEndReason = JOB_THREAD_BREAK; ThreadControlActive = false; SendJobProgress(0.0,0,false, TMessage); - SegmentReady(Module_Thread,ModuleFail); + SendSegmentFail(); //AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_BREAK,true); //EndState(CurrentJob,"ReadBreakSensor Error" ); LOG_ERROR(index, "ReadBreakSensor Error"); @@ -466,7 +472,7 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue) JobEndReason = JOB_WINDER_DANCER_FAIL+DancerId; SendJobProgress(0.0,0,false, TMessage); //EndState(CurrentJob,TMessage ); - SegmentReady(Module_Thread,ModuleFail); + SendSegmentFail(); /*switch (index) { case POOLER_MOTOR: @@ -750,10 +756,13 @@ uint32_t ThreadPreSegmentState(void *SegmentDetails, uint32_t SegmentId) //set speed for both rocker motors //wait for all motors to get to the required speed (set the target speed for the control to check) //call the job state machine when the thread system is ready - if ((InitialProcess==false) && (EnableIntersegment == true) && (IntersegmentLength >= 1.0)) //fix - avoid intersegment length 0 + if ((InitialProcess==false) && (EnableIntersegment == true)) //&& (IntersegmentLength >= 1.0)) //fix - avoid intersegment length 0 {//add initial presegment and cleaning before first segment ThreadUpdateProcessLength (IntersegmentLength,(void *)ThreadInterSegmentEnded); REPORT_MSG (IntersegmentLength," ThreadPreSegmentState IntersegmentLength"); + SegmentState = false; + PreSegmentState = true; + DTSState = false; } else { @@ -766,6 +775,17 @@ uint32_t ThreadPreSegmentState(void *SegmentDetails, uint32_t SegmentId) return OK; } int REPSegmentId = 0; +void SendSegmentFail(void) +{ + if (SegmentState == true) + SegmentReady(Module_Thread,ModuleFail); + else if (PreSegmentState == true) + PreSegmentReady(Module_Thread,ModuleFail); + else if (DTSState == true) + DistanceToSpoolReady(Module_Thread,ModuleFail); + +} + void ThreadInterSegmentEnded(void) { REPORT_MSG (REPSegmentId,"ThreadInterSegmentEnded"); @@ -792,6 +812,9 @@ uint32_t ThreadSegmentState(void *SegmentDetails, int SegmentId) CurrentSegmentId = SegmentId; REPORT_MSG (seglength," ThreadSegmentState"); ThreadUpdateProcessLength (seglength,(void *)ThreadSegmentEnded); + SegmentState = true; + PreSegmentState = false; + DTSState = false; return OK; } @@ -801,6 +824,9 @@ uint32_t ThreadDistanceToSpoolState(void ) seglength = dryerbufferlength; REPORT_MSG (seglength,"ThreadDistanceToSpoolState"); ThreadUpdateProcessLength (seglength,(void *)ThreadDistanceToSpoolEnded); + SegmentState = false; + PreSegmentState = false; + DTSState = true; return OK; } @@ -816,6 +842,7 @@ char Endstr[150]; Report(Endstr,__FILE__,__LINE__,(int)TotalProcessedLength,RpWarning,(int)PoolerTotalProcessedLength,0); ThreadUpdateProcessLength (0.0,(void *)NULL); + TotalProcessedLength = 0.0; SetOriginMotorSpeed(0); #ifdef HUNDRED_MICROSECONDS_DANCER_READ MillisecLogClose(); diff --git a/Software/Embedded_SW/Embedded/Software Release Notes.txt b/Software/Embedded_SW/Embedded/Software Release Notes.txt index 356301dda..d62cee15e 100644 --- a/Software/Embedded_SW/Embedded/Software Release Notes.txt +++ b/Software/Embedded_SW/Embedded/Software Release Notes.txt @@ -1,3 +1,11 @@ +Embedded SW Release note - Version 1.3.8.2 +File upload: prevent on job, reduce priority (watchdog) +Report: packages filters introduced, please feel free to use them. +robustness in communication improved +large number of segments and gradient support - initial +at the end of job the screw does not return back +rockers - adjust values before and after loading the cart + Embedded SW Release note - Version 1.3.8.12 Prepare continous response on sw upgarde - test! Lubrication supported throughout the job - test! diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c index 69361bbae..972f79939 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c @@ -37,6 +37,7 @@ #include "PMR/Printing/CurrentJobResponse.pb-c.h" #include "PMR/Printing/ResumeCurrentJobRequest.pb-c.h" #include "PMR/Printing/ResumeCurrentJobResponse.pb-c.h" +#include "PMR/Printing/JobUploadStrategy.pb-c.h" #include "PMR/Printing/JobStatus.pb-c.h" #include "PMR/Printing/AbortJobRequest.pb-c.h" #include "PMR/Printing/AbortJobResponse.pb-c.h" @@ -88,7 +89,7 @@ JobSegment *TSegment; JobSpool *Tspool; bool CopyConfigured[MAX_SYSTEM_MODULES]; char ErrorMsg[100]; - +JobUploadStrategy uploadstrategy = JOB_UPLOAD_STRATEGY__Default; ModuleStateEnum PrepareWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle}; @@ -377,6 +378,7 @@ uint32_t ThreadJoggingFunc(int speed) { //load essential job prameters to enable thread running Ticket.n_segments = 1; + n_segments = 1; Ticket.segments = my_malloc(sizeof(Ticket.segments)); TSegment = my_malloc(sizeof(JobSegment)); Tspool = my_malloc(sizeof(JobSpool)); @@ -587,7 +589,7 @@ void JobRequestFunc(MessageContainer* requestContainer) ErrorCode error = ERROR_CODE__NONE; JobEndReasonEnum JobAlarmReason = JOB_OK; - if (JobActive == false) + if (JobActive == true) { LOG_ERROR(JobActive, "Job started while active"); } @@ -612,7 +614,17 @@ void JobRequestFunc(MessageContainer* requestContainer) if (CurrentRequest!= NULL) job_request__free_unpacked(CurrentRequest,NULL); CurrentRequest = request; - + n_segments = 0; + if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + LOG_ERROR(JobActive, "Job upload strategy file"); + uploadstrategy = JOB_UPLOAD_STRATEGY__JobDescriptionFile; + } + else + { + uploadstrategy = JOB_UPLOAD_STRATEGY__Default; + n_segments = CurrentJob->n_segments; + } status = PASSED; JobEndReason = JOB_OK; JobAlarmReason = AlarmHandlingPrepareJob(CurrentJob); @@ -649,7 +661,8 @@ void JobRequestFunc(MessageContainer* requestContainer) } if (status == PASSED) { - Report("Job Request ",__FILE__,__LINE__,Ticket->processparameters->dyeingspeed,RpWarning,Ticket->n_segments, Ticket->intersegmentlength); + Report("Job Request ",__FILE__,__LINE__,Ticket->processparameters->dyeingspeed,RpWarning,n_segments, Ticket->intersegmentlength); + OpenJobFile(); StartJob(CurrentJob); } } diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c index 53057c170..c52ed8b4c 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c @@ -25,6 +25,10 @@ #include "PMR/Hardware/UploadHardWareConfigurationRequest.pb-c.h" #include "PMR/Hardware/HardwareMotorType.pb-c.h" #include "modules/General/process.h" +#include "PMR/Printing/JobDescriptionFileBrushStop.pb-c.h" +#include "PMR/Printing/JobDescriptionFileSegment.pb-c.h" +#include "Common/SWUpdate/FileSystem.h" +#include "drivers/Flash_Memory/fatfs/ff.h" ////////////////////////////////State machine operation//////////////////////////////////// //the state machine operation is used to operate in runtime correct profile flow execution //by recieved esign flow of the user from the UI @@ -38,7 +42,7 @@ static uint32_t PreSegmentState(void *Segment, int); static uint32_t SegmentState(void *Segment, int); uint32_t EndState(void *JobDetails, char *Message); //static uint32_t ExitState(void *JobDetails); - +uint16_t n_segments = 0; /********************************************************************** * the array and enum of PrintingState_t below must be in sync order ***********************************************************************/ @@ -65,9 +69,174 @@ ModuleStateEnum EndWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle,ModuleIdle,M bool Configured[MAX_SYSTEM_MODULES] = {false,false,false,false,false}; bool SuspendLargeMessages = false; +/* +Parsing the job description file. +The job description file simply contains an array of segments and their brush stops. +The job description file is meant to be read brush stop by brush stop while the job is in progress. +The following diagram represents a single job description file segment structure. +The process of reading the whole file is simply repeating that reading order. -/******************************************************************************************************************** - * this function is for development initial stages. it analyses the hardware configuration to determine which modules are operational +Each JobDescriptionFileSegment contains a “BrushStopsCount” field that should be used to determine how many brush stops are associated +with the current segment and how many times the process of reading brush stops should be repeated. +1. 32bit integer containing the next JobFileDescriptionSegment message byte count +2. JobDescriptionFileSegment message +3. 32bit integer containing the next JobDescriptionFileBrushStop message byte count +4. JobDescriptionFileBrushStop message + +1. Read segment message length. +2. Read segment message. +a. Read brush stop message length. +b. Read brush stop message. +c. Go to step 2.a x Segment.BrushStopsCount. +3. Go to step 1 until end of file. +*/ + +//job file reading functions +uint32_t bBytes = 0,readbBytes = 0,ImmediateRead = 0,SegmentSize = 0,BrushStopSize = 0; +FRESULT Fresult = FR_OK; +uint8_t *SegmentPtr = 0, *BrushStopPtr = 0; +FIL *JobRequestFileHandle = 0; //the system supports a single active file +FRESULT OpenJobFile() +{ + //n_segments = 0; + if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + JobRequestFileHandle = my_malloc(sizeof(FIL)); + + Fresult = FileOpen(CurrentJob->jobdescriptionfile, &bBytes, JobRequestFileHandle); + if (Fresult == FR_OK) + { + readbBytes = 0; + } + REPORT_MSG(bBytes,"OpenJobFile"); + } + return Fresult; +} +FRESULT CloseJobFile() +{ + Fresult = f_close(JobRequestFileHandle); + readbBytes = 0; + ImmediateRead = 0; + SegmentSize = 0; + BrushStopSize = 0; + my_free (JobRequestFileHandle); + JobRequestFileHandle = NULL; + if (BrushStopPtr) + my_free(BrushStopPtr); + if (SegmentPtr) + my_free(SegmentPtr); + REPORT_MSG(Fresult,"CloseJobFile"); + + return Fresult; +} +JobDescriptionFileSegment *GetNextSegmentFromJobFile() +{ + uint32_t status = OK; + JobDescriptionFileSegment *Segment = NULL; + if (JobRequestFileHandle == NULL) + { + LOG_ERROR(JobRequestFileHandle,"JobRequestFileHandle == NULL"); + return NULL; + } + if(readbBytes < bBytes) + { + Fresult = f_read(JobRequestFileHandle,&SegmentSize,4,&ImmediateRead ); + if (Fresult == FR_OK) + { + readbBytes += ImmediateRead; + if (SegmentPtr) + my_free(SegmentPtr); + SegmentPtr = my_malloc (SegmentSize); + if (SegmentPtr) + { + Fresult = f_read(JobRequestFileHandle,SegmentPtr,SegmentSize,&ImmediateRead ); + if (Fresult == FR_OK) + { + readbBytes += ImmediateRead; + //n_segments++; + Segment = job_description_file_segment__unpack(NULL, SegmentSize, SegmentPtr); + } + }// read segment data + my_free(SegmentPtr); + }//segment malloc + else + { + LOG_ERROR (SegmentPtr, "malloc error"); + status = ERROR; + } + }//segment read size + else + { + LOG_ERROR (Fresult, "f_read error"); + status = ERROR; + } + return Segment; +} +void FreeSegmentFileData(JobDescriptionFileSegment *Segment) +{ + job_description_file_segment__free_unpacked(Segment,NULL); + Segment = NULL; + if (SegmentPtr) + my_free(SegmentPtr); +} +JobDescriptionFileBrushStop *GetNextBrushStopFromJobFile() +{ + uint32_t status = OK; + JobDescriptionFileBrushStop *BrushStop = NULL; + if (JobRequestFileHandle == NULL) + { + LOG_ERROR(JobRequestFileHandle,"JobRequestFileHandle == NULL"); + return NULL; + } + Fresult = f_read(JobRequestFileHandle,&BrushStopSize,4,&ImmediateRead ); + if (Fresult == FR_OK) + { + readbBytes += ImmediateRead; + if (BrushStopPtr) + my_free(BrushStopPtr); + + BrushStopPtr = my_malloc (BrushStopSize); + if (BrushStopPtr) + { + Fresult = f_read(JobRequestFileHandle,BrushStopPtr,BrushStopSize,&ImmediateRead ); + if (Fresult == FR_OK) + { + readbBytes += ImmediateRead; + BrushStop = job_description_file_brush_stop__unpack(NULL, BrushStopSize, BrushStopPtr); + }//brushstop malloc ok + else + { + LOG_ERROR (Fresult, "f_read error"); + status = ERROR; + } + my_free(BrushStopPtr); + }//brushstop size read ok + else + { + LOG_ERROR (BrushStopPtr, "malloc error"); + status = ERROR; + } + }// if brush stop count + else + { + LOG_ERROR (0, "f_read error brush stop size error"); + status = ERROR; + } + REPORT_MSG(BrushStop->index,"BrushStop file Read Index"); + + return BrushStop; +} +void FreeBrushStopFileData(JobDescriptionFileBrushStop *BrushStop) +{ + REPORT_MSG(BrushStop->index,"Free BrushStop file Read Index"); + if (BrushStop) + job_description_file_brush_stop__free_unpacked (BrushStop,NULL); + BrushStop = NULL; + if (BrushStopPtr) + my_free(BrushStopPtr); +} +/************************************************************************************************************************************/ +/* this function is for development initial stages. it analyses the hardware configuration to determine which modules are operational * according to the configuration map */ @@ -233,8 +402,8 @@ uint32_t SegmentReady(int ModuleId, ModuleStateEnum result) assert (ModuleId<MAX_SYSTEM_MODULES); assert (result<=ModuleFail); - REPORT_MSG (ModuleId, "SegmentReady"); - Report("IDSSegmentState",__FILE__,__LINE__,(int)ModuleId,RpWarning,(int)result,0); + //REPORT_MSG (ModuleId, "SegmentReady"); + Report("SegmentReady",__FILE__,__LINE__,(int)ModuleId,RpWarning,(int)result,0); if (SegmentWaiting[ModuleId] != ModuleWaiting) { @@ -410,6 +579,7 @@ uint32_t EndState(void *JobDetails, char *Message) //EndWaiting[Module_Thread] = ModuleWaiting; ThreadEndState(); } + CloseJobFile(); //ROM_IntMasterEnable(); SendJobProgress(0.0,0,true,Message); @@ -436,16 +606,18 @@ void StartPrinting(void) //******************************************************************************************************************** //******************************************************************************************************************** -void StopPrinting(void) -{ -} int SegmentId = 0; +JobDescriptionFileSegment *Segment; +JobSegment SSegment; + +//******************************************************************************************************************** +//******************************************************************************************************************** void PrintSTMMsgHandler(void * msg) { JobMessageStruc *Message = msg; PrintMessageStruc *PrtMessage = (PrintMessageStruc *)Message->messageData; - Report("PrintSTMMsgHandler",__FILE__,__LINE__, RpMessage,0x1000,Message->messageId,PrtMessage->messageId); + Report("PrintSTMMsgHandler",__FILE__,__LINE__, 1000,RpMessage,Message->messageId,PrtMessage->messageId); if ((Message->messageId != PrintMessage)&&(Message->messageId != Abort)) { @@ -456,10 +628,28 @@ void PrintSTMMsgHandler(void * msg) { case PrintRequest: SegmentId = 0; - PreSegmentState(CurrentJob->segments[SegmentId],SegmentId); + if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + Segment = GetNextSegmentFromJobFile(); + SSegment.length = Segment->length; + SSegment.has_length = Segment->has_length; + SSegment.n_brushstops = Segment->brushstopscount; + PreSegmentState(&SSegment,SegmentId); + } + else + { + PreSegmentState(CurrentJob->segments[SegmentId],SegmentId); + } break; case PreSegmentResultsOk: - SegmentState(CurrentJob->segments[SegmentId],SegmentId); + if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + SegmentState(&SSegment,SegmentId); + } + else + { + SegmentState(CurrentJob->segments[SegmentId],SegmentId); + } break; case PreSegmentResultsFail: EndState(CurrentJob, "PreSegment Failed"); @@ -467,8 +657,9 @@ void PrintSTMMsgHandler(void * msg) break; case SegmentResultsOk: SegmentId++; - LOG_ERROR(SegmentId, "SegmentResultsOk segmentId"); - if (SegmentId >= CurrentJob->n_segments) + //REPORT_MSG(SegmentId, "SegmentResultsOk segmentId"); + Report("SegmentResultsOk segmentId",__FILE__,__LINE__, SegmentId,RpMessage,n_segments,0); + if (SegmentId >= n_segments) { if (dryerbufferlength == 0) EndState(CurrentJob, "Job Ended"); @@ -477,7 +668,21 @@ void PrintSTMMsgHandler(void * msg) } else { - PreSegmentState(CurrentJob->segments[SegmentId],SegmentId); + if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + if (Segment) + FreeSegmentFileData(Segment); + + Segment = GetNextSegmentFromJobFile(); + SSegment.length = Segment->length; + SSegment.has_length = Segment->has_length; + SSegment.n_brushstops = Segment->brushstopscount; + PreSegmentState(&SSegment,SegmentId); + } + else + { + PreSegmentState(CurrentJob->segments[SegmentId],SegmentId); + } } break; case SegmentResultsFail: diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h index 878e063b5..d7d8262f4 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h @@ -17,6 +17,9 @@ #include "PMR/Printing/JobRequest.pb-c.h" #include "PMR/Printing/JobTicket.pb-c.h" #include "PMR/Printing/JobResponse.pb-c.h" +#include "PMR/Printing/JobDescriptionFileBrushStop.pb-c.h" +#include "PMR/Printing/JobDescriptionFileSegment.pb-c.h" +#include "drivers/Flash_Memory/fatfs/ff.h" #define MAX_MSG_LEN 100 typedef enum @@ -166,8 +169,10 @@ uint32_t CurrentJobRequestFunc(MessageContainer* requestContainer); uint32_t ResumeCurrentJobRequestFunc(MessageContainer* requestContainer); bool JobIsActive(void); + extern bool SuspendLargeMessages; +extern uint16_t n_segments; void SendJobProgress(double ProcessedLength,int SegmentId, bool done, char *Message); uint32_t PrepareReady(int ModuleId, ModuleStateEnum result); @@ -179,4 +184,12 @@ uint32_t EndState(void *JobDetails, char *Message); bool GetHeatersPrepareWaiting(void); +extern JobUploadStrategy uploadstrategy; +FRESULT OpenJobFile(); +FRESULT CloseJobFile(); +JobDescriptionFileSegment *GetNextSegmentFromJobFile(); +void FreeSegmentFileData(JobDescriptionFileSegment *Segment); +JobDescriptionFileBrushStop *GetNextBrushStopFromJobFile(); +void FreeBrushStopFileData(JobDescriptionFileBrushStop *BrushStop); + #endif /* STATEMACHINES_PRINTSTM_H_ */ |
