Files
DS_SN65HVD230/Src/DS_SN65HVD230.c

93 lines
3.6 KiB
C
Raw Permalink 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 "sn65hvd230_g0.h"
/**
* @brief Инициализация структуры и привязка к FDCAN в STM32G0
*/
HAL_StatusTypeDef SN65HVD230_Init(SN65HVD230_t *node, FDCAN_HandleTypeDef *hfdcan_handle) {
if (node == NULL || hfdcan_handle == NULL) {
return HAL_ERROR;
}
node->hfdcan = hfdcan_handle;
return HAL_OK;
}
/**
* @brief Запуск периферийного модуля FDCAN
*/
HAL_StatusTypeDef SN65HVD230_Start(SN65HVD230_t *node) {
if (node == NULL || node->hfdcan == NULL) return HAL_ERROR;
// Активируем прерывание по заполнению FIFO 0 (потребуется, если включите IT-режим в CubeMX)
HAL_FDCAN_ActivateNotification(node->hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
return HAL_FDCAN_Start(node->hfdcan);
}
/**
* @brief Остановка модуля FDCAN
*/
HAL_StatusTypeDef SN65HVD230_Stop(SN65HVD230_t *node) {
if (node == NULL || node->hfdcan == NULL) return HAL_ERROR;
return HAL_FDCAN_Stop(node->hfdcan);
}
/**
* @brief Отправка пакета данных в шину (Классический CAN-кадр через FDCAN)
*/
HAL_StatusTypeDef SN65HVD230_Transmit(SN65HVD230_t *node, CAN_Message_t *msg, uint32_t timeout_ms) {
if (node == NULL || node->hfdcan == NULL || msg == NULL) return HAL_ERROR;
uint32_t tickstart = HAL_GetTick();
FDCAN_TxHeaderTypeDef TxHeader;
// Конфигурация заголовка кадра в стиле G0 FDCAN
TxHeader.Identifier = msg->Identifier;
TxHeader.IdType = msg->IdType;
TxHeader.TxFrameType = msg->TxFrameType;
TxHeader.DataLength = msg->DataLength; // Константы типа FDCAN_DLC_BYTES_8
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_OFF; // Выключаем ускорение данных (для классического CAN)
TxHeader.FDFormat = FDCAN_CLASSIC_CAN; // Работаем в режиме совместимости с обычным CAN
TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
TxHeader.MessageMarker = 0;
// Ожидаем, пока в TX FIFO освободится хотя бы одна ячейка
while (HAL_FDCAN_GetTxFifoFreeLevel(node->hfdcan) == 0) {
if ((HAL_GetTick() - tickstart) > timeout_ms) {
return HAL_TIMEOUT;
}
}
// Помещаем сообщение в очередь отправки FDCAN
return HAL_FDCAN_AddMessageToTxFifoQ(node->hfdcan, &TxHeader, msg->Data);
}
/**
* @brief Опрашивающий (блокирующий) прием кадра из FIFO 0
*/
HAL_StatusTypeDef SN65HVD230_Receive(SN65HVD230_t *node, CAN_Message_t *msg, uint32_t timeout_ms) {
if (node == NULL || node->hfdcan == NULL || msg == NULL) return HAL_ERROR;
uint32_t tickstart = HAL_GetTick();
FDCAN_RxHeaderTypeDef RxHeader;
// Ожидаем появления нового сообщения в FIFO 0
while (HAL_FDCAN_GetRxFifoFillLevel(node->hfdcan, FDCAN_RX_FIFO0) == 0) {
if ((HAL_GetTick() - tickstart) > timeout_ms) {
return HAL_TIMEOUT;
}
}
// Вычитываем данные из FIFO 0
if (HAL_FDCAN_GetRxMessage(node->hfdcan, FDCAN_RX_FIFO0, &RxHeader, msg->Data) == HAL_OK) {
msg->Identifier = RxHeader.Identifier;
msg->IdType = RxHeader.IdType;
msg->TxFrameType = RxHeader.RxFrameType;
msg->DataLength = RxHeader.DataLength;
return HAL_OK;
}
return HAL_ERROR;
}