blob: 797b9ff4e39be28c3b1ae2402a579fa0ddf91e2a [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>
Brian Silverman41cdd3e2019-01-19 19:48:58 -080016
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) {
James Kuszmaul4b81d302019-12-14 20:53:14 -080024 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080025 m_handle = HAL_kInvalidHandle;
26 return;
27 }
28
James Kuszmaul4b81d302019-12-14 20:53:14 -080029 HAL_Report(HALUsageReporting::kResourceType_CAN, deviceId + 1);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080030}
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) {
James Kuszmaul4b81d302019-12-14 20:53:14 -080038 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080039 m_handle = HAL_kInvalidHandle;
40 return;
41 }
42
James Kuszmaul4b81d302019-12-14 20:53:14 -080043 HAL_Report(HALUsageReporting::kResourceType_CAN, deviceId + 1);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080044}
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
Brian Silverman41cdd3e2019-01-19 19:48:58 -080054void CAN::WritePacket(const uint8_t* data, int length, int apiId) {
55 int32_t status = 0;
56 HAL_WriteCANPacket(m_handle, data, length, apiId, &status);
James Kuszmaul4b81d302019-12-14 20:53:14 -080057 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080058}
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);
James Kuszmaul4b81d302019-12-14 20:53:14 -080064 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080065}
66
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080067void CAN::WriteRTRFrame(int length, int apiId) {
68 int32_t status = 0;
69 HAL_WriteCANRTRFrame(m_handle, length, apiId, &status);
James Kuszmaul4b81d302019-12-14 20:53:14 -080070 wpi_setHALError(status);
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080071}
72
Brian Silverman41cdd3e2019-01-19 19:48:58 -080073void CAN::StopPacketRepeating(int apiId) {
74 int32_t status = 0;
75 HAL_StopCANPacketRepeating(m_handle, apiId, &status);
James Kuszmaul4b81d302019-12-14 20:53:14 -080076 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080077}
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) {
James Kuszmaul4b81d302019-12-14 20:53:14 -080087 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080088 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) {
James Kuszmaul4b81d302019-12-14 20:53:14 -0800102 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800103 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) {
James Kuszmaul4b81d302019-12-14 20:53:14 -0800118 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800119 return false;
120 } else {
121 return true;
122 }
123}