Сгенерировано ИИ
This commit is contained in:
92
Src/DS_SN65HVD230.c
Normal file
92
Src/DS_SN65HVD230.c
Normal file
@@ -0,0 +1,92 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user