diff --git a/diode_tester/Core/Interfaces/interface_config.h b/diode_tester/Core/Interfaces/interface_config.h index 55b520a..2cc2ef6 100644 --- a/diode_tester/Core/Interfaces/interface_config.h +++ b/diode_tester/Core/Interfaces/interface_config.h @@ -18,6 +18,14 @@ @{ */ +#define MODBUS_VENDOR_NAME "\n\rNIO-12" +#define MODBUS_PRODUCT_CODE "\n\r12345" +#define MODBUS_REVISION "\n\r1.0" +#define MODBUS_VENDOR_URL "\n\rhttps://git.arktika.cyou/Andrey/Diod_Test" +#define MODBUS_PRODUCT_NAME "\n\rDiode Tester" +#define MODBUS_MODEL_NAME "\n\rSTM32F103" +#define MODBUS_USER_APPLICATION_NAME "\n\rdiode_tester" + //#define MODBUS_UART_NUMB 1 ///< Номер используемого UART, по нему выставляется дефайн USED_MB_UART = USARTx #define MODBUS_SPEED 115200 ///< Скорость UART для модбас //#define MODBUS_GPIOX GPIOA ///< Порт для UART RX/TX diff --git a/diode_tester/Core/Interfaces/modbus.c b/diode_tester/Core/Interfaces/modbus.c index ce16e65..f4da156 100644 --- a/diode_tester/Core/Interfaces/modbus.c +++ b/diode_tester/Core/Interfaces/modbus.c @@ -95,6 +95,7 @@ RS_HandleTypeDef hmodbus1; /* DEFINE REGISTERS/COILS */ MB_DataStructureTypeDef MB_DATA; RS_MsgTypeDef MODBUS_MSG; +MB_DeviceIdentificationTypeDef MB_INFO; uint32_t delay_scide = 1; uint32_t numb_scide = 10; @@ -109,6 +110,7 @@ uint32_t numb_scide = 10; */ void MODBUS_FirstInit(void) { + MB_DevoceInentificationInit(); //-----------SETUP MODBUS------------- // set up UART for modbus #ifdef INCLUDE_GENERAL_PERIPH_LIBS @@ -589,6 +591,54 @@ uint8_t MB_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg) return 1; } +void MB_WriteObjectToMessage(char *mbdata, unsigned *ind, MB_DeviceObjectTypeDef *obj) +{ + mbdata[(*ind)++] = obj->length; + for (int i = 0; i < obj->length; i++) + { + mbdata[(*ind)++] = obj->name[i]; + } +} +/** + * @brief Proccess command Read Device Identification (43/14 - 0x2B/0E). + * @param modbus_msg - указатель на структуру собщения modbus. + * @return fMessageHandled - статус о результате обработки комманды. + * @details Обработка команды Write Single Register. + */ +uint8_t MB_Read_Device_Identification(RS_MsgTypeDef *modbus_msg) +{ + char *mbdata = (char *)modbus_msg->DATA; + unsigned ind = 0; + switch(modbus_msg->DevId.ReadDevId) + { + case MB_BASIC_IDENTIFICATION: + mbdata[ind++] = 0x00; + MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.VendorName); + mbdata[ind++] = 0x01; + MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.ProductCode); + mbdata[ind++] = 0x02; + MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.Revision); + modbus_msg->DevId.NumbOfObj = 3; + break; + case MB_REGULAR_IDENTIFICATION: + mbdata[ind++] = 0x03; + MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.VendorUrl); + mbdata[ind++] = 0x04; + MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.ProductName); + mbdata[ind++] = 0x05; + MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.ModelName); + mbdata[ind++] = 0x06; + MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.UserApplicationName); + modbus_msg->DevId.NumbOfObj = 4; + break; + default: + return 0; + } + + modbus_msg->ByteCnt = ind; + return 1; +} + /** * @brief Respond accord to received message. @@ -661,6 +711,11 @@ RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_ms } break; + case MB_R_DEVICE_INFO: + hmodbus->f.MessageHandled = MB_Read_Device_Identification(hmodbus->pMessagePtr); + break; + + /* unknown func code */ default: modbus_msg->Except_Code = 0x01; /* set exception code: illegal function */ } @@ -715,28 +770,60 @@ RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mo if (modbus_msg->Func_Code < ERR_VALUES_START) // if no error occur { - // set size of received data - if (modbus_msg->ByteCnt <= DATA_SIZE*2) // if ByteCnt less than DATA_SIZE - modbus_uart_buff[ind++] = modbus_msg->ByteCnt; - else // otherwise return data_size err + // fill modbus header + if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // devide identification header { - TrackerCnt_Err(hmodbus->rs_err); - return RS_COLLECT_MSG_ERR; + modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type; + modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId; + modbus_uart_buff[ind++] = modbus_msg->DevId.Conformity; + modbus_uart_buff[ind++] = modbus_msg->DevId.MoreFollows; + modbus_uart_buff[ind++] = modbus_msg->DevId.NextObjId; + modbus_uart_buff[ind++] = modbus_msg->DevId.NumbOfObj; + + if (modbus_msg->ByteCnt > DATA_SIZE*2) // if ByteCnt less than DATA_SIZE + { + TrackerCnt_Err(hmodbus->rs_err); + return RS_COLLECT_MSG_ERR; + } + + + //---------------DATA---------------- + //-----------[data bytes]------------ + uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA; + for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data + { // set data + modbus_uart_buff[ind++] = *tmp_data_addr; + tmp_data_addr++; + } + } - - //---------------DATA---------------- - //-----------[data bytes]------------ - uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA; - for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data - { // set data - if (i%2 == 0) // HI byte - modbus_uart_buff[ind++] = (*tmp_data_addr)>>8; - else // LO byte - { - modbus_uart_buff[ind++] = *tmp_data_addr; - tmp_data_addr++; - } - } + else // modbus data header + { + // set size of received data + if (modbus_msg->ByteCnt <= DATA_SIZE*2) // if ByteCnt less than DATA_SIZE + modbus_uart_buff[ind++] = modbus_msg->ByteCnt; + else // otherwise return data_size err + { + TrackerCnt_Err(hmodbus->rs_err); + return RS_COLLECT_MSG_ERR; + } + + //---------------DATA---------------- + //-----------[data bytes]------------ + uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA; + for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data + { // set data + if (i%2 == 0) // HI byte + modbus_uart_buff[ind++] = (*tmp_data_addr)>>8; + else // LO byte + { + modbus_uart_buff[ind++] = *tmp_data_addr; + tmp_data_addr++; + } + } + + } + } else // if some error occur { // send expection code @@ -776,9 +863,17 @@ RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modb if(modbus_msg->MbAddr != hmodbus->ID) return RS_SKIP; - // get dat or err response + // get func code modbus_msg->Func_Code = modbus_uart_buff[ind++]; - + if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // if it device identification request + { + modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++]; + modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++]; + modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++]; + modbus_msg->ByteCnt = 0; + } + else // if its classic modbus request + { // get address from CMD modbus_msg->Addr = modbus_uart_buff[ind++] << 8; modbus_msg->Addr |= modbus_uart_buff[ind++]; @@ -786,7 +881,7 @@ RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modb // get address from CMD modbus_msg->Qnt = modbus_uart_buff[ind++] << 8; modbus_msg->Qnt |= modbus_uart_buff[ind++]; - + } if(hmodbus->f.RX_Half == 0) // if all message received { //---------------DATA---------------- @@ -856,6 +951,7 @@ RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hmodbus, uint32_ if(MB_RES == RS_SKIP) // if message not for us return MB_RES; // return + if ((hmodbus->pMessagePtr->Func_Code & ~ERR_VALUES_START) < 0x0F) { hmodbus->pMessagePtr->ByteCnt = 0; @@ -867,6 +963,13 @@ RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hmodbus, uint32_ // +1 because that defines is size, not ind. *rx_data_size = hmodbus->pMessagePtr->ByteCnt + 2; } + + + if(hmodbus->pMessagePtr->Func_Code == MB_R_DEVICE_INFO) + { + *rx_data_size = 0; + } + hmodbus->RS_Message_Size = RX_FIRST_PART_SIZE + *rx_data_size; // size of whole message return RS_OK; } @@ -875,21 +978,25 @@ RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hmodbus, uint32_ //------------------------------------------------------------------- +void MB_DevoceInentificationInit(void) +{ + MB_INFO.VendorName.name = MODBUS_VENDOR_NAME; + MB_INFO.ProductCode.name = MODBUS_PRODUCT_CODE; + MB_INFO.Revision.name = MODBUS_REVISION; + MB_INFO.VendorUrl.name = MODBUS_VENDOR_URL; + MB_INFO.ProductName.name = MODBUS_PRODUCT_NAME; + MB_INFO.ModelName.name = MODBUS_MODEL_NAME; + MB_INFO.UserApplicationName.name = MODBUS_USER_APPLICATION_NAME; + + + MB_INFO.VendorName.length = sizeof(MODBUS_VENDOR_NAME); + MB_INFO.ProductCode.length = sizeof(MODBUS_PRODUCT_CODE); + MB_INFO.Revision.length = sizeof(MODBUS_REVISION); + MB_INFO.VendorUrl.length = sizeof(MODBUS_VENDOR_URL); + MB_INFO.ProductName.length = sizeof(MODBUS_PRODUCT_NAME); + MB_INFO.ModelName.length = sizeof(MODBUS_MODEL_NAME); + MB_INFO.UserApplicationName.length = sizeof(MODBUS_USER_APPLICATION_NAME); +} + -//------------------------------------------------------------------- -//-------------------------HANDLERS FUNCTION------------------------- -//void USART1_IRQHandler(void) -//{ -// Trace_MB_UART_Enter(); -// RS_UART_Handler(&hmodbus1); -// Trace_MB_UART_Exit(); -//} -//void TIM1_UP_TIM10_IRQHandler(void) -//{ -// Trace_MB_TIM_Enter(); -// RS_TIM_Handler(&hmodbus1); -// Trace_MB_TIM_Exit(); -//} -//-------------------------HANDLERS FUNCTION------------------------- -//------------------------------------------------------------------- diff --git a/diode_tester/Core/Interfaces/modbus.h b/diode_tester/Core/Interfaces/modbus.h index 7359b0e..d23e8a9 100644 --- a/diode_tester/Core/Interfaces/modbus.h +++ b/diode_tester/Core/Interfaces/modbus.h @@ -54,11 +54,11 @@ first receive info part of message, than defines size of rest message*/ typedef enum //MB_ExceptionTypeDef { // reading - NO_ERRORS = 0x00, ///< no errors - ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан - ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен - ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной - SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие + NO_ERRORS = 0x00, ///< no errors + ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан + ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен + ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной + SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие // ACKNOWLEDGE = 0x05, ///< idk // SLAVE_DEVICE_BUSY = 0x06, ///< idk // MEMORY_PARITY_ERROR = 0x08, ///< idk @@ -70,41 +70,73 @@ typedef enum //MB_FunctonTypeDef { /* COMMANDS */ // reading - MB_R_COILS = 0x01, ///< Чтение битовых ячеек - MB_R_DISC_IN = 0x02, ///< Чтение дискретных входов + MB_R_COILS = 0x01, ///< Чтение битовых ячеек + MB_R_DISC_IN = 0x02, ///< Чтение дискретных входов #ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS - MB_R_HOLD_REGS = 0x03, ///< Чтение входных регистров - MB_R_IN_REGS = 0x04, ///< Чтение регистров хранения + MB_R_HOLD_REGS = 0x03, ///< Чтение входных регистров + MB_R_IN_REGS = 0x04, ///< Чтение регистров хранения #else - MB_R_HOLD_REGS = 0x04, ///< Чтение входных регистров - MB_R_IN_REGS = 0x03, ///< Чтение регистров хранения + MB_R_HOLD_REGS = 0x04, ///< Чтение входных регистров + MB_R_IN_REGS = 0x03, ///< Чтение регистров хранения #endif // writting - MB_W_COIL = 0x05, ///< Запись битовой ячейки - MB_W_HOLD_REG = 0x06, ///< Запись одиночного регистра - MB_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек - MB_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров + MB_W_COIL = 0x05, ///< Запись битовой ячейки + MB_W_HOLD_REG = 0x06, ///< Запись одиночного регистра + MB_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек + MB_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров + + MB_R_DEVICE_INFO = 0x2B, ///< Чтения информации об устройстве /* ERRORS */ // error reading - MB_ERR_R_COILS = MB_R_COILS + ERR_VALUES_START, ///< Ошибка чтения битовых ячеек - MB_ERR_R_DISC_IN = MB_R_DISC_IN + ERR_VALUES_START, ///< Ошибка чтения дискретных входов - MB_ERR_R_IN_REGS = MB_R_IN_REGS + ERR_VALUES_START, ///< Ошибка чтения регистров хранения - MB_ERR_R_HOLD_REGS = MB_R_HOLD_REGS + ERR_VALUES_START, ///< Ошибка чтения входных регистров + MB_ERR_R_COILS = MB_R_COILS + ERR_VALUES_START, ///< Ошибка чтения битовых ячеек + MB_ERR_R_DISC_IN = MB_R_DISC_IN + ERR_VALUES_START, ///< Ошибка чтения дискретных входов + MB_ERR_R_IN_REGS = MB_R_IN_REGS + ERR_VALUES_START, ///< Ошибка чтения регистров хранения + MB_ERR_R_HOLD_REGS = MB_R_HOLD_REGS + ERR_VALUES_START, ///< Ошибка чтения входных регистров // error writting - MB_ERR_W_COIL = MB_W_COIL + ERR_VALUES_START, ///< Ошибка записи битовой ячейки - MB_ERR_W_HOLD_REG = MB_W_HOLD_REG + ERR_VALUES_START, ///< Ошибка записи одиночного регистра - MB_ERR_W_COILS = MB_W_COILS + ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек - MB_ERR_W_HOLD_REGS = MB_W_HOLD_REGS + ERR_VALUES_START, ///< Ошибка записи нескольких регистров + MB_ERR_W_COIL = MB_W_COIL + ERR_VALUES_START, ///< Ошибка записи битовой ячейки + MB_ERR_W_HOLD_REG = MB_W_HOLD_REG + ERR_VALUES_START, ///< Ошибка записи одиночного регистра + MB_ERR_W_COILS = MB_W_COILS + ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек + MB_ERR_W_HOLD_REGS = MB_W_HOLD_REGS + ERR_VALUES_START, ///< Ошибка записи нескольких регистров }MB_FunctonTypeDef; +/** @brief Structure for MEI func codes */ +typedef enum //MB_FunctonTypeDef +{ + MEI_DEVICE_IDENTIFICATION = 0x0E, +}MB_MEITypeDef; + +/** @brief Structure for MEI func codes */ +typedef enum //MB_FunctonTypeDef +{ + MB_BASIC_IDENTIFICATION = 0x01, + MB_REGULAR_IDENTIFICATION = 0x02, + + + /* ERRORS */ + MB_ERR_BASIC_IDENTIFICATION = MB_BASIC_IDENTIFICATION + ERR_VALUES_START, + MB_ERR_REGULAR_IDENTIFICATION = MB_REGULAR_IDENTIFICATION + ERR_VALUES_START, +}MB_ConformityTypeDef; + +/** @brief Structure for decive identification message type */ +typedef struct +{ + MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identification Interface + MB_ConformityTypeDef ReadDevId; + MB_ConformityTypeDef Conformity; + uint8_t MoreFollows; ///< in this library always a zero + uint8_t NextObjId; + uint8_t NumbOfObj; +}MB_DevIdMsgTypeDef; + /** @brief Structure for modbus messsage */ typedef struct // RS_MsgTypeDef { uint8_t MbAddr; ///< Modbus Slave Address MB_FunctonTypeDef Func_Code; ///< Modbus Function Code + MB_DevIdMsgTypeDef DevId; ///< Read Device Identification Header struct uint16_t Addr; ///< Modbus Address of data uint16_t Qnt; ///< Quantity of modbus data uint8_t ByteCnt; ///< Quantity of bytes of data in message to transmit/receive diff --git a/diode_tester/Core/Interfaces/modbus_data.h b/diode_tester/Core/Interfaces/modbus_data.h index e24d914..42a237e 100644 --- a/diode_tester/Core/Interfaces/modbus_data.h +++ b/diode_tester/Core/Interfaces/modbus_data.h @@ -148,6 +148,23 @@ typedef struct // tester modbus data extern MB_DataStructureTypeDef MB_DATA; +typedef struct +{ + unsigned length; + char *name; +}MB_DeviceObjectTypeDef; +typedef struct +{ + MB_DeviceObjectTypeDef VendorName; + MB_DeviceObjectTypeDef ProductCode; + MB_DeviceObjectTypeDef Revision; + MB_DeviceObjectTypeDef VendorUrl; + MB_DeviceObjectTypeDef ProductName; + MB_DeviceObjectTypeDef ModelName; + MB_DeviceObjectTypeDef UserApplicationName; +}MB_DeviceIdentificationTypeDef; +void MB_DevoceInentificationInit(void); + #endif //_MODBUS_DATA_H_ diff --git a/diode_tester/Core/Interfaces/rs_message.c b/diode_tester/Core/Interfaces/rs_message.c index 3586c0e..46673d0 100644 --- a/diode_tester/Core/Interfaces/rs_message.c +++ b/diode_tester/Core/Interfaces/rs_message.c @@ -388,18 +388,38 @@ RS_StatusTypeDef RS_UART_RxCpltCallback(RS_HandleTypeDef *hRS) { // First receive part of message, then define size of rest of message, and start receive it hRS->f.RX_Half = 1; //---------------FIND DATA SIZE----------------- - uint32_t NuRS_of_Rest_Bytes = 0; + uint32_t NuRS_of_Rest_Bytes = 0xFFFF; RS_RES = RS_Define_Size_of_RX_Message(hRS, &NuRS_of_Rest_Bytes); - // if there is no bytes to receive OR we need to skip this message - restart receive - if ((NuRS_of_Rest_Bytes == 0) || (RS_RES == RS_SKIP)) + // if we need to skip this message - restart receive + if(RS_RES == RS_SKIP || NuRS_of_Rest_Bytes == 0xFFFF) { TrackerCnt_Err(hRS->rs_err); RS_Abort(hRS, ABORT_RX); RS_RES = RS_Handle_Receive_Start(hRS, hRS->pMessagePtr); return RS_RES; } + + // if there is no bytes to receive + if(NuRS_of_Rest_Bytes == 0) + { + hRS->f.RX_Half = 0; + + //---------PROCESS DATA & ENDING RECEIVING-------- + RS_Set_RX_End(hRS); + + if(hRS->sRS_Timeout) // if timeout setted + HAL_TIM_Base_Stop_IT(hRS->htim); // stop timeout + + // parse received data + RS_RES = RS_Parse_Message(hRS, hRS->pMessagePtr, hRS->pBufferPtr); // parse message + + // RESPONSE + RS_RES = RS_Response(hRS, hRS->pMessagePtr); + return RS_RES; + } + //-------------START UART RECEIVE--------------- uart_res = HAL_UART_Receive_IT(hRS->huart, (hRS->pBufferPtr + RX_FIRST_PART_SIZE), NuRS_of_Rest_Bytes); diff --git a/diode_tester/MDK-ARM/diode_tester.uvoptx b/diode_tester/MDK-ARM/diode_tester.uvoptx index 200d7cf..bff4e9a 100644 --- a/diode_tester/MDK-ARM/diode_tester.uvoptx +++ b/diode_tester/MDK-ARM/diode_tester.uvoptx @@ -152,18 +152,18 @@ 0 0 - 89 + 227 1 -
134240776
+
134244270
0 0 0 0 0 1 - ..\Core\Tester_main\tester_adc_func.c + ../Core/Src/stm32f1xx_it.c - \\diode_tester\../Core/Tester_main/tester_adc_func.c\89 + \\diode_tester\../Core/Src/stm32f1xx_it.c\227
@@ -197,6 +197,11 @@ 1 tester->mbdata->Coils + + 6 + 1 + RS_Buffer + @@ -234,6 +239,26 @@ 2 \\diode_tester\../Core/Tester_main/tester_main.c\TESTER + + 7 + 2 + MB_INFO + + + 8 + 2 + RS_Buffer + + + 9 + 2 + *ind + + + 10 + 2 + &ind + 0 @@ -279,28 +304,12 @@ - System Viewer\ADC1 - 35903 - - - System Viewer\AFIO - 35905 - - - System Viewer\DMA1 - 35902 - - - System Viewer\GPIOA - 35904 - - - System Viewer\GPIOB - 35901 + System Viewer\TIM2 + 35899 System Viewer\USART1 - 35900 + 35905