Отправка Modbus. Промежуточный коммит
This commit is contained in:
@@ -218,11 +218,26 @@ typedef union{
|
|||||||
* Используется для хранения данных о регистре и его содержимом.
|
* Используется для хранения данных о регистре и его содержимом.
|
||||||
*/
|
*/
|
||||||
typedef struct{
|
typedef struct{
|
||||||
|
struct ProtoCanCoreData{
|
||||||
|
uint16_t Type;
|
||||||
|
uint16_t Body;
|
||||||
|
uint8_t *Data;
|
||||||
|
unsigned DataCount;
|
||||||
|
} CoreData;
|
||||||
struct ProtoCanGeneralAddressSpaceData{
|
struct ProtoCanGeneralAddressSpaceData{
|
||||||
uint16_t RegStartAdr; /**< Начальный адрес регистров. */
|
uint16_t RegStartAdr; /**< Начальный адрес регистров. */
|
||||||
uint16_t *Data; /**< Указатель на массив данных. */
|
uint16_t *Data; /**< Указатель на массив данных. */
|
||||||
unsigned RegCount; /**< Количество регистров. */
|
unsigned RegCount; /**< Количество регистров. */
|
||||||
} GeneralAddressSpaceData;
|
} GeneralAddressSpaceData;
|
||||||
|
struct ProtoCanModbusData{
|
||||||
|
uint16_t StrAdr;
|
||||||
|
uint16_t *Data;
|
||||||
|
unsigned RegCount:4;
|
||||||
|
} ModbusData;
|
||||||
|
struct ProtoCanErrorData{
|
||||||
|
uint16_t Info;
|
||||||
|
uint16_t Code;
|
||||||
|
} ErrorData;
|
||||||
} ProtoCanData_t;
|
} ProtoCanData_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ struct RXMsg rxMsg[PROTOCAN_RX_BUFFER_SIZE];
|
|||||||
*/
|
*/
|
||||||
_Bool IsLeapYear(uint8_t year)
|
_Bool IsLeapYear(uint8_t year)
|
||||||
{
|
{
|
||||||
year+=2000;
|
year += 2000;
|
||||||
return (year%400==0)||((year%4==0)&&(year%100!=0));
|
return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,12 +33,13 @@ _Bool IsLeapYear(uint8_t year)
|
|||||||
*/
|
*/
|
||||||
uint16_t AvailableCanRxMsg(void)
|
uint16_t AvailableCanRxMsg(void)
|
||||||
{
|
{
|
||||||
return ((uint16_t)(PROTOCAN_RX_BUFFER_SIZE + (LastStep - CurrentStep + 1)))%PROTOCAN_RX_BUFFER_SIZE;
|
return ((uint16_t)(PROTOCAN_RX_BUFFER_SIZE + (LastStep - CurrentStep + 1))) % PROTOCAN_RX_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PROTOCAN_DEINIT(uint8_t stage)
|
void PROTOCAN_DEINIT(uint8_t stage)
|
||||||
{
|
{
|
||||||
switch(stage) {
|
switch(stage)
|
||||||
|
{
|
||||||
case 3:
|
case 3:
|
||||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||||
HAL_TIM_UnRegisterCallback(_HTIM, HAL_TIM_PERIOD_ELAPSED_CB_ID);
|
HAL_TIM_UnRegisterCallback(_HTIM, HAL_TIM_PERIOD_ELAPSED_CB_ID);
|
||||||
@@ -60,11 +61,13 @@ void PROTOCAN_DEINIT(uint8_t stage)
|
|||||||
PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_HandleTypeDef *tmp_hrtc, TIM_HandleTypeDef *tmp_tim)
|
PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_HandleTypeDef *tmp_hrtc, TIM_HandleTypeDef *tmp_tim)
|
||||||
{
|
{
|
||||||
unsigned initStage = 0;
|
unsigned initStage = 0;
|
||||||
if(tmp_hcan) {
|
if(tmp_hcan)
|
||||||
|
{
|
||||||
_HCAN = tmp_hcan;
|
_HCAN = tmp_hcan;
|
||||||
#if (USE_HAL_CAN_REGISTER_CALLBACKS == 1)
|
#if (USE_HAL_CAN_REGISTER_CALLBACKS == 1)
|
||||||
HAL_StatusTypeDef CAN_RC_RESULT = HAL_CAN_RegisterCallback(_HCAN, HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID, ProtoCanRxFifo0MsgPendingCallback);
|
HAL_StatusTypeDef CAN_RC_RESULT = HAL_CAN_RegisterCallback(_HCAN, HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID, ProtoCanRxFifo0MsgPendingCallback);
|
||||||
if(CAN_RC_RESULT != HAL_OK) {
|
if(CAN_RC_RESULT != HAL_OK)
|
||||||
|
{
|
||||||
PROTOCAN_DEINIT(initStage);
|
PROTOCAN_DEINIT(initStage);
|
||||||
return PROTOCAN_INIT_HRTC_ERROR;
|
return PROTOCAN_INIT_HRTC_ERROR;
|
||||||
}
|
}
|
||||||
@@ -74,23 +77,30 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_Handl
|
|||||||
return PROTOCAN_INIT_HCAN_ERROR;
|
return PROTOCAN_INIT_HCAN_ERROR;
|
||||||
}
|
}
|
||||||
initStage++;
|
initStage++;
|
||||||
if(tmp_hrtc) {
|
if(tmp_hrtc)
|
||||||
|
{
|
||||||
_HRTC = tmp_hrtc;
|
_HRTC = tmp_hrtc;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
PROTOCAN_DEINIT(initStage);
|
PROTOCAN_DEINIT(initStage);
|
||||||
return PROTOCAN_INIT_HRTC_ERROR;
|
return PROTOCAN_INIT_HRTC_ERROR;
|
||||||
}
|
}
|
||||||
initStage++;
|
initStage++;
|
||||||
if(tmp_tim) {
|
if(tmp_tim)
|
||||||
|
{
|
||||||
_HTIM = tmp_tim;
|
_HTIM = tmp_tim;
|
||||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||||
HAL_StatusTypeDef TIM_RC_RESULT = HAL_TIM_RegisterCallback(_HTIM, HAL_TIM_PERIOD_ELAPSED_CB_ID, ProtoCanPulseCallback);
|
HAL_StatusTypeDef TIM_RC_RESULT = HAL_TIM_RegisterCallback(_HTIM, HAL_TIM_PERIOD_ELAPSED_CB_ID, ProtoCanPulseCallback);
|
||||||
if(TIM_RC_RESULT != HAL_OK) {
|
if(TIM_RC_RESULT != HAL_OK)
|
||||||
|
{
|
||||||
PROTOCAN_DEINIT(initStage);
|
PROTOCAN_DEINIT(initStage);
|
||||||
return PROTOCAN_INIT_HRTC_ERROR;
|
return PROTOCAN_INIT_HRTC_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
PROTOCAN_DEINIT(initStage);
|
PROTOCAN_DEINIT(initStage);
|
||||||
return PROTOCAN_INIT_TIM_ERROR;
|
return PROTOCAN_INIT_TIM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -111,19 +121,6 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_Handl
|
|||||||
*/
|
*/
|
||||||
void PROTOCAN_LOOP(void)
|
void PROTOCAN_LOOP(void)
|
||||||
{
|
{
|
||||||
ProtoCanId_t testId;
|
|
||||||
testId.BitAll = 0;
|
|
||||||
testId.Fields.Priority = PROTOCAN_PRIORITY_STANDARD;
|
|
||||||
testId.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
|
|
||||||
testId.Fields.DeviceType = CURRENT_TYPE_DEVICE;
|
|
||||||
testId.Fields.DeviceID = CURRENT_ID_DEVICE;
|
|
||||||
testId.Fields.MsgType = PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE;
|
|
||||||
|
|
||||||
ProtoCanData_t testData;
|
|
||||||
uint16_t massiv[] = {0xABCD, 0x1234, 0xAFBF, 0x5678, 0x9AF1};
|
|
||||||
testData.GeneralAddressSpaceData.Data = massiv;
|
|
||||||
testData.GeneralAddressSpaceData.RegCount = 5;
|
|
||||||
testData.GeneralAddressSpaceData.RegStartAdr = 0xFA;
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
if(AvailableCanRxMsg())
|
if(AvailableCanRxMsg())
|
||||||
@@ -157,7 +154,6 @@ void PROTOCAN_LOOP(void)
|
|||||||
}
|
}
|
||||||
CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE;
|
CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
PROTOCAN_SEND(testId, testData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,20 +221,17 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastStatus(struct RXMsg _rxMsg)
|
|||||||
tmp_eID.Fields.DeviceType = CURRENT_TYPE_DEVICE;
|
tmp_eID.Fields.DeviceType = CURRENT_TYPE_DEVICE;
|
||||||
tmp_eID.Fields.DeviceID = CURRENT_ID_DEVICE;
|
tmp_eID.Fields.DeviceID = CURRENT_ID_DEVICE;
|
||||||
TxHeader.ExtId = tmp_eID.BitAll;
|
TxHeader.ExtId = tmp_eID.BitAll;
|
||||||
|
|
||||||
RTC_TimeTypeDef sTime = {0};
|
RTC_TimeTypeDef sTime = {0};
|
||||||
HAL_RTC_GetTime(_HRTC, &sTime, RTC_FORMAT_BIN);
|
HAL_RTC_GetTime(_HRTC, &sTime, RTC_FORMAT_BIN);
|
||||||
data[0] = sTime.Hours;
|
data[0] = sTime.Hours;
|
||||||
data[1] = sTime.Minutes;
|
data[1] = sTime.Minutes;
|
||||||
data[2] = sTime.Seconds;
|
data[2] = sTime.Seconds;
|
||||||
|
|
||||||
RTC_DateTypeDef DateToUpdate = {0};
|
RTC_DateTypeDef DateToUpdate = {0};
|
||||||
HAL_RTC_GetDate(_HRTC, &DateToUpdate, RTC_FORMAT_BIN);
|
HAL_RTC_GetDate(_HRTC, &DateToUpdate, RTC_FORMAT_BIN);
|
||||||
data[3] = DateToUpdate.Year;
|
data[3] = DateToUpdate.Year;
|
||||||
data[4] = DateToUpdate.Month;
|
data[4] = DateToUpdate.Month;
|
||||||
data[5] = DateToUpdate.Date;
|
data[5] = DateToUpdate.Date;
|
||||||
data[6] = DateToUpdate.WeekDay;
|
data[6] = DateToUpdate.WeekDay;
|
||||||
|
|
||||||
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,9 +266,9 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastRestart(struct RXMsg _rxMsg)
|
|||||||
uint64_t page = 0;
|
uint64_t page = 0;
|
||||||
for(int i = 0; i < _rxMsg.DLC; i++)
|
for(int i = 0; i < _rxMsg.DLC; i++)
|
||||||
{
|
{
|
||||||
page+=(_rxMsg.Data[i]<<(i*8));
|
page += (_rxMsg.Data[i] << (i * 8));
|
||||||
}
|
}
|
||||||
if((page>>CURRENT_ID_DEVICE)&0b1)
|
if((page >> CURRENT_ID_DEVICE) & 0b1)
|
||||||
{
|
{
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
}
|
}
|
||||||
@@ -291,9 +284,12 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastRestart(struct RXMsg _rxMsg)
|
|||||||
*/
|
*/
|
||||||
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastRtcSetup(struct RXMsg _rxMsg)
|
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastRtcSetup(struct RXMsg _rxMsg)
|
||||||
{
|
{
|
||||||
if(_rxMsg.DLC > 7) {
|
if(_rxMsg.DLC > 7)
|
||||||
|
{
|
||||||
return PROTOCAN_ERROR;
|
return PROTOCAN_ERROR;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int DaysCount_Normal[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
int DaysCount_Normal[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
||||||
if( _rxMsg.Data[0] > 23 ||
|
if( _rxMsg.Data[0] > 23 ||
|
||||||
@@ -302,10 +298,12 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastRtcSetup(struct RXMsg _rxMsg
|
|||||||
_rxMsg.Data[3] > 99 ||
|
_rxMsg.Data[3] > 99 ||
|
||||||
_rxMsg.Data[4] > 12 ||
|
_rxMsg.Data[4] > 12 ||
|
||||||
_rxMsg.Data[5] > DaysCount_Normal[IsLeapYear(_rxMsg.Data[3])][_rxMsg.Data[4]] ||
|
_rxMsg.Data[5] > DaysCount_Normal[IsLeapYear(_rxMsg.Data[3])][_rxMsg.Data[4]] ||
|
||||||
_rxMsg.Data[6] > 6) {
|
_rxMsg.Data[6] > 6)
|
||||||
|
{
|
||||||
return PROTOCAN_ERROR;
|
return PROTOCAN_ERROR;
|
||||||
//ERROR
|
}
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
PROTOCAN_RTC_SYNC(_rxMsg.Data);
|
PROTOCAN_RTC_SYNC(_rxMsg.Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -323,7 +321,8 @@ PROTOCAN_StatusTypeDef PROTOCAN_DiscreticProcessing(struct RXMsg _rxMsg)
|
|||||||
{
|
{
|
||||||
msgBodyDiscreteType msg;
|
msgBodyDiscreteType msg;
|
||||||
msg.Body = _rxMsg.eID.Fields.MsgBody;
|
msg.Body = _rxMsg.eID.Fields.MsgBody;
|
||||||
switch(msg.Fields.Type){
|
switch(msg.Fields.Type)
|
||||||
|
{
|
||||||
case PROTOCAN_DISCRETE_ACCIDENT:
|
case PROTOCAN_DISCRETE_ACCIDENT:
|
||||||
{
|
{
|
||||||
ProtoCanMsgToDiscreteAccident(_rxMsg);
|
ProtoCanMsgToDiscreteAccident(_rxMsg);
|
||||||
@@ -660,14 +659,14 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToGeneralAddressSpace(struct RXMsg _rxM
|
|||||||
data[3] = '-';
|
data[3] = '-';
|
||||||
for(int i = 0; i < 4; i++)
|
for(int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
unsigned sym = (_rxMsg.eID.Fields.MsgBody>>(12-(i*4)))&0xF;
|
unsigned sym = (_rxMsg.eID.Fields.MsgBody >> (12 - (i * 4))) & 0xF;
|
||||||
if(sym >= 10)
|
if(sym >= 10)
|
||||||
{
|
{
|
||||||
data[4+i] = sym%10+'A';
|
data[4 + i] = sym % 10 + 'A';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data[4+i] = sym+'0';
|
data[4 + i] = sym + '0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
||||||
@@ -712,8 +711,8 @@ PROTOCAN_StatusTypeDef PROTOCAN_SEND_GENERAL_ADDRESS_SPACE(ProtoCanId_t id, uint
|
|||||||
|
|
||||||
for(int i = 0; i < regsInPacket; i++)
|
for(int i = 0; i < regsInPacket; i++)
|
||||||
{
|
{
|
||||||
canData[(i*2)+1] = LowByteOfWord(data[currentIndex+i]);
|
canData[(i * 2)] = LowByteOfWord(data[currentIndex + i]);
|
||||||
canData[(i*2)] = HighByteOfWord(data[currentIndex+i]);
|
canData[(i * 2) + 1] = HighByteOfWord(data[currentIndex + i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox);
|
HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox);
|
||||||
@@ -896,6 +895,85 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToModbusInput(struct RXMsg _rxMsg)
|
|||||||
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
int PROTOCAN_SEND_MODBUS(const ProtoCanId_t* id, const struct ProtoCanModbusData* modbusData)
|
||||||
|
{
|
||||||
|
if (!id || !modbusData)
|
||||||
|
{
|
||||||
|
return PROTOCAN_ERROR;
|
||||||
|
}
|
||||||
|
ProtoCanId_t localId = *id;
|
||||||
|
uint8_t msgType = localId.Fields.MsgType;
|
||||||
|
// Структура для отправки
|
||||||
|
CAN_TxHeaderTypeDef TxHeader;
|
||||||
|
uint32_t TxMailBox = 0;
|
||||||
|
uint8_t canData[8];
|
||||||
|
if(msgType == PROTOCAN_MSGTYPE_MODBUS_COIL || msgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE)
|
||||||
|
{
|
||||||
|
// Формируем body
|
||||||
|
msgBodyModbusType body;
|
||||||
|
body.Fields.StrAdr = modbusData->StrAdr;
|
||||||
|
body.Fields.RegCount = modbusData->RegCount;
|
||||||
|
// Устанавливаем коллизию ExtId с body.Body
|
||||||
|
localId.Fields.MsgBody = (body.Body & 0xFFFF);
|
||||||
|
// Обновляем ExtId
|
||||||
|
TxHeader.ExtId = localId.BitAll;
|
||||||
|
// Остальные настройки
|
||||||
|
TxHeader.IDE = CAN_ID_EXT; // Предположим, что используете расширенные ID
|
||||||
|
TxHeader.RTR = CAN_RTR_DATA;
|
||||||
|
TxHeader.TransmitGlobalTime = DISABLE;
|
||||||
|
TxHeader.DLC = modbusData->RegCount % 8 + 1;
|
||||||
|
// Формируем CAN данные
|
||||||
|
canData[0] = (*modbusData->Data) & 0xFF;
|
||||||
|
canData[1] = (*modbusData->Data >> 8) & 0xFF;
|
||||||
|
if (HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox) != HAL_OK)
|
||||||
|
{
|
||||||
|
return PROTOCAN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(msgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING || msgType == PROTOCAN_MSGTYPE_MODBUS_INPUT)
|
||||||
|
{
|
||||||
|
uint16_t* dataPtr = modbusData->Data;
|
||||||
|
unsigned totalRegs = modbusData->RegCount;
|
||||||
|
unsigned regsProcessed = 0;
|
||||||
|
unsigned startAddress = modbusData->StrAdr;
|
||||||
|
while (regsProcessed < totalRegs)
|
||||||
|
{
|
||||||
|
uint8_t regsInPacket = (totalRegs - regsProcessed) > 4 ? 4 : (totalRegs - regsProcessed);
|
||||||
|
// Формируем body
|
||||||
|
msgBodyModbusType body;
|
||||||
|
body.Fields.StrAdr = startAddress;
|
||||||
|
body.Fields.RegCount = regsInPacket;
|
||||||
|
// Обновляем ExtId
|
||||||
|
localId.Fields.MsgBody = (body.Body & 0xFFFF);
|
||||||
|
TxHeader.ExtId = localId.BitAll;
|
||||||
|
TxHeader.IDE = CAN_ID_EXT;
|
||||||
|
TxHeader.RTR = CAN_RTR_DATA;
|
||||||
|
TxHeader.TransmitGlobalTime = DISABLE;
|
||||||
|
TxHeader.DLC = regsInPacket * 2;
|
||||||
|
// Добавляем регистры
|
||||||
|
for (int i = 0; i < regsInPacket; i++)
|
||||||
|
{
|
||||||
|
canData[i * 2] = LowByteOfWord(dataPtr[regsProcessed + i]);
|
||||||
|
canData[i * 2 + 1] = HighByteOfWord(dataPtr[regsProcessed + i]);
|
||||||
|
}
|
||||||
|
// Отправляем сообщение
|
||||||
|
if(HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox) != HAL_OK)
|
||||||
|
{
|
||||||
|
return PROTOCAN_ERROR;
|
||||||
|
}
|
||||||
|
regsProcessed += regsInPacket;
|
||||||
|
startAddress += regsInPacket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PROTOCAN_ERROR; // Неверный тип сообщения
|
||||||
|
}
|
||||||
|
return PROTOCAN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief __weak Функция отправки сообщения об ошибке.
|
* @brief __weak Функция отправки сообщения об ошибке.
|
||||||
* Посылает CAN сообщение с кодом ошибки. Используется, когда необходимо оповестить о неуспешной операции.
|
* Посылает CAN сообщение с кодом ошибки. Используется, когда необходимо оповестить о неуспешной операции.
|
||||||
@@ -961,17 +1039,14 @@ void ProtoCanRxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
|||||||
//Расширенный ID
|
//Расширенный ID
|
||||||
if(RxHeader.IDE == CAN_ID_EXT)
|
if(RxHeader.IDE == CAN_ID_EXT)
|
||||||
{
|
{
|
||||||
if(!((PROTOCAN_RX_BUFFER_SIZE + LastStep - (CurrentStep-1))&PROTOCAN_RX_BUFFER_SIZE))
|
if(!((PROTOCAN_RX_BUFFER_SIZE + LastStep - (CurrentStep - 1)) & PROTOCAN_RX_BUFFER_SIZE))
|
||||||
{
|
{
|
||||||
//Буффер переполнен
|
//Буффер переполнен
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t tmp_LastStep = (uint16_t)(LastStep + 1) % PROTOCAN_RX_BUFFER_SIZE;
|
uint16_t tmp_LastStep = (uint16_t)(LastStep + 1) % PROTOCAN_RX_BUFFER_SIZE;
|
||||||
|
|
||||||
ProtoCanId_t ExtID_Of_RX_MSG;
|
ProtoCanId_t ExtID_Of_RX_MSG;
|
||||||
ExtID_Of_RX_MSG.BitAll = RxHeader.ExtId;
|
ExtID_Of_RX_MSG.BitAll = RxHeader.ExtId;
|
||||||
|
|
||||||
//Полученное сообщение - пульс устройств в сети
|
//Полученное сообщение - пульс устройств в сети
|
||||||
if(ExtID_Of_RX_MSG.Fields.MsgType == PROTOCAN_MSGTYPE_PULSE)
|
if(ExtID_Of_RX_MSG.Fields.MsgType == PROTOCAN_MSGTYPE_PULSE)
|
||||||
{
|
{
|
||||||
@@ -979,7 +1054,6 @@ void ProtoCanRxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
|||||||
Device_on_the_Network[ExtID_Of_RX_MSG.Fields.DeviceType][ExtID_Of_RX_MSG.Fields.DeviceID].TimeFromLastPulse = 0;
|
Device_on_the_Network[ExtID_Of_RX_MSG.Fields.DeviceType][ExtID_Of_RX_MSG.Fields.DeviceID].TimeFromLastPulse = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep);
|
TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1031,16 +1105,13 @@ void PROTOCAN_RTC_SYNC(uint8_t *data)
|
|||||||
__HAL_RTC_WRITEPROTECTION_DISABLE(_HRTC);
|
__HAL_RTC_WRITEPROTECTION_DISABLE(_HRTC);
|
||||||
RTC_TimeTypeDef sTime = {0};
|
RTC_TimeTypeDef sTime = {0};
|
||||||
RTC_DateTypeDef DateToUpdate = {0};
|
RTC_DateTypeDef DateToUpdate = {0};
|
||||||
|
|
||||||
sTime.Hours = data[0];
|
sTime.Hours = data[0];
|
||||||
sTime.Minutes = data[1];
|
sTime.Minutes = data[1];
|
||||||
sTime.Seconds = data[2];
|
sTime.Seconds = data[2];
|
||||||
|
|
||||||
if(HAL_RTC_SetTime(_HRTC, &sTime, RTC_FORMAT_BIN) != HAL_OK)
|
if(HAL_RTC_SetTime(_HRTC, &sTime, RTC_FORMAT_BIN) != HAL_OK)
|
||||||
{
|
{
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
DateToUpdate.Year = data[3];
|
DateToUpdate.Year = data[3];
|
||||||
DateToUpdate.Month = data[4];
|
DateToUpdate.Month = data[4];
|
||||||
DateToUpdate.Date = data[5];
|
DateToUpdate.Date = data[5];
|
||||||
@@ -1068,15 +1139,12 @@ void PROTOCAN_CONFIG_FILTER(uint8_t filterBank, uint32_t idFilter, uint32_t idMa
|
|||||||
canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
|
canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
|
||||||
canFilterConfig.FilterActivation = ENABLE;
|
canFilterConfig.FilterActivation = ENABLE;
|
||||||
canFilterConfig.SlaveStartFilterBank = 14;
|
canFilterConfig.SlaveStartFilterBank = 14;
|
||||||
|
|
||||||
#define CAN_IDE_32 0b00000100 // Для 32-х битного масштаба
|
#define CAN_IDE_32 0b00000100 // Для 32-х битного масштаба
|
||||||
|
|
||||||
// Разбиваем 32-битный ID и маску для фильтрации на High и Low 16 бит
|
// Разбиваем 32-битный ID и маску для фильтрации на High и Low 16 бит
|
||||||
canFilterConfig.FilterIdHigh = (uint16_t)(((idFilter) >> 13)); // верхние 16 бит
|
canFilterConfig.FilterIdHigh = (uint16_t)(((idFilter) >> 13)); // верхние 16 бит
|
||||||
canFilterConfig.FilterIdLow = (uint16_t)((((idFilter) << 3)) | CAN_IDE_32); // низкие 16 бит,
|
canFilterConfig.FilterIdLow = (uint16_t)((((idFilter) << 3)) | CAN_IDE_32); // низкие 16 бит,
|
||||||
canFilterConfig.FilterMaskIdHigh = (uint16_t)(((idMask) >> 13));
|
canFilterConfig.FilterMaskIdHigh = (uint16_t)(((idMask) >> 13));
|
||||||
canFilterConfig.FilterMaskIdLow = (uint16_t)((((idMask) << 3)) | CAN_IDE_32);
|
canFilterConfig.FilterMaskIdLow = (uint16_t)((((idMask) << 3)) | CAN_IDE_32);
|
||||||
|
|
||||||
if(HAL_CAN_ConfigFilter(_HCAN, &canFilterConfig) != HAL_OK)
|
if(HAL_CAN_ConfigFilter(_HCAN, &canFilterConfig) != HAL_OK)
|
||||||
{
|
{
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
@@ -1131,6 +1199,18 @@ PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data)
|
|||||||
{
|
{
|
||||||
switch (id.Fields.MsgType)
|
switch (id.Fields.MsgType)
|
||||||
{
|
{
|
||||||
|
case PROTOCAN_MSGTYPE_BROADCAST:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PROTOCAN_MSGTYPE_DISCRETE:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PROTOCAN_MSGTYPE_ANALOG:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
case PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE:
|
case PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE:
|
||||||
{
|
{
|
||||||
/* Если есть регистры для отправки, указатель data должен быть валиден. */
|
/* Если есть регистры для отправки, указатель data должен быть валиден. */
|
||||||
@@ -1142,6 +1222,17 @@ PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data)
|
|||||||
data.GeneralAddressSpaceData.Data,
|
data.GeneralAddressSpaceData.Data,
|
||||||
data.GeneralAddressSpaceData.RegCount);
|
data.GeneralAddressSpaceData.RegCount);
|
||||||
}
|
}
|
||||||
|
case PROTOCAN_MSGTYPE_MODBUS_COIL:
|
||||||
|
case PROTOCAN_MSGTYPE_MODBUS_DISCRETE:
|
||||||
|
case PROTOCAN_MSGTYPE_MODBUS_HOLDING:
|
||||||
|
case PROTOCAN_MSGTYPE_MODBUS_INPUT:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PROTOCAN_MSGTYPE_ERROR:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return PROTOCAN_ERROR;
|
return PROTOCAN_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user