blob: aa0370f861130a54ef30a48b3d12c40260515c70 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5#include "frc/CAN.h"
6
7#include <utility>
8
9#include <hal/CAN.h>
10#include <hal/CANAPI.h>
11#include <hal/Errors.h>
12#include <hal/FRCUsageReporting.h>
13
Austin Schuh812d0d12021-11-04 20:16:48 -070014#include "frc/Errors.h"
15
Brian Silverman8fce7482020-01-05 13:18:21 -080016using namespace frc;
17
18CAN::CAN(int deviceId) {
19 int32_t status = 0;
20 m_handle =
21 HAL_InitializeCAN(kTeamManufacturer, deviceId, kTeamDeviceType, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070022 FRC_CheckErrorStatus(status, "device id {}", deviceId);
Brian Silverman8fce7482020-01-05 13:18:21 -080023
24 HAL_Report(HALUsageReporting::kResourceType_CAN, deviceId + 1);
25}
26
27CAN::CAN(int deviceId, int deviceManufacturer, int deviceType) {
28 int32_t status = 0;
29 m_handle = HAL_InitializeCAN(
30 static_cast<HAL_CANManufacturer>(deviceManufacturer), deviceId,
31 static_cast<HAL_CANDeviceType>(deviceType), &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070032 FRC_CheckErrorStatus(status, "device id {} mfg {} type {}", deviceId,
33 deviceManufacturer, deviceType);
Brian Silverman8fce7482020-01-05 13:18:21 -080034
35 HAL_Report(HALUsageReporting::kResourceType_CAN, deviceId + 1);
36}
37
38CAN::~CAN() {
Brian Silverman8fce7482020-01-05 13:18:21 -080039 if (m_handle != HAL_kInvalidHandle) {
40 HAL_CleanCAN(m_handle);
41 m_handle = HAL_kInvalidHandle;
42 }
43}
44
45void CAN::WritePacket(const uint8_t* data, int length, int apiId) {
46 int32_t status = 0;
47 HAL_WriteCANPacket(m_handle, data, length, apiId, &status);
James Kuszmaulcf324122023-01-14 14:07:17 -080048 FRC_CheckErrorStatus(status, "WritePacket");
Brian Silverman8fce7482020-01-05 13:18:21 -080049}
50
51void CAN::WritePacketRepeating(const uint8_t* data, int length, int apiId,
52 int repeatMs) {
53 int32_t status = 0;
54 HAL_WriteCANPacketRepeating(m_handle, data, length, apiId, repeatMs, &status);
James Kuszmaulcf324122023-01-14 14:07:17 -080055 FRC_CheckErrorStatus(status, "WritePacketRepeating");
Brian Silverman8fce7482020-01-05 13:18:21 -080056}
57
58void CAN::WriteRTRFrame(int length, int apiId) {
59 int32_t status = 0;
60 HAL_WriteCANRTRFrame(m_handle, length, apiId, &status);
James Kuszmaulcf324122023-01-14 14:07:17 -080061 FRC_CheckErrorStatus(status, "WriteRTRFrame");
Brian Silverman8fce7482020-01-05 13:18:21 -080062}
63
Austin Schuh1e69f942020-11-14 15:06:14 -080064int CAN::WritePacketNoError(const uint8_t* data, int length, int apiId) {
65 int32_t status = 0;
66 HAL_WriteCANPacket(m_handle, data, length, apiId, &status);
67 return status;
68}
69
70int CAN::WritePacketRepeatingNoError(const uint8_t* data, int length, int apiId,
71 int repeatMs) {
72 int32_t status = 0;
73 HAL_WriteCANPacketRepeating(m_handle, data, length, apiId, repeatMs, &status);
74 return status;
75}
76
77int CAN::WriteRTRFrameNoError(int length, int apiId) {
78 int32_t status = 0;
79 HAL_WriteCANRTRFrame(m_handle, length, apiId, &status);
80 return status;
81}
82
Brian Silverman8fce7482020-01-05 13:18:21 -080083void CAN::StopPacketRepeating(int apiId) {
84 int32_t status = 0;
85 HAL_StopCANPacketRepeating(m_handle, apiId, &status);
James Kuszmaulcf324122023-01-14 14:07:17 -080086 FRC_CheckErrorStatus(status, "StopPacketRepeating");
Brian Silverman8fce7482020-01-05 13:18:21 -080087}
88
89bool CAN::ReadPacketNew(int apiId, CANData* data) {
90 int32_t status = 0;
91 HAL_ReadCANPacketNew(m_handle, apiId, data->data, &data->length,
92 &data->timestamp, &status);
93 if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
94 return false;
95 }
96 if (status != 0) {
James Kuszmaulcf324122023-01-14 14:07:17 -080097 FRC_CheckErrorStatus(status, "ReadPacketNew");
Brian Silverman8fce7482020-01-05 13:18:21 -080098 return false;
99 } else {
100 return true;
101 }
102}
103
104bool CAN::ReadPacketLatest(int apiId, CANData* data) {
105 int32_t status = 0;
106 HAL_ReadCANPacketLatest(m_handle, apiId, data->data, &data->length,
107 &data->timestamp, &status);
108 if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
109 return false;
110 }
111 if (status != 0) {
James Kuszmaulcf324122023-01-14 14:07:17 -0800112 FRC_CheckErrorStatus(status, "ReadPacketLatest");
Brian Silverman8fce7482020-01-05 13:18:21 -0800113 return false;
114 } else {
115 return true;
116 }
117}
118
119bool CAN::ReadPacketTimeout(int apiId, int timeoutMs, CANData* data) {
120 int32_t status = 0;
121 HAL_ReadCANPacketTimeout(m_handle, apiId, data->data, &data->length,
122 &data->timestamp, timeoutMs, &status);
123 if (status == HAL_CAN_TIMEOUT ||
124 status == HAL_ERR_CANSessionMux_MessageNotFound) {
125 return false;
126 }
127 if (status != 0) {
James Kuszmaulcf324122023-01-14 14:07:17 -0800128 FRC_CheckErrorStatus(status, "ReadPacketTimeout");
Brian Silverman8fce7482020-01-05 13:18:21 -0800129 return false;
130 } else {
131 return true;
132 }
133}
James Kuszmaulb13e13f2023-11-22 20:44:04 -0800134
135uint64_t CAN::GetTimestampBaseTime() {
136 return HAL_GetCANPacketBaseTime();
137}