/*------------------------------------------- Profibus State Machine -------------------------------------------*/ void Profibus(void) { u8 i; u8 MSG_old; u8 toggle; switch(DP_State) { case STATE_IDLE: default: { break; } case STARTUP: { TX_Buffer [0] = SD2; TX_Buffer [1] = 0x05; TX_Buffer [2] = 0x05; TX_Buffer [3] = SD2; TX_Buffer [4] = ActualSlaveAddress + SAP_OFFSET; TX_Buffer [5] = MASTER_ADDRESS + SAP_OFFSET; TX_Buffer [6] = 0x6D; TX_Buffer [7] = 0x3C; TX_Buffer [8] = 0x3E; TX_Buffer [9] = Checksum(&TX_Buffer [0]); TX_Buffer [10] = ED; SendDP(&TX_Buffer [0], 11); break; } case DIAG_REQUEST: { TX_Buffer [0] = SD2; TX_Buffer [1] = 0x05; TX_Buffer [2] = 0x05; TX_Buffer [3] = SD2; TX_Buffer [4] = ActualSlaveAddress + SAP_OFFSET; TX_Buffer [5] = MASTER_ADDRESS + SAP_OFFSET; TX_Buffer [6] = 0x6D; TX_Buffer [7] = 0x3C; TX_Buffer [8] = 0x3E; TX_Buffer [9] = Checksum(&TX_Buffer [0]); TX_Buffer [10] = ED; SendDP(&TX_Buffer [0], 11); DP_State = DIAG_RESPONSE; break; } case DIAG_RESPONSE: { Ident_High = RX_Buffer[13]; Ident_Low = RX_Buffer[14]; TX_Buffer [0] = SD2; TX_Buffer [1] = ActualSlaveParameterLength + 11; TX_Buffer [2] = ActualSlaveParameterLength + 11; TX_Buffer [3] = SD2; TX_Buffer [4] = ActualSlaveAddress + SAP_OFFSET; TX_Buffer [5] = MASTER_ADDRESS + SAP_OFFSET; TX_Buffer [6] = 0x5D; TX_Buffer [7] = 0x3D; TX_Buffer [8] = 0x3E; TX_Buffer [9] = 0xB8; TX_Buffer [10] = 0x12; TX_Buffer [11] = 0x13; TX_Buffer [12] = 0x0B; TX_Buffer [13] = Ident_High; TX_Buffer [14] = Ident_Low; for (i = 0; i < ActualSlaveParameterLength; i++) { TX_Buffer [15 + i] = ActualSlaveParameter[i]; } TX_Buffer[TX_Buffer[1] + 4] = Checksum(&TX_Buffer [0]); TX_Buffer[TX_Buffer[1] + 5] = ED; SendDP(&TX_Buffer [0], TX_Buffer[1] + 6); DP_State = PARAMETER_REQUEST; break; } case PARAMETER_REQUEST: { TX_Buffer [0] = SD2; TX_Buffer [1] = ActualSlaveConfigLength + 5; TX_Buffer [2] = ActualSlaveConfigLength + 5; TX_Buffer [3] = SD2; TX_Buffer [4] = ActualSlaveAddress + SAP_OFFSET; TX_Buffer [5] = MASTER_ADDRESS + SAP_OFFSET; TX_Buffer [6] = 0x7D; TX_Buffer [7] = 0x3E; TX_Buffer [8] = 0x3E; for (i = 0; i < ActualSlaveConfigLength; i++) { TX_Buffer [9 + i] = ActualSlaveConfig[i]; } TX_Buffer [TX_Buffer[1] + 4] = Checksum(&TX_Buffer [0]); TX_Buffer [TX_Buffer[1] + 5] = ED; SendDP(&TX_Buffer [0], TX_Buffer[1] + 6); DP_State = CHECK_CONFIG; break; } case CHECK_CONFIG: { if(!DataOutLength) { TX_Buffer [0] = SD1; TX_Buffer [1] = ActualSlaveAddress; TX_Buffer [2] = MASTER_ADDRESS; if(!toggle) { TX_Buffer [3] = 0x7D; toggle = 1; } else { TX_Buffer [3] = 0x5D; toggle = 0; } TX_Buffer [4] = Checksum(&TX_Buffer [0]); TX_Buffer [5] = ED; SendDP(&TX_Buffer [0], 6); } else { TX_Buffer [0] = SD2; TX_Buffer [1] = DataOutLength + 3; TX_Buffer [2] = DataOutLength + 3; TX_Buffer [3] = SD2; TX_Buffer [4] = ActualSlaveAddress; TX_Buffer [5] = MASTER_ADDRESS; TX_Buffer [6] = 0x7D; // TX_Buffer still filled with data for (i = 0; i < DataOutLength; i++) { TX_Buffer [7 + i] = 0; } TX_Buffer [TX_Buffer[1] + 4] = Checksum(&TX_Buffer [0]); TX_Buffer [TX_Buffer[1] + 5] = ED; SendDP(&TX_Buffer [0], TX_Buffer[1] + 6); } DP_State = DATA_EXCHANGE; break; } case GET_DIAG_REQUEST: // hier noch dynamisch??? { TX_Buffer [0] = SD2; TX_Buffer [1] = 0x0B; TX_Buffer [2] = 0x0B; TX_Buffer [3] = SD2; TX_Buffer [4] = ActualSlaveAddress; TX_Buffer [5] = MASTER_ADDRESS; TX_Buffer [6] = 0x7D; TX_Buffer [7] = 0x00; TX_Buffer [8] = 0x00; TX_Buffer [9] = 0x00; TX_Buffer [10] = 0x00; TX_Buffer [11] = 0x00; TX_Buffer [12] = 0x00; TX_Buffer [13] = 0x00; TX_Buffer [14] = 0x00; TX_Buffer [15] = Checksum(&TX_Buffer [0]); TX_Buffer [16] = ED; SendDP(&TX_Buffer [0], 17); DP_State = DATA_EXCHANGE; break; } case SEARCH_DEVICE: { Start_Search = 0; DP_State = STATE_IDLE; // DIAG_RESPONSE; ? GotDevice(); break; } case SET_SLAVE_ADDRESS: { Ident_High = RX_Buffer[13]; Ident_Low = RX_Buffer[14]; TX_Buffer [0] = SD2; TX_Buffer [1] = 0x09; TX_Buffer [2] = 0x09; TX_Buffer [3] = SD2; TX_Buffer [4] = ActualSlaveAddress + SAP_OFFSET; TX_Buffer [5] = MASTER_ADDRESS + SAP_OFFSET; TX_Buffer [6] = 0x6D; TX_Buffer [7] = 0x37; TX_Buffer [8] = 0x3E; TX_Buffer [9] = NewSlaveAddress; TX_Buffer [10] = Ident_High; TX_Buffer [11] = Ident_Low; TX_Buffer [12] = 0x00; TX_Buffer [13] = Checksum(&TX_Buffer [0]); TX_Buffer [14] = ED; SendDP(&TX_Buffer [0], 15); SSA_Flag = 0; DP_State = STATE_IDLE; break; } case DATA_EXCHANGE: { if(!DataOutLength) { TX_Buffer [0] = SD1; TX_Buffer [1] = ActualSlaveAddress; TX_Buffer [2] = MASTER_ADDRESS; if(!toggle) { TX_Buffer [3] = 0x7D; toggle = 1; } else { TX_Buffer [3] = 0x5D; toggle = 0; } TX_Buffer [4] = Checksum(&TX_Buffer [0]); TX_Buffer [5] = ED; SendDP(&TX_Buffer [0], 6); } else { TX_Buffer [0] = SD2; TX_Buffer [1] = DataOutLength + 3; TX_Buffer [2] = DataOutLength + 3; TX_Buffer [3] = SD2; TX_Buffer [4] = ActualSlaveAddress; TX_Buffer [5] = MASTER_ADDRESS; TX_Buffer [6] = 0x7D; //NewOutputData = 1; // TX_Buffer still filled with data if(NewOutputData) { for (i = 0; i < DataOutLength; i++) { TX_Buffer [7 + i] = DataOut[i]; } NewOutputData = 0; } else { // if no data is used, send 0 for (i = 0; i < DataOutLength; i++) { TX_Buffer [7 + i] = 0; } } TX_Buffer [TX_Buffer[1] + 4] = Checksum(&TX_Buffer [0]); TX_Buffer [TX_Buffer[1] + 5] = ED; SendDP(&TX_Buffer [0], TX_Buffer[1] + 6); } // input data for (i = 0; i < DataInLength; i++) { DataIn[i] = RX_Buffer [7 + i] ; } break; } } FrameState = FRAME_IDLE; } /*------------------------------------------- Set input / output data size -------------------------------------------*/ void SetConfig(uint8_t *Buffer, uint8_t length) { uint8_t cnt; uint8_t Vendor_Data_size; for (cnt = 0; cnt < length; cnt++) { switch (Buffer[0+cnt] & CFG_DIRECTION_) { case CFG_INPUT: { DataInLength += (Buffer[0+cnt] & CFG_BYTE_CNT_) + 1; if (Buffer[0+cnt] & CFG_WIDTH_ & CFG_WORD) { DataInLength += DataInLength*2; } break; } case CFG_OUTPUT: { DataOutLength += (Buffer[0+cnt] & CFG_BYTE_CNT_) + 1; if (Buffer[0+cnt] & CFG_WIDTH_ & CFG_WORD) { DataOutLength += DataOutLength*2; } break; } case CFG_INPUT_OUTPUT: { DataInLength += (Buffer[0+cnt] & CFG_BYTE_CNT_) + 1; DataOutLength += (Buffer[0+cnt] & CFG_BYTE_CNT_) + 1; if (Buffer[0+cnt] & CFG_WIDTH_ & CFG_WORD) { DataInLength += DataInLength*2; DataOutLength += DataOutLength*2; } break; } case CFG_SPECIAL: { // Herstellerspezifische Bytes vorhanden? if (Buffer[0+cnt] & CFG_SP_VENDOR_CNT_) { // Anzahl Herstellerdaten sichern Vendor_Data_size = Buffer[0+cnt] & CFG_SP_VENDOR_CNT_; // Anzahl von Gesamtanzahl abziehen //uart_buffer[1] -= Vendor_Data_size; // cnt -= Vendor_Data_size; } // I/O Daten switch (Buffer[0+cnt] & CFG_SP_DIRECTION_) { case CFG_SP_VOID: { // Leeres Datenfeld break; } case CFG_SP_INPUT: { DataInLength += (Buffer[1+cnt] & CFG_SP_BYTE_CNT_) + 1; if (Buffer[1+cnt] & CFG_WIDTH_ & CFG_WORD) { DataInLength += DataInLength*2; } cnt++; break; } case CFG_SP_OUTPUT: { DataOutLength += (Buffer[1+cnt] & CFG_SP_BYTE_CNT_) + 1; if (Buffer[0+cnt] & CFG_WIDTH_ & CFG_WORD) { DataOutLength += DataOutLength*2; } cnt++; break; } case CFG_SP_INPUT_OPTPUT: { // output DataOutLength += (Buffer[1+cnt] & CFG_SP_BYTE_CNT_) + 1; if (Buffer[1+cnt] & CFG_WIDTH_ & CFG_WORD) { DataOutLength += DataOutLength*2; } // input DataInLength += (Buffer[2+cnt] & CFG_SP_BYTE_CNT_) + 1; if (Buffer[2+cnt] & CFG_WIDTH_ & CFG_WORD) { DataInLength += DataInLength*2; } cnt += 2; break; } } } } } } /*------------------------------------------- create checksum of buffer -------------------------------------------*/ u8 Checksum(char *Buffer) { u8 Length; u8 Checksum = 0; u8 n; if(Buffer[0] == SD2) { Length = Buffer[1]; for(n=0;n