blob: 797b9ff4e39be28c3b1ae2402a579fa0ddf91e2a [file] [log] [blame]
Brian Silverman8fce7482020-01-05 13:18:21 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */
3/* 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
73void CAN::StopPacketRepeating(int apiId) {
74 int32_t status = 0;
75 HAL_StopCANPacketRepeating(m_handle, apiId, &status);
76 wpi_setHALError(status);
77}
78
79bool CAN::ReadPacketNew(int apiId, CANData* data) {
80 int32_t status = 0;
81 HAL_ReadCANPacketNew(m_handle, apiId, data->data, &data->length,
82 &data->timestamp, &status);
83 if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
84 return false;
85 }
86 if (status != 0) {
87 wpi_setHALError(status);
88 return false;
89 } else {
90 return true;
91 }
92}
93
94bool CAN::ReadPacketLatest(int apiId, CANData* data) {
95 int32_t status = 0;
96 HAL_ReadCANPacketLatest(m_handle, apiId, data->data, &data->length,
97 &data->timestamp, &status);
98 if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
99 return false;
100 }
101 if (status != 0) {
102 wpi_setHALError(status);
103 return false;
104 } else {
105 return true;
106 }
107}
108
109bool CAN::ReadPacketTimeout(int apiId, int timeoutMs, CANData* data) {
110 int32_t status = 0;
111 HAL_ReadCANPacketTimeout(m_handle, apiId, data->data, &data->length,
112 &data->timestamp, timeoutMs, &status);
113 if (status == HAL_CAN_TIMEOUT ||
114 status == HAL_ERR_CANSessionMux_MessageNotFound) {
115 return false;
116 }
117 if (status != 0) {
118 wpi_setHALError(status);
119 return false;
120 } else {
121 return true;
122 }
123}