/*----------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------*/ static pwr_tStatus IoAgentClose ( io_tCtx ctx, io_sAgent *ap ) { io_sAgentLocal *local; T_PROFI_DEVICE_HANDLE *hDevice; pwr_tStatus sts = PB_FALSE; T_PROFI_SERVICE_DESCR sdb; USIGN8 con_ind_buffer [256]; USIGN16 con_ind_buffer_len = 256; T_PROFI_SERVICE_DESCR con_ind_sdb; INT16 result; /* !!! local result variable !!! */ local = (io_sAgentLocal *) ap->Local; if ( !local) return IO__SUCCESS; pthread_cancel(local->events); pthread_mutex_lock(&local->mutex); hDevice = (T_PROFI_DEVICE_HANDLE *) ap->Local; sdb.comm_ref = 0; sdb.layer = DP; sdb.service = DP_EXIT_MASTER; sdb.primitive = REQ; sdb.invoke_id = 0; sdb.result = 0; profi_snd_req_res(hDevice, &sdb, &sdb, PB_FALSE); try_profi_rcv_con_ind(hDevice, &con_ind_sdb, con_ind_buffer, &con_ind_buffer_len, &result); if ((con_ind_sdb.service == DP_EXIT_MASTER) && (con_ind_sdb.primitive == CON ) && (con_ind_sdb.result == POS )) { sts = PB_TRUE; } close(local->hServiceReadDevice); close(local->hServiceWriteDevice); close(local->hDpDataDevice); close(local->hDpsInputDataDevice); close(local->hDpsOutputDataDevice); close(local->hDpsBoardDevice); pthread_mutex_unlock(&local->mutex); free( (char *)local); return sts; }
static short fdlif_reply_update_mult_req(io_sAgentLocal *local_agent, pwr_sClass_Pb_FDL_SAP *sap, pwr_sClass_Pb_FDL_DataTransfer *op, io_sFDLCardLocal *local) /*----------------------------------------------------------------------------- FUNCTIONAL_DESCRIPTION this function is used to activate a SAP possible return values: - == E_OK -> no error - != E_OK -> error -----------------------------------------------------------------------------*/ { // LOCAL_VARIABLES INT16 result; /* !!! local result variable !!! */ // FUNCTION_BODY T_FDLIF_RUP_REQ *req = (T_FDLIF_RUP_REQ*) req_res_buffer; USIGN8 *data_ptr; T_PROFI_SERVICE_DESCR sdb; /* --- set data block parameters ------------------------------------------- */ data_ptr = (USIGN8*) (req+1); req->sap_nr = sap->SAP_Nr; req->priority = HIGH; memcpy(data_ptr, local->output_area, local->output_area_size); req->length = local->output_area_size; /* --- set parameter block parameters -------------------------------------- */ sdb.comm_ref = 0; sdb.layer = FDLIF; sdb.service = FDLIF_REPLY_UPDATE_MULTIPLE; sdb.primitive = REQ; sdb.invoke_id = local->invoke_id = local_agent->invoke_id; local_agent->invoke_id = (local_agent->invoke_id + 1) % 128; result = profi_snd_req_res((T_PROFI_DEVICE_HANDLE *) local_agent, &sdb, (void *) req, PB_FALSE); return ((pwr_tBoolean) (result == E_OK)); }
/*----------------------------------------------------------------------------*\ Calculate offsets of inputs and outputs for a slave \*----------------------------------------------------------------------------*/ static pwr_tStatus dp_io_offsets ( T_PROFI_DEVICE_HANDLE *hDevice, pwr_sClass_Pb_DP_Slave *op ) { T_PROFI_SERVICE_DESCR sdb; T_DP_GET_SLAVE_PARAM_REQ get_slave_param_req; T_DP_GET_SLAVE_PARAM_CON FAR *get_slave_param_con_ptr; T_DP_SLAVE_PARAM_SLAVE_INFO FAR *slave_info_ptr; USIGN8 con_ind_buffer [256]; USIGN16 con_ind_buffer_len = 256; T_PROFI_SERVICE_DESCR con_ind_sdb; INT16 result; /* !!! local result variable !!! */ sdb.comm_ref = 0; sdb.layer = DP; sdb.service = DP_GET_SLAVE_PARAM; sdb.primitive = REQ; sdb.invoke_id = 0; sdb.result = 0; get_slave_param_req.identifier = DP_SLAVE_PARAM_SLAVE_INFO; get_slave_param_req.rem_add = op->SlaveAddress; result = profi_snd_req_res (hDevice, &sdb, &get_slave_param_req, PB_FALSE); if (result != E_OK) return (result); try_profi_rcv_con_ind(hDevice, &con_ind_sdb, con_ind_buffer, &con_ind_buffer_len, &result); get_slave_param_con_ptr = (T_DP_GET_SLAVE_PARAM_CON FAR*) con_ind_buffer; if ( (con_ind_sdb.service == DP_GET_SLAVE_PARAM) && (con_ind_sdb.primitive == CON ) && (con_ind_sdb.result == POS ) ) { slave_info_ptr = (T_DP_SLAVE_PARAM_SLAVE_INFO FAR*) (get_slave_param_con_ptr + 1); op->BytesOfInput = slave_info_ptr->number_inputs; op->BytesOfOutput = slave_info_ptr->number_outputs; op->OffsetInputs = slave_info_ptr->offset_inputs; op->OffsetOutputs = slave_info_ptr->offset_outputs; return (PB_TRUE); } return (PB_FALSE); }
/*----------------------------------------------------------------------------*\ Sends request to Profiboard for setting FMB parameters \*----------------------------------------------------------------------------*/ static short fmb_set_configuration(T_PROFI_DEVICE_HANDLE *hDevice, pwr_sClass_Pb_Profiboard *op) { T_PROFI_SERVICE_DESCR sdb; T_FMB_SET_CONFIGURATION_REQ data; USIGN8 con_ind_buffer [256]; USIGN16 con_ind_buffer_len = 256; T_PROFI_SERVICE_DESCR con_ind_sdb; INT16 result; /* !!! local result variable !!! */ sdb.comm_ref = 0; sdb.layer = FMB; sdb.service = FMB_SET_CONFIGURATION; sdb.primitive = REQ; sdb.invoke_id = 0; sdb.result = 0; data.fms_active = PB_FALSE; data.dp_active = PB_TRUE; data.fdlif_active = PB_FALSE; data.fdl_evt_receiver = DP_USR; data.sm7_active = PB_FALSE; data.data_buffer_length = 256; data.dp.max_number_slaves = op->MaxNumberSlaves; data.dp.max_slave_output_len = op->MaxSlaveOutputLen; data.dp.max_slave_input_len = op->MaxSlaveInputLen; data.dp.max_slave_diag_entries = op->MaxNumberSlaves * 4; data.dp.max_slave_diag_len = op->MaxSlaveDiagLen; if ( data.dp.max_slave_diag_len == 0) data.dp.max_slave_diag_len = 60; data.dp.max_bus_para_len = 1024; data.dp.max_slave_para_len = 1024; profi_snd_req_res(hDevice, &sdb, &data, PB_FALSE); try_profi_rcv_con_ind(hDevice, &con_ind_sdb, con_ind_buffer, &con_ind_buffer_len, &result); if ((con_ind_sdb.service == FMB_SET_CONFIGURATION) && (con_ind_sdb.primitive == CON ) && (con_ind_sdb.result == POS )) { return (PB_TRUE); } return (PB_FALSE); }
/*----------------------------------------------------------------------------*\ Sends request for getting slave diagnostics \*----------------------------------------------------------------------------*/ static pwr_tBoolean dp_get_slave_diag(T_PROFI_DEVICE_HANDLE *hDevice) { T_PROFI_SERVICE_DESCR sdb; pwr_tUInt16 retval; /* Fill the service description block */ sdb.comm_ref = 0; sdb.layer = DP; sdb.service = DP_GET_SLAVE_DIAG; sdb.primitive = REQ; sdb.invoke_id = 0; sdb.result = 0; retval = profi_snd_req_res(hDevice, &sdb, &sdb, PB_FALSE); return ((pwr_tBoolean) (retval == E_OK)); }
/*----------------------------------------------------------------------------*\ Starts download sequence of prm data to one slave \*----------------------------------------------------------------------------*/ static pwr_tStatus start_download_seq ( T_PROFI_DEVICE_HANDLE *hDevice, pwr_sClass_Pb_DP_Slave *op ) { T_PROFI_SERVICE_DESCR sdb; T_DP_START_SEQ_REQ ssrp; USIGN8 con_ind_buffer [256]; USIGN16 con_ind_buffer_len = 256; USIGN16 timeout = 400; T_PROFI_SERVICE_DESCR con_ind_sdb; INT16 result; /* !!! local result variable !!! */ sdb.comm_ref = 0; sdb.layer = DP; sdb.service = DP_START_SEQ_LOC; sdb.primitive = REQ; sdb.invoke_id = 0; sdb.result = 0; ssrp.rem_add = 0; ssrp.area_code = op->SlaveAddress; ssrp.timeout = timeout; profi_snd_req_res(hDevice, &sdb, &ssrp, PB_FALSE); try_profi_rcv_con_ind(hDevice, &con_ind_sdb, con_ind_buffer, &con_ind_buffer_len, &result); if ((con_ind_sdb.service == DP_START_SEQ_LOC) && (con_ind_sdb.primitive == CON ) && (con_ind_sdb.result == POS )) { op->Status = PB__NOCONN; return (PB_TRUE); } op->Status = PB__INITFAIL; return (PB_FALSE); }
/*----------------------------------------------------------------------------*\ Sends request for selecting operation mode to the Profiboard \*----------------------------------------------------------------------------*/ static short dp_act_param_loc(T_PROFI_DEVICE_HANDLE *hDevice, short arg) { T_PROFI_SERVICE_DESCR sdb; T_DP_ACT_PARAM_REQ apr; pwr_tUInt16 retval; /* Fill the service description block */ sdb.comm_ref = 0; sdb.layer = DP; sdb.service = DP_ACT_PARAM_LOC; sdb.primitive = REQ; sdb.invoke_id = 0; sdb.result = 0; apr.rem_add = 0; apr.area_code = DP_AREA_SET_MODE; apr.activate = arg; apr.dummy = 0; retval = profi_snd_req_res(hDevice, &sdb, &apr, PB_FALSE); return retval; }
/*----------------------------------------------------------------------------*\ Sends request to Profiboard for setting DP master parameters \*----------------------------------------------------------------------------*/ static short dp_init_master(T_PROFI_DEVICE_HANDLE *hDevice) { T_PROFI_SERVICE_DESCR sdb; T_DP_INIT_MASTER_REQ data; USIGN8 con_ind_buffer [256]; USIGN16 con_ind_buffer_len = 256; T_PROFI_SERVICE_DESCR con_ind_sdb; INT16 result; /* !!! local result variable !!! */ sdb.comm_ref = 0; sdb.layer = DP; sdb.service = DP_INIT_MASTER; sdb.primitive = REQ; sdb.invoke_id = 0; sdb.result = 0; data.master_default_address = 0; data.master_class2 = PB_FALSE; data.lowest_slave_address = 2; data.slave_io_address_mode = DP_AAM_IO_BLOCKS; // only mode possible with Linux-driver DP_AAM_ARRAY; data.clear_outputs = PB_TRUE; data.auto_remote_services = DP_AUTO_REMOTE_SERVICES; data.cyclic_data_transfer = PB_TRUE; profi_snd_req_res(hDevice, &sdb, &data, PB_FALSE); try_profi_rcv_con_ind(hDevice, &con_ind_sdb, con_ind_buffer, &con_ind_buffer_len, &result); if ((con_ind_sdb.service == DP_INIT_MASTER) && (con_ind_sdb.primitive == CON ) && (con_ind_sdb.result == POS )) { return (PB_TRUE); } return (PB_FALSE); }
static short fdlif_sda_sdn_sdr_req(io_sAgentLocal *local_agent, pwr_sClass_Pb_FDL_SAP *sap, pwr_sClass_Pb_FDL_DataTransfer *op, io_sFDLCardLocal *local) /*----------------------------------------------------------------------------- FUNCTIONAL_DESCRIPTION this function is used to activate a SAP possible return values: - == E_OK -> no error - != E_OK -> error -----------------------------------------------------------------------------*/ { // LOCAL_VARIABLES short result; /* !!! local result variable !!! */ // FUNCTION_BODY T_FDLIF_SDN_SDA_SRD_REQ *req = (T_FDLIF_SDN_SDA_SRD_REQ*) req_res_buffer; unsigned char *data_ptr; T_PROFI_SERVICE_DESCR sdb; /* --- set data block parameters ------------------------------------------- */ data_ptr = (USIGN8*) (req+1); req->ssap = sap->SAP_Nr; req->dsap = op->DestSAP; req->rem_add = sap->SlaveAddress; req->priority = HIGH; memcpy(data_ptr, local->output_area, local->output_area_size); req->length = local->output_area_size; /* --- set parameter block parameters -------------------------------------- */ sdb.comm_ref = 0; sdb.layer = FDLIF; switch (op->Type) { case pwr_ePbFDLDataTransferTypeEnum_FDLIF_SDA: { sdb.service = FDLIF_SDA; break; } case pwr_ePbFDLDataTransferTypeEnum_FDLIF_SDN: { sdb.service = FDLIF_SDN; break; } case pwr_ePbFDLDataTransferTypeEnum_FDLIF_SRD: { sdb.service = FDLIF_SRD; break; } default: sdb.service = FDLIF_SDN; break; } sdb.primitive = REQ; sdb.invoke_id = local->invoke_id = local_agent->invoke_id; local_agent->invoke_id = (local_agent->invoke_id + 1) % 128; result = profi_snd_req_res((T_PROFI_DEVICE_HANDLE *) local_agent, &sdb, (void *) req, PB_FALSE); return ((pwr_tBoolean) (result == E_OK)); }
/*----------------------------------------------------------------------------*\ Initializes one DP slave in the master card \*----------------------------------------------------------------------------*/ static pwr_tStatus dp_download_slave ( T_PROFI_DEVICE_HANDLE *hDevice, pwr_sClass_Pb_DP_Slave *op ) { int i; T_PROFI_SERVICE_DESCR sdb; struct { T_DP_DOWNLOAD_REQ drp; unsigned char param[512]; } slave_data; char *send_buf; T_DP_SLAVE_PARA_SET prm_head; T_DP_PRM_DATA prm_data; T_DP_AAT_DATA aat_data; T_DP_SLAVE_USER_DATA user_data; USIGN16 download_data_size; USIGN16 data_len; pwr_tBoolean failure = FALSE; USIGN8 con_ind_buffer [256]; USIGN16 con_ind_buffer_len = 256; T_PROFI_SERVICE_DESCR con_ind_sdb; INT16 result; /* !!! local result variable !!! */ op->Status = PB__NOTINIT; download_data_size = sizeof(prm_head) + sizeof(prm_data) + op->PrmUserDataLen + op->ConfigDataLen + sizeof(aat_data) + sizeof(user_data); data_len = download_data_size; sdb.comm_ref = 0; sdb.layer = DP; sdb.service = DP_DOWNLOAD_LOC; sdb.primitive = REQ; sdb.invoke_id = 0; sdb.result = 0; prm_head.slave_para_len = swap16(download_data_size); prm_head.sl_flag = DP_SL_NEW_PRM | DP_SL_ACTIVE; prm_head.slave_type = DP_SLAVE_TYPE_DP; for (i = 0; i < 12; i++) prm_head.reserved[i] = 0; i = 0; memcpy(&slave_data.param[i], &prm_head, sizeof(prm_head)); i += sizeof(prm_head); prm_data.prm_data_len = swap16(sizeof(prm_data) + op->PrmUserDataLen); prm_data.station_status = DP_PRM_LOCK_REQ | DP_PRM_WD_ON; prm_data.wd_fact_1 = op->WdFact1; prm_data.wd_fact_2 = op->WdFact2; prm_data.min_tsdr = 0; prm_data.ident_number = swap16(op->PNOIdent); prm_data.group_ident = op->GroupIdent; memcpy(&slave_data.param[i], &prm_data, sizeof(prm_data)); i += sizeof(prm_data); memcpy(&slave_data.param[i], op->PrmUserData, op->PrmUserDataLen); i += op->PrmUserDataLen; memcpy(&slave_data.param[i], op->ConfigData, op->ConfigDataLen); i += op->ConfigDataLen; aat_data.aat_data_len = swap16(4); // AAT data not used in array mode aat_data.number_inputs = 0; aat_data.number_outputs = 0; // aat_data.offset_inputs = 0; // aat_data.offset_outputs = 0; memcpy(&slave_data.param[i], &aat_data, sizeof(aat_data)); i += sizeof(aat_data); user_data.slave_user_data_len = swap16(2); memcpy(&slave_data.param[i], &user_data, sizeof(user_data)); i += sizeof(user_data); slave_data.drp.rem_add = 0; slave_data.drp.area_code = op->SlaveAddress; slave_data.drp.add_offset = 0; send_buf = (char *) slave_data.param; if (data_len > DP_MAX_DOWNLOAD_DATA_LEN) { if (!start_download_seq(hDevice, op)) { op->Status = PB__INITFAIL; return (PB_FALSE); } } while (download_data_size > 0) { slave_data.drp.data_len = MIN(download_data_size, DP_MAX_DOWNLOAD_DATA_LEN); profi_snd_req_res(hDevice, &sdb, &slave_data, PB_FALSE); try_profi_rcv_con_ind(hDevice, &con_ind_sdb, con_ind_buffer, &con_ind_buffer_len, &result); if (con_ind_sdb.service == DP_DOWNLOAD_LOC) { if ((con_ind_sdb.primitive == CON ) && (con_ind_sdb.result == POS )) { op->Status = PB__NOCONN; } else { op->Status = PB__INITFAIL; failure = TRUE; break; } } if (download_data_size > DP_MAX_DOWNLOAD_DATA_LEN) { download_data_size -= DP_MAX_DOWNLOAD_DATA_LEN; slave_data.drp.add_offset += DP_MAX_DOWNLOAD_DATA_LEN; send_buf += DP_MAX_DOWNLOAD_DATA_LEN; memcpy(slave_data.param, send_buf, MIN(download_data_size, DP_MAX_DOWNLOAD_DATA_LEN)); } else download_data_size = 0; } if (data_len > DP_MAX_DOWNLOAD_DATA_LEN) { if (!end_download_seq(hDevice, op)) { op->Status = PB__INITFAIL; return (PB_FALSE); } } if (failure) return (PB_FALSE); else return (PB_TRUE); }
/*----------------------------------------------------------------------------*\ Sends request to Profiboard for setting DP bus parameters \*----------------------------------------------------------------------------*/ static short dp_download_bus(T_PROFI_DEVICE_HANDLE *hDevice, pwr_sClass_Pb_Profiboard *op) { T_PROFI_SERVICE_DESCR sdb; struct { T_DP_DOWNLOAD_REQ drp; T_DP_BUS_PARA_SET dbp; } data; int i; USIGN8 con_ind_buffer [256]; USIGN16 con_ind_buffer_len = 256; T_PROFI_SERVICE_DESCR con_ind_sdb; INT16 result; /* !!! local result variable !!! */ sdb.comm_ref = 0; sdb.layer = DP; sdb.service = DP_DOWNLOAD_LOC; sdb.primitive = REQ; sdb.invoke_id = 0; sdb.result = 0; data.drp.data_len = 66; data.drp.rem_add = 0; data.drp.area_code = DP_AREA_BUS_PARAM; data.drp.add_offset = 0; data.dbp.bus_para_len = swap16(66); data.dbp.fdl_add = 0; switch (op->BaudRate) { case 500: data.dbp.baud_rate = DP_KBAUD_500; break; case 750: data.dbp.baud_rate = DP_KBAUD_750; break; case 1500: data.dbp.baud_rate = DP_KBAUD_1500; break; case 3000: data.dbp.baud_rate = DP_KBAUD_3000; break; case 6000: data.dbp.baud_rate = DP_KBAUD_6000; break; case 12000: data.dbp.baud_rate = DP_KBAUD_12000; break; default: data.dbp.baud_rate = DP_KBAUD_1500; break; } data.dbp.tsl = swap16(op->Tsl); data.dbp.min_tsdr = swap16(op->MinTsdr); data.dbp.max_tsdr = swap16(op->MaxTsdr); data.dbp.tqui = op->Tqui; data.dbp.tset = op->Tset; data.dbp.ttr = swap32(op->Ttr); data.dbp.g = op->G; data.dbp.hsa = op->Hsa; data.dbp.max_retry_limit = op->MaxRetryLimit; data.dbp.bp_flag = op->BpFlag; data.dbp.min_slave_interval = swap16(op->MinSlaveInterval); data.dbp.poll_timeout = swap16(op->PollTimeout); data.dbp.data_control_time = swap16(op->DataControlTime); for (i=0; i<6; i++) data.dbp.reserved[i] = 0; data.dbp.master_user_data_len = swap16(DP_MASTER_USER_DATA_LEN); for (i=0; i<32; i++) data.dbp.master_class2_name[i] = 0; profi_snd_req_res(hDevice, &sdb, &data, PB_FALSE); try_profi_rcv_con_ind(hDevice, &con_ind_sdb, con_ind_buffer, &con_ind_buffer_len, &result); if ((con_ind_sdb.service == DP_DOWNLOAD_LOC) && (con_ind_sdb.primitive == CON ) && (con_ind_sdb.result == POS )) { return (PB_TRUE); } return (PB_FALSE); }