Функция отправки сообщений
Пока только PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE
This commit is contained in:
@@ -255,6 +255,7 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan,
|
|||||||
void PROTOCAN_DEINIT(uint8_t stage);
|
void PROTOCAN_DEINIT(uint8_t stage);
|
||||||
void PROTOCAN_FILTERS(void);
|
void PROTOCAN_FILTERS(void);
|
||||||
void PROTOCAN_LOOP(void);
|
void PROTOCAN_LOOP(void);
|
||||||
|
PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data);
|
||||||
|
|
||||||
void ProtoCanPulseCallback(TIM_HandleTypeDef *htim);
|
void ProtoCanPulseCallback(TIM_HandleTypeDef *htim);
|
||||||
void ProtoCanRxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
|
void ProtoCanRxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
|
||||||
|
|||||||
@@ -111,6 +111,19 @@ 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())
|
||||||
@@ -144,6 +157,7 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,6 +673,60 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToGeneralAddressSpace(struct RXMsg _rxM
|
|||||||
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Отправляет произвольный диапазон регистров в пакетах по, максимум, 4 регистра за раз через CAN.
|
||||||
|
*
|
||||||
|
* Функция разбивает передаваемый массив регистров на пакеты по 4 или меньше и отправляет их по отдельности.
|
||||||
|
* Для каждого пакета формируется уникальный MsgBody, равный адресу первого регистра в пакете.
|
||||||
|
*
|
||||||
|
* @param priority Приоритет сообщения CAN. ProtoCan_Priority_TypeDef
|
||||||
|
* @param regStartAdr Адрес первого регистра из всего массива.
|
||||||
|
* @param data Указатель на массив регистров для отправки.
|
||||||
|
* @param regCount Общее количество регистров для отправки.
|
||||||
|
*
|
||||||
|
* @return Возвращает статус отправки: HAL_OK при успехе, или код ошибки HAL_StatusTypeDef при сбое.
|
||||||
|
*/
|
||||||
|
PROTOCAN_StatusTypeDef PROTOCAN_SEND_GENERAL_ADDRESS_SPACE(ProtoCanId_t id, uint16_t regStartAdr, uint16_t *data, uint8_t regCount)
|
||||||
|
{
|
||||||
|
CAN_TxHeaderTypeDef TxHeader;
|
||||||
|
uint32_t TxMailBox = 0;
|
||||||
|
uint8_t canData[8];
|
||||||
|
|
||||||
|
TxHeader.IDE = CAN_ID_EXT;
|
||||||
|
TxHeader.TransmitGlobalTime = DISABLE;
|
||||||
|
TxHeader.RTR = CAN_RTR_DATA;
|
||||||
|
|
||||||
|
ProtoCanId_t tmp_eID;
|
||||||
|
tmp_eID.BitAll = id.BitAll;
|
||||||
|
|
||||||
|
uint8_t regsRemaining = regCount;
|
||||||
|
uint8_t currentIndex = 0;
|
||||||
|
|
||||||
|
while(regsRemaining > 0)
|
||||||
|
{
|
||||||
|
uint8_t regsInPacket = (regsRemaining > 4) ? 4 : regsRemaining;
|
||||||
|
|
||||||
|
tmp_eID.Fields.MsgBody = regStartAdr + currentIndex;
|
||||||
|
TxHeader.ExtId = tmp_eID.BitAll;
|
||||||
|
TxHeader.DLC = regsInPacket*2;
|
||||||
|
|
||||||
|
for(int i = 0; i < regsInPacket; i++)
|
||||||
|
{
|
||||||
|
canData[(i*2)+1] = LowByteOfWord(data[currentIndex+i]);
|
||||||
|
canData[(i*2)] = HighByteOfWord(data[currentIndex+i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox);
|
||||||
|
|
||||||
|
if(status != HAL_OK)
|
||||||
|
{
|
||||||
|
return (PROTOCAN_StatusTypeDef)status;
|
||||||
|
}
|
||||||
|
|
||||||
|
regsRemaining -= regsInPacket;
|
||||||
|
currentIndex += regsInPacket;
|
||||||
|
}
|
||||||
|
return (PROTOCAN_StatusTypeDef)HAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1044,3 +1112,38 @@ void PROTOCAN_FILTERS()
|
|||||||
// Третий фильтр: проверяем 16-19 биты, равны PROTOCAN_MSGTYPE_PULSE
|
// Третий фильтр: проверяем 16-19 биты, равны PROTOCAN_MSGTYPE_PULSE
|
||||||
PROTOCAN_CONFIG_FILTER(2, filter3_id, filter3_mask);
|
PROTOCAN_CONFIG_FILTER(2, filter3_id, filter3_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Отправляет CAN-сообщение в зависимости от типа сообщения.
|
||||||
|
*
|
||||||
|
* Эта функция анализирует тип сообщения в идентификаторе и вызывает
|
||||||
|
* соответствующую функцию отправки. В текущей реализации поддерживается только
|
||||||
|
* тип PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE.
|
||||||
|
*
|
||||||
|
* @param id Идентификатор CAN-сообщения, содержащий информацию о типе.
|
||||||
|
* @param data Структура с данными, которые необходимо отправить. Зависит от типа сообщения.
|
||||||
|
*
|
||||||
|
* @return Статус выполнения операции:
|
||||||
|
* - PROTOCAN_OK при успешной отправке,
|
||||||
|
* - PROTOCAN_ERROR, если тип сообщения не поддерживается или произошла ошибка.
|
||||||
|
*/
|
||||||
|
PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data)
|
||||||
|
{
|
||||||
|
switch (id.Fields.MsgType)
|
||||||
|
{
|
||||||
|
case PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE:
|
||||||
|
{
|
||||||
|
/* Если есть регистры для отправки, указатель data должен быть валиден. */
|
||||||
|
if((data.GeneralAddressSpaceData.RegCount > 0U) && data.GeneralAddressSpaceData.Data == 0)
|
||||||
|
{
|
||||||
|
return PROTOCAN_ERROR;
|
||||||
|
}
|
||||||
|
return PROTOCAN_SEND_GENERAL_ADDRESS_SPACE(id, data.GeneralAddressSpaceData.RegStartAdr,
|
||||||
|
data.GeneralAddressSpaceData.Data,
|
||||||
|
data.GeneralAddressSpaceData.RegCount);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return PROTOCAN_ERROR;
|
||||||
|
}
|
||||||
|
return PROTOCAN_ERROR;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user