UKSVEP_23550.2/Core/Bootloader/boot_can.c

128 lines
3.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "boot_can.h"
CAN_HandleTypeDef hcan_boot;
/**
* @brief Инициализация CAN для бутлоадера (по defines)
*/
void MX_BOOT_CAN_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
CAN_FilterTypeDef sFilterConfig;
/* Включаем тактирование */
__RCC_CAN_BOOT_CLK_ENABLE();
__RCC_CAN_PORT_CLK_ENABLE();
/* Настройка пинов RX/TX */
GPIO_InitStruct.Pin = CAN_PIN_RX;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(CAN_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = CAN_PIN_TX;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(CAN_PORT, &GPIO_InitStruct);
/* Настройка CAN */
hcan_boot.Instance = CAN_BOOT;
hcan_boot.Init.Prescaler = CAN_SPEED_PRESCALER;
hcan_boot.Init.Mode = CAN_MODE;
hcan_boot.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan_boot.Init.TimeSeg1 = CAN_SPEED_BS1;
hcan_boot.Init.TimeSeg2 = CAN_SPEED_BS2;
hcan_boot.Init.TimeTriggeredMode = DISABLE;
hcan_boot.Init.AutoBusOff = DISABLE;
hcan_boot.Init.AutoWakeUp = DISABLE;
hcan_boot.Init.AutoRetransmission = ENABLE;
hcan_boot.Init.ReceiveFifoLocked = DISABLE;
hcan_boot.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan_boot) != HAL_OK)
{
Error_Handler();
}
/* Настройка фильтра: пропускать все сообщения */
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
if (HAL_CAN_ConfigFilter(&hcan_boot, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
/* Запускаем CAN */
if (HAL_CAN_Start(&hcan_boot) != HAL_OK)
{
Error_Handler();
}
}
// -----------------------------
// CAN: приём страницы + CRC с таймаутом
// -----------------------------
void Bootloader_CAN_Receive_Page(Bootloader_t *bl)
{
uint16_t bytes_received = 0;
uint8_t crc_buf[4];
CAN_RxHeaderTypeDef canHeader;
uint8_t canData[8];
uint32_t start_tick = HAL_GetTick();
// Приём данных страницы
while(bytes_received < PAGE_SIZE)
{
if(HAL_CAN_GetRxFifoFillLevel(bl->hcan, CAN_RX_FIFO0) > 0)
{
if(HAL_CAN_GetRxMessage(bl->hcan, CAN_RX_FIFO0, &canHeader, canData) == HAL_OK)
{
uint8_t len = canHeader.DLC;
if(bytes_received + len > PAGE_SIZE)
len = PAGE_SIZE - bytes_received;
memcpy(&bl->fw_buffer[bytes_received], canData, len);
bytes_received += len;
start_tick = HAL_GetTick(); // сброс таймера
}
}
// проверка таймаута
if(HAL_GetTick() - start_tick >= FW_RECEIVE_TIMEOUT_MS)
{
bl->state = BL_STATE_ERROR;
return;
}
}
// Приём CRC (следующий CAN пакет)
while(1)
{
if(HAL_CAN_GetRxFifoFillLevel(bl->hcan, CAN_RX_FIFO0) > 0)
{
if(HAL_CAN_GetRxMessage(bl->hcan, CAN_RX_FIFO0, &canHeader, canData) == HAL_OK)
{
// первые 4 байта = CRC
bl->fw_crc = (canData[0] << 24) | (canData[1] << 16) | (canData[2] << 8) | canData[3];
break;
}
}
if(HAL_GetTick() - start_tick >= FW_RECEIVE_TIMEOUT_MS)
{
bl->state = BL_STATE_ERROR;
return;
}
}
bl->fw_len = bytes_received;
bl->state = BL_STATE_IDLE;
}