#ifndef SDP_SCHEDULER_UTILS_H #define SDP_SCHEDULER_UTILS_H // Все зоны линии enum Zones { ZONE_LOAD_1 = 0, // загрузка 0, используется как точка появления барабанов ZONE_LOAD_2, // загрузка 1, используется как конечная точка барабанов ZONE_DEGREASING, // обезжиривание ZONE_WASHING_1A, // промывка 1А ZONE_WASHING_1B, // промывка 1Б ZONE_ETCHING_1, // травление 1 ZONE_ETCHING_2, // травление 2 ZONE_WASHING_2A, // промывка 2А ZONE_WASHING_2B, // промывка 2Б ZONE_GALVANIZING_1, // цинкование 1 ZONE_GALVANIZING_2, // цинкование 2 ZONE_GALVANIZING_3, // цинкование 3 ZONE_GALVANIZING_4, // цинкование 4 ZONE_GALVANIZING_5, // цинкование 5 ZONE_GALVANIZING_6, // цинкование 6 ZONE_GALVANIZING_7, // цинкование 7 ZONE_GALVANIZING_8, // цинкование 8 ZONE_WASHING_3A, // промывка 3А ZONE_WASHING_3B, // промывка 3Б ZONE_PASSIVATION, // пассивация ZONE_WASHING_4A, // промывка 4A ZONE_WASHING_4B, // промывка 4Б ZONE_UNLOAD, // зона выгрузки }; #define BARRELS_COUNT 10 union barrel_flags { short raw_word; struct { char is_exist: 1; char is_up: 1; // для панели char robot: 2; // обслуживающий робот char is_night: 1; // ночной барабан, имеет такой статус если он в промывке в ночном режиме или в промывке, // но пока не дождался очереди на выход из ночного режима char is_empty: 1; // пустой барабан, нужен для работы операции возврата }; }; struct barrel { union barrel_flags flags; short zone; // программный таймер, тикает сразу у всех барабанов, short software_timer; // время процессов short time_degreasing; // Время обезжиривания short time_washing_1a; // Время промывки 1А short time_washing_1b; // Время промывки 1Б short time_etching; // Время травления short time_washing_2a; // Время промывки 2А short time_washing_2b; // Время промывки 2Б short time_galvanizing; // Время цинкования short time_washing_3a; // Время промывки 3А short time_washing_3b; // Время промывки 3Б short time_passivation; // Время пассивации short time_washing_4a; // Время промывки 4А short time_washing_4b; // Время промывки 4Б }; union robot_regs_mx { short raw_word; struct { char correct_status: 1; char last_cmd_executed: 1; char correct_sensor: 1; char move_to_zone: 1; char move_to_offset: 1; char move_to_precise: 1; char do_correct: 1; char do_parking: 1; char hla_left: 1; char hla_right: 1; char auto_mode: 1; char error: 1; }; }; union robot_regs_dx { short raw_data[6]; struct { short current_zone; short target_zone; short left_max; short right_max; short output_current; short output_freq; }; }; union robot_regs_mz { short raw_word; struct { char correct_status: 1; char last_cmd_executed: 1; char is_up: 1; char move_up: 1; char move_down: 1; char do_correct: 1; char hla_up: 1; char hla_down: 1; char auto_mode: 1; char error: 1; }; }; union robot_regs_dz { short raw_data[3]; struct { short current_zone; short output_current; short output_freq; }; }; struct robot_regs { union robot_regs_mx mx; union robot_regs_dx dx; union robot_regs_mz mz; union robot_regs_dz dz; }; // NOTE первой командой на любую транзакцию должна стоять команда опустить траверсу (в 22 зоне по идее никогда не закончим) struct robot_code { short barrel_id; // нужен ID барабана, если short PC; // когда -1, код не выполняется /* * система команд, которая нужна: (квадратные скобки - аргумент это младшие 14 бит) * 0 (смещение: да () ? нет): установить смещение (да - встанет в смещенную позицию, нет - в точную) * 1 (опция с барабаном) [поднять (1) | опустить]: поднять/опустить траверсу (перед поднятием ожидать если таймер барабана не истек) * 2 (опция с барабаном) [зона]: съебаться в зону * 3 [сек]: пауза на нужное количество секунд * 4 [время]: установить таймер барабану * 5 (ETCH(1) | GAL (2)) [зона]: установить зону блокировки, умеет использовать автоинкримент зоны гальваники или обезжиривания * 6 [X(1) | Y(2)]: скорректировать ось * 15: конец * * формат команды: (команда, старший байт) [младший байт, аргумент команды (если есть)] [слово, аргумент если команда требует] */ short code[16]; // формат кода: [команды] <команда 0> }; #ifdef __cplusplus extern "C" { #endif #ifdef EMULATOR extern struct barrel barrels[BARRELS_COUNT]; extern struct robot_regs robot1; extern struct robot_regs robot2; extern struct robot_code robot1_code; extern struct robot_code robot2_code; #else #define barrels ((struct barrel*)&barrels_array) #define robot1 (*((struct robot_regs*)&robot1_reg_mx)) #define robot2 (*((struct robot_regs*)&robot2_reg_mx)) #define robot1_code (*((struct robot_code*)_robot1_code_struct)) #define robot2_code (*((struct robot_code*)_robot2_code_struct)) #endif // почему-то компилер говорит что размер структуру сраный //extern struct robot robot1; //extern struct robot robot2; // появилась идея сделать пачку short-команд, то есть вставлять не полный код операции, а код 0x7000 | код операции 0x0X00 #define ROBOT_CMD_MASK (short)0xF000 #define ROBOT_CMD_END_code (short)0x0000 #define ROBOT_CMD_MOVE_TO_ZONE_code (short)0x1000 #define ROBOT_CMD_MOVE_OFF_code (short)0x2000 #define ROBOT_CMD_MOVE_ACCURATE_code (short)0x3000 #define ROBOT_CMD_UP_code (short)0x4000 #define ROBOT_CMD_DOWN_code (short)0x5000 #define ROBOT_CMD_WAIT_code (short)0x6000 #define ROBOT_CMD_TMR_SET_code (short)0x7000 #define ROBOT_CMD_CORRECT_AXIS_code (short)0x9000 #define ROBOT_CMD_INC_ZONE_code (short)0xA000 // перемещение с барабаном #define ROBOT_WITH_BARREL 0x0800 // опции зон #define ROBOT_ZONE_ETCH 0x0400 #define ROBOT_ZONE_GAL 0x0200 #define ROBOT_ZONE_PARKING 0x0100 // опции коррекции осей #define ROBOT_AXIS_X 1 #define ROBOT_AXIS_Z 2 // макросы для генерации команд #define ROBOT_CMD_END() (ROBOT_CMD_END_code) #define ROBOT_CMD_MOVE_TO_ZONE(zone) ((ROBOT_CMD_MOVE_TO_ZONE_code) | (short)(zone & 0x00FF)) #define ROBOT_CMD_MOVE_TO_ZONE_WITH_BARREL(zone) ((ROBOT_CMD_MOVE_TO_ZONE_code) | (short)(ROBOT_WITH_BARREL) | (short)(zone & 0x00FF)) #define ROBOT_CMD_MOVE_TO_PARKING() ((short)(ROBOT_CMD_MOVE_TO_ZONE_code) | (short)(ROBOT_ZONE_PARKING)) #define ROBOT_CMD_MOVE_OFF() (ROBOT_CMD_MOVE_OFF_code) #define ROBOT_CMD_MOVE_ACCURATE() (ROBOT_CMD_MOVE_ACCURATE_code) #define ROBOT_CMD_UP() (ROBOT_CMD_UP_code) #define ROBOT_CMD_UP_WITH_BARREL() ((ROBOT_CMD_UP_code) | (short)(ROBOT_WITH_BARREL)) #define ROBOT_CMD_DOWN() (ROBOT_CMD_DOWN_code) #define ROBOT_CMD_DOWN_WITH_BARREL() ((ROBOT_CMD_DOWN_code) | (short)(ROBOT_WITH_BARREL)) #define ROBOT_CMD_WAIT(time) ((ROBOT_CMD_WAIT_code) | (short)(time & 0x0FFF)) #define ROBOT_CMD_TMR_SET(time) ((ROBOT_CMD_TMR_SET_code) | (short)(time & 0x0FFF)) #define ROBOT_CMD_CORRECT_AXIS(axis) ((short)(ROBOT_CMD_CORRECT_AXIS_code) | (short)axis) #define ROBOT_CMD_INC_ZONE(arg) ((ROBOT_CMD_INC_ZONE_code) | (short)(arg)) /* ======================== IO DEFS ======================== */ #define ROBOT1_X 1 #define ROBOT1_Z 2 #define ROBOT2_X 3 #define ROBOT2_Z 4 #define VFD_REG_D0_ADDR 4096 #define VFD_REG_M0_ADDR 2048 /* ======================== ROBOT DEFS ======================== */ #define MB_CMD_WRITE_FLAG 5 #define MB_CMD_WRITE_REG 6 #define VFD_REG_D0_ADDR 4096 #define VFD_REG_M0_ADDR 2048 // смещение регистров M относительно M0 #define ROBOT_Z_CORRECT_STATUS_OFFSET 0 #define ROBOT_Z_CMD_EXECUTED_OFFSET 1 #define ROBOT_Z_CMD_UP_OFFSET 3 #define ROBOT_Z_CMD_DOWN_OFFSET 4 #define ROBOT_Z_CMD_CORRECT_OFFSET 5 #define ROBOT_X_CORRECT_STATUS_OFFSET 0 #define ROBOT_X_CMD_EXECUTED_OFFSET 1 #define ROBOT_X_CORRECT_SENSOR_OFFSET 2 #define ROBOT_X_CMD_MOVE_TO_ZONE_OFFSET 3 #define ROBOT_X_CMD_MOVE_TO_OFF_POS_OFFSET 4 // встать в смещенную позицию #define ROBOT_X_CMD_MOVE_TO_COR_POS_OFFSET 5 // встать в точную позицию #define ROBOT_X_CMD_CORRECT_OFFSET 6 #define ROBOT_X_CMD_CMD_PARKING_OFFSET 7 // смещение регистров D относительно D0 #define ROBOT_X_TARGET_ZONE_OFFSET 2 // адреса регистров в частотнике #define ROBOT_Z_CORRECT_STATUS_ADDR VFD_REG_M0_ADDR #define ROBOT_Z_CMD_EXECUTED_ADDR (VFD_REG_M0_ADDR + 1) #define ROBOT_Z_CMD_UP_ADDR (VFD_REG_M0_ADDR + 3) #define ROBOT_Z_CMD_DOWN_ADDR (VFD_REG_M0_ADDR + 4) #define ROBOT_Z_CMD_CORRECT_ADDR (VFD_REG_M0_ADDR + 5) #define ROBOT_X_CORRECT_STATUS_ADDR VFD_REG_M0_ADDR #define ROBOT_X_CMD_EXECUTED_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_EXECUTED_OFFSET) #define ROBOT_X_CORRECT_SENSOR_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CORRECT_SENSOR_OFFSET) #define ROBOT_X_CMD_MOVE_TO_ZONE_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_MOVE_TO_ZONE_OFFSET) #define ROBOT_X_CMD_MOVE_TO_OFF_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_MOVE_TO_OFF_POS_OFFSET) #define ROBOT_X_CMD_MOVE_TO_COR_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_MOVE_TO_COR_POS_OFFSET) #define ROBOT_X_CMD_CORRECT_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_CORRECT_OFFSET) #define ROBOT_X_CMD_PARKING_ADDR (VFD_REG_M0_ADDR + ROBOT_X_CMD_CMD_PARKING_OFFSET) #define ROBOT_X_TARGET_ZONE_ADDR (VFD_REG_D0_ADDR + ROBOT_X_TARGET_ZONE_OFFSET) #ifdef __cplusplus } #endif #endif //SDP_SCHEDULER_UTILS_H