mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-22 01:11:42 +00:00
SPI and I2C simulator (#662)
* Creating SPI and I2C simulation abilities * Update the callback helpers to support different function callback types * Create callback type that uses a buffer * Created I2C/SPI data classes that manage the callbacks and don't do much of anything else * Ran format, cleaned up some issues
This commit is contained in:
committed by
Peter Johnson
parent
be77f9cb26
commit
3c842d8234
39
hal/src/main/native/include/MockData/I2CData.h
Normal file
39
hal/src/main/native/include/MockData/I2CData.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void HALSIM_ResetI2CData(int32_t index);
|
||||
|
||||
int32_t HALSIM_RegisterI2CInitializedCallback(int32_t index,
|
||||
HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify);
|
||||
void HALSIM_CancelI2CInitializedCallback(int32_t index, int32_t uid);
|
||||
HAL_Bool HALSIM_GetI2CInitialized(int32_t index);
|
||||
void HALSIM_SetI2CInitialized(int32_t index, HAL_Bool initialized);
|
||||
|
||||
int32_t HALSIM_RegisterI2CReadCallback(int32_t index,
|
||||
HAL_BufferCallback callback,
|
||||
void* param);
|
||||
void HALSIM_CancelI2CReadCallback(int32_t index, int32_t uid);
|
||||
|
||||
int32_t HALSIM_RegisterI2CWriteCallback(int32_t index,
|
||||
HAL_BufferCallback callback,
|
||||
void* param);
|
||||
void HALSIM_CancelI2CWriteCallback(int32_t index, int32_t uid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -12,15 +12,21 @@
|
||||
typedef void (*HAL_NotifyCallback)(const char* name, void* param,
|
||||
const struct HAL_Value* value);
|
||||
|
||||
typedef void (*HAL_BufferCallback)(const char* name, void* param,
|
||||
unsigned char* buffer, unsigned int count);
|
||||
|
||||
namespace hal {
|
||||
struct NotifyListener {
|
||||
NotifyListener() = default;
|
||||
NotifyListener(void* param_, HAL_NotifyCallback callback_)
|
||||
|
||||
template <typename CallbackFunction>
|
||||
struct HalCallbackListener {
|
||||
HalCallbackListener() = default;
|
||||
HalCallbackListener(void* param_, CallbackFunction callback_)
|
||||
: callback(callback_), param(param_) {}
|
||||
|
||||
explicit operator bool() const { return callback != nullptr; }
|
||||
|
||||
HAL_NotifyCallback callback;
|
||||
CallbackFunction callback;
|
||||
void* param;
|
||||
};
|
||||
|
||||
} // namespace hal
|
||||
|
||||
@@ -17,52 +17,121 @@
|
||||
namespace hal {
|
||||
// Vector which provides an integrated freelist for removal and reuse of
|
||||
// individual elements.
|
||||
class NotifyListenerVector {
|
||||
|
||||
template <typename ListenerType>
|
||||
class HalCallbackListenerVectorImpl {
|
||||
struct private_init {};
|
||||
|
||||
public:
|
||||
typedef typename std::vector<NotifyListener>::size_type size_type;
|
||||
typedef typename std::vector<HalCallbackListener<ListenerType>>::size_type
|
||||
size_type;
|
||||
|
||||
// Constructor for creating copies of the vector
|
||||
NotifyListenerVector(const NotifyListenerVector*, const private_init&);
|
||||
HalCallbackListenerVectorImpl(const HalCallbackListenerVectorImpl* copyFrom,
|
||||
const private_init&);
|
||||
|
||||
// Delete all default constructors so they cannot be used
|
||||
NotifyListenerVector& operator=(const NotifyListenerVector&) = delete;
|
||||
NotifyListenerVector() = delete;
|
||||
NotifyListenerVector(const NotifyListenerVector&) = delete;
|
||||
HalCallbackListenerVectorImpl& operator=(
|
||||
const HalCallbackListenerVectorImpl&) = delete;
|
||||
HalCallbackListenerVectorImpl() = delete;
|
||||
HalCallbackListenerVectorImpl(const HalCallbackListenerVectorImpl&) = delete;
|
||||
|
||||
// Create a new vector with a single callback inside of it
|
||||
NotifyListenerVector(void* param, HAL_NotifyCallback callback,
|
||||
unsigned int* newUid);
|
||||
HalCallbackListenerVectorImpl(void* param, ListenerType callback,
|
||||
unsigned int* newUid) {
|
||||
*newUid = emplace_back_impl(param, callback);
|
||||
}
|
||||
|
||||
size_type size() const { return m_vector.size(); }
|
||||
NotifyListener& operator[](size_type i) { return m_vector[i]; }
|
||||
const NotifyListener& operator[](size_type i) const { return m_vector[i]; }
|
||||
HalCallbackListener<ListenerType>& operator[](size_type i) {
|
||||
return m_vector[i];
|
||||
}
|
||||
const HalCallbackListener<ListenerType>& operator[](size_type i) const {
|
||||
return m_vector[i];
|
||||
}
|
||||
|
||||
// Add a new NotifyListener to a copy of the vector. If there are elements on
|
||||
// the freelist,
|
||||
// reuses the last one; otherwise adds to the end of the vector.
|
||||
// Returns the resulting element index (+1).
|
||||
std::shared_ptr<NotifyListenerVector> emplace_back(
|
||||
void* param, HAL_NotifyCallback callback, unsigned int* newUid);
|
||||
std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>> emplace_back(
|
||||
void* param, ListenerType callback, unsigned int* newUid);
|
||||
|
||||
// Removes the identified element by replacing it with a default-constructed
|
||||
// one. The element is added to the freelist for later reuse. Returns a copy
|
||||
std::shared_ptr<NotifyListenerVector> erase(unsigned int uid);
|
||||
std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>> erase(
|
||||
unsigned int uid);
|
||||
|
||||
private:
|
||||
std::vector<NotifyListener> m_vector;
|
||||
std::vector<HalCallbackListener<ListenerType>> m_vector;
|
||||
std::vector<unsigned int> m_free;
|
||||
|
||||
// Add a new NotifyListener to the vector. If there are elements on the
|
||||
// freelist,
|
||||
// reuses the last one; otherwise adds to the end of the vector.
|
||||
// Returns the resulting element index (+1).
|
||||
unsigned int emplace_back_impl(void* param, HAL_NotifyCallback callback);
|
||||
unsigned int emplace_back_impl(void* param, ListenerType callback);
|
||||
|
||||
// Removes the identified element by replacing it with a default-constructed
|
||||
// one. The element is added to the freelist for later reuse.
|
||||
void erase_impl(unsigned int uid);
|
||||
};
|
||||
|
||||
template <typename ListenerType>
|
||||
HalCallbackListenerVectorImpl<ListenerType>::HalCallbackListenerVectorImpl(
|
||||
const HalCallbackListenerVectorImpl<ListenerType>* copyFrom,
|
||||
const private_init&)
|
||||
: m_vector(copyFrom->m_vector), m_free(copyFrom->m_free) {}
|
||||
|
||||
template <typename ListenerType>
|
||||
std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>>
|
||||
HalCallbackListenerVectorImpl<ListenerType>::emplace_back(
|
||||
void* param, ListenerType callback, unsigned int* newUid) {
|
||||
auto newVector =
|
||||
std::make_shared<HalCallbackListenerVectorImpl<ListenerType>>(
|
||||
this, private_init());
|
||||
newVector->m_vector = m_vector;
|
||||
newVector->m_free = m_free;
|
||||
*newUid = newVector->emplace_back_impl(param, callback);
|
||||
return newVector;
|
||||
}
|
||||
|
||||
template <typename ListenerType>
|
||||
std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>>
|
||||
HalCallbackListenerVectorImpl<ListenerType>::erase(unsigned int uid) {
|
||||
auto newVector =
|
||||
std::make_shared<HalCallbackListenerVectorImpl<ListenerType>>(
|
||||
this, private_init());
|
||||
newVector->m_vector = m_vector;
|
||||
newVector->m_free = m_free;
|
||||
newVector->erase_impl(uid);
|
||||
return newVector;
|
||||
}
|
||||
|
||||
template <typename ListenerType>
|
||||
unsigned int HalCallbackListenerVectorImpl<ListenerType>::emplace_back_impl(
|
||||
void* param, ListenerType callback) {
|
||||
unsigned int uid;
|
||||
if (m_free.empty()) {
|
||||
uid = m_vector.size();
|
||||
m_vector.emplace_back(param, callback);
|
||||
} else {
|
||||
uid = m_free.back();
|
||||
m_free.pop_back();
|
||||
m_vector[uid] = HalCallbackListener<ListenerType>(param, callback);
|
||||
}
|
||||
return uid + 1;
|
||||
}
|
||||
|
||||
template <typename ListenerType>
|
||||
void HalCallbackListenerVectorImpl<ListenerType>::erase_impl(unsigned int uid) {
|
||||
--uid;
|
||||
if (uid >= m_vector.size() || !m_vector[uid]) return;
|
||||
m_free.push_back(uid);
|
||||
m_vector[uid] = HalCallbackListener<ListenerType>();
|
||||
}
|
||||
|
||||
typedef HalCallbackListenerVectorImpl<HAL_NotifyCallback> NotifyListenerVector;
|
||||
typedef HalCallbackListenerVectorImpl<HAL_BufferCallback> BufferListenerVector;
|
||||
|
||||
} // namespace hal
|
||||
|
||||
52
hal/src/main/native/include/MockData/SPIData.h
Normal file
52
hal/src/main/native/include/MockData/SPIData.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "HAL/HAL.h"
|
||||
#include "NotifyListener.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void HALSIM_ResetSPIData(int32_t index);
|
||||
|
||||
int32_t HALSIM_RegisterSPIInitializedCallback(int32_t index,
|
||||
HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify);
|
||||
void HALSIM_CancelSPIInitializedCallback(int32_t index, int32_t uid);
|
||||
HAL_Bool HALSIM_GetSPIInitialized(int32_t index);
|
||||
void HALSIM_SetSPIInitialized(int32_t index, HAL_Bool initialized);
|
||||
|
||||
int32_t HALSIM_RegisterSPIReadCallback(int32_t index,
|
||||
HAL_BufferCallback callback,
|
||||
void* param);
|
||||
void HALSIM_CancelSPIReadCallback(int32_t index, int32_t uid);
|
||||
|
||||
int32_t HALSIM_RegisterSPIWriteCallback(int32_t index,
|
||||
HAL_BufferCallback callback,
|
||||
void* param);
|
||||
void HALSIM_CancelSPIWriteCallback(int32_t index, int32_t uid);
|
||||
|
||||
int32_t HALSIM_RegisterSPIResetAccumulatorCallback(int32_t index,
|
||||
HAL_NotifyCallback callback,
|
||||
void* param,
|
||||
HAL_Bool initialNotify);
|
||||
void HALSIM_CancelSPIResetAccumulatorCallback(int32_t index, int32_t uid);
|
||||
|
||||
int32_t HALSIM_RegisterSPISetAccumulatorCallback(int32_t index,
|
||||
HAL_BufferCallback callback,
|
||||
void* param);
|
||||
void HALSIM_CancelSPISetAccumulatorCallback(int32_t index, int32_t uid);
|
||||
void HALSIM_SetSPISetAccumulatorValue(int32_t index, int64_t value);
|
||||
int64_t HALSIM_GetSPIGetAccumulatorValue(int32_t index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user