mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +00:00
[hal] Expose CAN timestamp base clock (#5357)
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
package edu.wpi.first.hal;
|
||||
|
||||
public class CANAPIJNI extends JNIWrapper {
|
||||
public static native long getCANPacketBaseTime();
|
||||
|
||||
public static native int initializeCAN(int manufacturer, int deviceId, int deviceType);
|
||||
|
||||
public static native void cleanCAN(int handle);
|
||||
|
||||
@@ -6,16 +6,19 @@ package edu.wpi.first.hal;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public class CANData {
|
||||
/** Contents of the CAN frame. */
|
||||
public final byte[] data = new byte[8];
|
||||
/** Length of the frame in bytes. */
|
||||
public int length;
|
||||
/** CAN frame timestamp in milliseconds. */
|
||||
public long timestamp;
|
||||
|
||||
/**
|
||||
* API used from JNI to set the data.
|
||||
*
|
||||
* @param length Length of packet in bytes.
|
||||
* @param timestamp CAN frame timestamp in microseconds.
|
||||
* @return Buffer containing CAN frame.
|
||||
* @param timestamp CAN frame timestamp in milliseconds.
|
||||
* @return Buffer to place CAN frame data in.
|
||||
*/
|
||||
@SuppressWarnings("PMD.MethodReturnsInternalArray")
|
||||
public byte[] setData(int length, long timestamp) {
|
||||
|
||||
@@ -35,15 +35,6 @@ struct CANStorage {
|
||||
static UnlimitedHandleResource<HAL_CANHandle, CANStorage, HAL_HandleEnum::CAN>*
|
||||
canHandles;
|
||||
|
||||
static uint32_t GetPacketBaseTime() {
|
||||
timespec t;
|
||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||
|
||||
// Convert t to milliseconds
|
||||
uint64_t ms = t.tv_sec * 1000ull + t.tv_nsec / 1000000ull;
|
||||
return ms & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
namespace hal::init {
|
||||
void InitializeCANAPI() {
|
||||
static UnlimitedHandleResource<HAL_CANHandle, CANStorage, HAL_HandleEnum::CAN>
|
||||
@@ -63,6 +54,15 @@ static int32_t CreateCANId(CANStorage* storage, int32_t apiId) {
|
||||
|
||||
extern "C" {
|
||||
|
||||
uint32_t HAL_GetCANPacketBaseTime(void) {
|
||||
timespec t;
|
||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||
|
||||
// Convert t to milliseconds
|
||||
uint64_t ms = t.tv_sec * 1000ull + t.tv_nsec / 1000000ull;
|
||||
return ms & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
HAL_CANHandle HAL_InitializeCAN(HAL_CANManufacturer manufacturer,
|
||||
int32_t deviceId, HAL_CANDeviceType deviceType,
|
||||
int32_t* status) {
|
||||
@@ -267,7 +267,7 @@ void HAL_ReadCANPacketTimeout(HAL_CANHandle handle, int32_t apiId,
|
||||
auto i = can->receives.find(messageId);
|
||||
if (i != can->receives.end()) {
|
||||
// Found, check if new enough
|
||||
uint32_t now = GetPacketBaseTime();
|
||||
uint32_t now = HAL_GetCANPacketBaseTime();
|
||||
if (now - i->second.lastTimeStamp > static_cast<uint32_t>(timeoutMs)) {
|
||||
// Timeout, return bad status
|
||||
*status = HAL_CAN_TIMEOUT;
|
||||
|
||||
@@ -18,6 +18,18 @@ using namespace hal;
|
||||
using namespace wpi::java;
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: getCANPacketBaseTime
|
||||
* Signature: ()J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_edu_wpi_first_hal_CANAPIJNI_getCANPacketBaseTime
|
||||
(JNIEnv*, jclass)
|
||||
{
|
||||
return HAL_GetCANPacketBaseTime();
|
||||
}
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: initializeCAN
|
||||
|
||||
@@ -19,6 +19,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Reads the current value of the millisecond-resolution timer that the CAN API
|
||||
* functions use as a time base.
|
||||
*
|
||||
* @return Current value of timer used as a base time by the CAN API in
|
||||
* milliseconds.
|
||||
*/
|
||||
uint32_t HAL_GetCANPacketBaseTime(void);
|
||||
|
||||
/**
|
||||
* Initializes a CAN device.
|
||||
*
|
||||
@@ -111,8 +120,8 @@ void HAL_StopCANPacketRepeating(HAL_CANHandle handle, int32_t apiId,
|
||||
* @param[in] apiId the ID to read (0-1023)
|
||||
* @param[out] data the packet data (8 bytes)
|
||||
* @param[out] length the received length (0-8 bytes)
|
||||
* @param[out] receivedTimestamp the packet received timestamp (based off of
|
||||
* CLOCK_MONOTONIC)
|
||||
* @param[out] receivedTimestamp the packet received timestamp in ms (based off
|
||||
* of CLOCK_MONOTONIC)
|
||||
* @param[out] status Error status variable. 0 on success.
|
||||
*/
|
||||
void HAL_ReadCANPacketNew(HAL_CANHandle handle, int32_t apiId, uint8_t* data,
|
||||
@@ -127,8 +136,8 @@ void HAL_ReadCANPacketNew(HAL_CANHandle handle, int32_t apiId, uint8_t* data,
|
||||
* @param[in] apiId the ID to read (0-1023)
|
||||
* @param[out] data the packet data (8 bytes)
|
||||
* @param[out] length the received length (0-8 bytes)
|
||||
* @param[out] receivedTimestamp the packet received timestamp (based off of
|
||||
* CLOCK_MONOTONIC)
|
||||
* @param[out] receivedTimestamp the packet received timestamp in ms (based off
|
||||
* of CLOCK_MONOTONIC)
|
||||
* @param[out] status Error status variable. 0 on success.
|
||||
*/
|
||||
void HAL_ReadCANPacketLatest(HAL_CANHandle handle, int32_t apiId, uint8_t* data,
|
||||
@@ -144,8 +153,8 @@ void HAL_ReadCANPacketLatest(HAL_CANHandle handle, int32_t apiId, uint8_t* data,
|
||||
* @param[in] apiId the ID to read (0-1023)
|
||||
* @param[out] data the packet data (8 bytes)
|
||||
* @param[out] length the received length (0-8 bytes)
|
||||
* @param[out] receivedTimestamp the packet received timestamp (based off of
|
||||
* CLOCK_MONOTONIC)
|
||||
* @param[out] receivedTimestamp the packet received timestamp in ms (based off
|
||||
* of CLOCK_MONOTONIC)
|
||||
* @param[out] timeoutMs the timeout time for the packet
|
||||
* @param[out] status Error status variable. 0 on success.
|
||||
*/
|
||||
|
||||
@@ -35,13 +35,6 @@ struct CANStorage {
|
||||
static UnlimitedHandleResource<HAL_CANHandle, CANStorage, HAL_HandleEnum::CAN>*
|
||||
canHandles;
|
||||
|
||||
static uint32_t GetPacketBaseTime() {
|
||||
int status = 0;
|
||||
auto basetime = HAL_GetFPGATime(&status);
|
||||
// us to ms
|
||||
return (basetime / 1000ull) & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
namespace hal {
|
||||
namespace init {
|
||||
void InitializeCANAPI() {
|
||||
@@ -71,6 +64,13 @@ static int32_t CreateCANId(CANStorage* storage, int32_t apiId) {
|
||||
return createdId;
|
||||
}
|
||||
|
||||
uint32_t HAL_GetCANPacketBaseTime() {
|
||||
int status = 0;
|
||||
auto basetime = HAL_GetFPGATime(&status);
|
||||
// us to ms
|
||||
return (basetime / 1000ull) & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
HAL_CANHandle HAL_InitializeCAN(HAL_CANManufacturer manufacturer,
|
||||
int32_t deviceId, HAL_CANDeviceType deviceType,
|
||||
int32_t* status) {
|
||||
@@ -275,7 +275,7 @@ void HAL_ReadCANPacketTimeout(HAL_CANHandle handle, int32_t apiId,
|
||||
auto i = can->receives.find(messageId);
|
||||
if (i != can->receives.end()) {
|
||||
// Found, check if new enough
|
||||
uint32_t now = GetPacketBaseTime();
|
||||
uint32_t now = HAL_GetCANPacketBaseTime();
|
||||
if (now - i->second.lastTimeStamp > static_cast<uint32_t>(timeoutMs)) {
|
||||
// Timeout, return bad status
|
||||
*status = HAL_CAN_TIMEOUT;
|
||||
@@ -307,7 +307,7 @@ void HAL_ReadCANPeriodicPacket(HAL_CANHandle handle, int32_t apiId,
|
||||
auto i = can->receives.find(messageId);
|
||||
if (i != can->receives.end()) {
|
||||
// Found, check if new enough
|
||||
uint32_t now = GetPacketBaseTime();
|
||||
uint32_t now = HAL_GetCANPacketBaseTime();
|
||||
if (now - i->second.lastTimeStamp < static_cast<uint32_t>(periodMs)) {
|
||||
*status = 0;
|
||||
// Read the data from the stored message into the output
|
||||
@@ -337,7 +337,7 @@ void HAL_ReadCANPeriodicPacket(HAL_CANHandle handle, int32_t apiId,
|
||||
auto i = can->receives.find(messageId);
|
||||
if (i != can->receives.end()) {
|
||||
// Found, check if new enough
|
||||
uint32_t now = GetPacketBaseTime();
|
||||
uint32_t now = HAL_GetCANPacketBaseTime();
|
||||
if (now - i->second.lastTimeStamp > static_cast<uint32_t>(timeoutMs)) {
|
||||
// Timeout, return bad status
|
||||
*status = HAL_CAN_TIMEOUT;
|
||||
|
||||
@@ -131,3 +131,7 @@ bool CAN::ReadPacketTimeout(int apiId, int timeoutMs, CANData* data) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t CAN::GetTimestampBaseTime() {
|
||||
return HAL_GetCANPacketBaseTime();
|
||||
}
|
||||
|
||||
@@ -10,8 +10,11 @@
|
||||
|
||||
namespace frc {
|
||||
struct CANData {
|
||||
/** Contents of the CAN packet. */
|
||||
uint8_t data[8];
|
||||
/** Length of packet in bytes. */
|
||||
int32_t length;
|
||||
/** CAN frame timestamp in milliseconds. */
|
||||
uint64_t timestamp;
|
||||
};
|
||||
|
||||
@@ -158,6 +161,15 @@ class CAN {
|
||||
*/
|
||||
bool ReadPacketTimeout(int apiId, int timeoutMs, CANData* data);
|
||||
|
||||
/**
|
||||
* Reads the current value of the millisecond-resolution timer that CANData
|
||||
* timestamps are based on
|
||||
*
|
||||
* @return Current value of timer used as a base time for CANData timestamps
|
||||
* in milliseconds
|
||||
*/
|
||||
static uint64_t GetTimestampBaseTime();
|
||||
|
||||
static constexpr HAL_CANManufacturer kTeamManufacturer = HAL_CAN_Man_kTeamUse;
|
||||
static constexpr HAL_CANDeviceType kTeamDeviceType =
|
||||
HAL_CAN_Dev_kMiscellaneous;
|
||||
|
||||
@@ -172,4 +172,15 @@ public class CAN implements Closeable {
|
||||
public boolean readPacketTimeout(int apiId, int timeoutMs, CANData data) {
|
||||
return CANAPIJNI.readCANPacketTimeout(m_handle, apiId, timeoutMs, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current value of the millisecond-resolution timer that {@link CANData} timestamps are
|
||||
* based on.
|
||||
*
|
||||
* @return Current value of timer used as a base time for {@link CANData} timestamps in
|
||||
* milliseconds
|
||||
*/
|
||||
public static long getTimestampBaseTime() {
|
||||
return CANAPIJNI.getCANPacketBaseTime();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user