blob: e56e435514cd853f2d752217bc3f5d6c0688070b [file] [log] [blame]
Brian Silverman8fce7482020-01-05 13:18:21 -08001/*----------------------------------------------------------------------------*/
Austin Schuh1e69f942020-11-14 15:06:14 -08002/* Copyright (c) 2018-2020 FIRST. All Rights Reserved. */
Brian Silverman8fce7482020-01-05 13:18:21 -08003/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "frc/CAN.h"
9
10#include <utility>
11
12#include <hal/CAN.h>
13#include <hal/CANAPI.h>
14#include <hal/Errors.h>
15#include <hal/FRCUsageReporting.h>
16
17using namespace frc;
18
19CAN::CAN(int deviceId) {
20 int32_t status = 0;
21 m_handle =
22 HAL_InitializeCAN(kTeamManufacturer, deviceId, kTeamDeviceType, &status);
23 if (status != 0) {
24 wpi_setHALError(status);
25 m_handle = HAL_kInvalidHandle;
26 return;
27 }
28
29 HAL_Report(HALUsageReporting::kResourceType_CAN, deviceId + 1);
30}
31
32CAN::CAN(int deviceId, int deviceManufacturer, int deviceType) {
33 int32_t status = 0;
34 m_handle = HAL_InitializeCAN(
35 static_cast<HAL_CANManufacturer>(deviceManufacturer), deviceId,
36 static_cast<HAL_CANDeviceType>(deviceType), &status);
37 if (status != 0) {
38 wpi_setHALError(status);
39 m_handle = HAL_kInvalidHandle;
40 return;
41 }
42
43 HAL_Report(HALUsageReporting::kResourceType_CAN, deviceId + 1);
44}
45
46CAN::~CAN() {
47 if (StatusIsFatal()) return;
48 if (m_handle != HAL_kInvalidHandle) {
49 HAL_CleanCAN(m_handle);
50 m_handle = HAL_kInvalidHandle;
51 }
52}
53
54void CAN::WritePacket(const uint8_t* data, int length, int apiId) {
55 int32_t status = 0;
56 HAL_WriteCANPacket(m_handle, data, length, apiId, &status);
57 wpi_setHALError(status);
58}
59
60void CAN::WritePacketRepeating(const uint8_t* data, int length, int apiId,
61 int repeatMs) {
62 int32_t status = 0;
63 HAL_WriteCANPacketRepeating(m_handle, data, length, apiId, repeatMs, &status);
64 wpi_setHALError(status);
65}
66
67void CAN::WriteRTRFrame(int length, int apiId) {
68 int32_t status = 0;
69 HAL_WriteCANRTRFrame(m_handle, length, apiId, &status);
70 wpi_setHALError(status);
71}
72
Austin Schuh1e69f942020-11-14 15:06:14 -080073int CAN::WritePacketNoError(const uint8_t* data, int length, int apiId) {
74 int32_t status = 0;
75 HAL_WriteCANPacket(m_handle, data, length, apiId, &status);
76 return status;
77}
78
79int CAN::WritePacketRepeatingNoError(const uint8_t* data, int length, int apiId,
80 int repeatMs) {
81 int32_t status = 0;
82 HAL_WriteCANPacketRepeating(m_handle, data, length, apiId, repeatMs, &status);
83 return status;
84}
85
86int CAN::WriteRTRFrameNoError(int length, int apiId) {
87 int32_t status = 0;
88 HAL_WriteCANRTRFrame(m_handle, length, apiId, &status);
89 return status;
90}
91
Brian Silverman8fce7482020-01-05 13:18:21 -080092void CAN::StopPacketRepeating(int apiId) {
93 int32_t status = 0;
94 HAL_StopCANPacketRepeating(m_handle, apiId, &status);
95 wpi_setHALError(status);
96}
97
98bool CAN::ReadPacketNew(int apiId, CANData* data) {
99 int32_t status = 0;
100 HAL_ReadCANPacketNew(m_handle, apiId, data->data, &data->length,
101 &data->timestamp, &status);
102 if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
103 return false;
104 }
105 if (status != 0) {
106 wpi_setHALError(status);
107 return false;
108 } else {
109 return true;
110 }
111}
112
113bool CAN::ReadPacketLatest(int apiId, CANData* data) {
114 int32_t status = 0;
115 HAL_ReadCANPacketLatest(m_handle, apiId, data->data, &data->length,
116 &data->timestamp, &status);
117 if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
118 return false;
119 }
120 if (status != 0) {
121 wpi_setHALError(status);
122 return false;
123 } else {
124 return true;
125 }
126}
127
128bool CAN::ReadPacketTimeout(int apiId, int timeoutMs, CANData* data) {
129 int32_t status = 0;
130 HAL_ReadCANPacketTimeout(m_handle, apiId, data->data, &data->length,
131 &data->timestamp, timeoutMs, &status);
132 if (status == HAL_CAN_TIMEOUT ||
133 status == HAL_ERR_CANSessionMux_MessageNotFound) {
134 return false;
135 }
136 if (status != 0) {
137 wpi_setHALError(status);
138 return false;
139 } else {
140 return true;
141 }
142}