Функция отправки сообщений
Пока только 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_FILTERS(void);
|
||||
void PROTOCAN_LOOP(void);
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data);
|
||||
|
||||
void ProtoCanPulseCallback(TIM_HandleTypeDef *htim);
|
||||
void ProtoCanRxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
|
||||
|
||||
@@ -111,6 +111,19 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_Handl
|
||||
*/
|
||||
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)
|
||||
{
|
||||
if(AvailableCanRxMsg())
|
||||
@@ -144,6 +157,7 @@ void PROTOCAN_LOOP(void)
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
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