blob: 35a926a3af43aac19658df99445a0eefcddc37c9 [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -08002/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */
Brian Silverman41cdd3e2019-01-19 19:48:58 -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#include <hal/HALBase.h>
17
18using namespace frc;
19
20CAN::CAN(int deviceId) {
21 int32_t status = 0;
22 m_handle =
23 HAL_InitializeCAN(kTeamManufacturer, deviceId, kTeamDeviceType, &status);
24 if (status != 0) {
25 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
26 m_handle = HAL_kInvalidHandle;
27 return;
28 }
29
30 HAL_Report(HALUsageReporting::kResourceType_CAN, deviceId);
31}
32
33CAN::CAN(int deviceId, int deviceManufacturer, int deviceType) {
34 int32_t status = 0;
35 m_handle = HAL_InitializeCAN(
36 static_cast<HAL_CANManufacturer>(deviceManufacturer), deviceId,
37 static_cast<HAL_CANDeviceType>(deviceType), &status);
38 if (status != 0) {
39 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
40 m_handle = HAL_kInvalidHandle;
41 return;
42 }
43
44 HAL_Report(HALUsageReporting::kResourceType_CAN, deviceId);
45}
46
47CAN::~CAN() {
48 if (StatusIsFatal()) return;
49 if (m_handle != HAL_kInvalidHandle) {
50 HAL_CleanCAN(m_handle);
51 m_handle = HAL_kInvalidHandle;
52 }
53}
54
Brian Silverman41cdd3e2019-01-19 19:48:58 -080055void CAN::WritePacket(const uint8_t* data, int length, int apiId) {
56 int32_t status = 0;
57 HAL_WriteCANPacket(m_handle, data, length, apiId, &status);
58 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
59}
60
61void CAN::WritePacketRepeating(const uint8_t* data, int length, int apiId,
62 int repeatMs) {
63 int32_t status = 0;
64 HAL_WriteCANPacketRepeating(m_handle, data, length, apiId, repeatMs, &status);
65 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
66}
67
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080068void CAN::WriteRTRFrame(int length, int apiId) {
69 int32_t status = 0;
70 HAL_WriteCANRTRFrame(m_handle, length, apiId, &status);
71 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
72}
73
Brian Silverman41cdd3e2019-01-19 19:48:58 -080074void CAN::StopPacketRepeating(int apiId) {
75 int32_t status = 0;
76 HAL_StopCANPacketRepeating(m_handle, apiId, &status);
77 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
78}
79
80bool CAN::ReadPacketNew(int apiId, CANData* data) {
81 int32_t status = 0;
82 HAL_ReadCANPacketNew(m_handle, apiId, data->data, &data->length,
83 &data->timestamp, &status);
84 if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
85 return false;
86 }
87 if (status != 0) {
88 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
89 return false;
90 } else {
91 return true;
92 }
93}
94
95bool CAN::ReadPacketLatest(int apiId, CANData* data) {
96 int32_t status = 0;
97 HAL_ReadCANPacketLatest(m_handle, apiId, data->data, &data->length,
98 &data->timestamp, &status);
99 if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
100 return false;
101 }
102 if (status != 0) {
103 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
104 return false;
105 } else {
106 return true;
107 }
108}
109
110bool CAN::ReadPacketTimeout(int apiId, int timeoutMs, CANData* data) {
111 int32_t status = 0;
112 HAL_ReadCANPacketTimeout(m_handle, apiId, data->data, &data->length,
113 &data->timestamp, timeoutMs, &status);
114 if (status == HAL_CAN_TIMEOUT ||
115 status == HAL_ERR_CANSessionMux_MessageNotFound) {
116 return false;
117 }
118 if (status != 0) {
119 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
120 return false;
121 } else {
122 return true;
123 }
124}