wip: implement portalIO
TODO : Fix the write IO timing issue
This commit is contained in:
parent
2360897978
commit
ed7b37b4fe
2 changed files with 101 additions and 26 deletions
|
@ -14,6 +14,7 @@ void USkyPortalSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||||||
UE_LOG(LogTemp, Log, TEXT("SkyPortalSubsystem Initialized"));
|
UE_LOG(LogTemp, Log, TEXT("SkyPortalSubsystem Initialized"));
|
||||||
|
|
||||||
// Initialize HIDAPI
|
// Initialize HIDAPI
|
||||||
|
/*May be not needed
|
||||||
int res = hid_init();
|
int res = hid_init();
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +27,7 @@ void USkyPortalSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||||||
HidError = hid_error(NULL);
|
HidError = hid_error(NULL);
|
||||||
UE_LOG(LogHIDApi, Error, TEXT("%s"), *HidError);
|
UE_LOG(LogHIDApi, Error, TEXT("%s"), *HidError);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +44,34 @@ void USkyPortalSubsystem::Deinitialize()
|
||||||
Super::Deinitialize();
|
Super::Deinitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Antenna up / activate
|
||||||
|
void USkyPortalSubsystem::ActivatePortal(int active)
|
||||||
|
{
|
||||||
|
RWBlock req, res;
|
||||||
|
|
||||||
|
memset(req.buf, 0, rw_buf_size);
|
||||||
|
req.buf[1] = 'A';
|
||||||
|
req.buf[2] = active;
|
||||||
|
do { Write(&req); } while (CheckResponse(&res, 'A'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start portal
|
||||||
|
void USkyPortalSubsystem::RestartPortal()
|
||||||
|
{
|
||||||
|
RWBlock req, res;
|
||||||
|
|
||||||
|
memset(req.buf, 0, rw_buf_size);
|
||||||
|
req.buf[1] = 'R';
|
||||||
|
|
||||||
|
// Wait until the device is ready
|
||||||
|
while (PortalStatus() == 0) {
|
||||||
|
FPlatformProcess::Sleep(0.05f); // Sleep for 50ms and try again
|
||||||
|
}
|
||||||
|
|
||||||
|
do { Write(&req); } while (CheckResponse(&res, 'R'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -49,7 +79,13 @@ Number of endpoints : 2
|
||||||
found an IN End Point 0 with attributes interrupt and address 0x1
|
found an IN End Point 0 with attributes interrupt and address 0x1
|
||||||
found an OUT End Point 1 with attributes interrupt and address 0x1
|
found an OUT End Point 1 with attributes interrupt and address 0x1
|
||||||
*/
|
*/
|
||||||
bool USkyPortalSubsystem::ConnectPortal() {
|
bool USkyPortalSubsystem::OpenPortalHandle() {
|
||||||
|
|
||||||
|
//reset
|
||||||
|
if (PortalDevice) {
|
||||||
|
hid_close(PortalDevice);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Declare two pointers to hold information about HID devices.
|
Declare two pointers to hold information about HID devices.
|
||||||
"list" will point to the head of the linked list of devices,
|
"list" will point to the head of the linked list of devices,
|
||||||
|
@ -90,7 +126,7 @@ bool USkyPortalSubsystem::ConnectPortal() {
|
||||||
|
|
||||||
// Free the device list
|
// Free the device list
|
||||||
hid_free_enumeration(list);
|
hid_free_enumeration(list);
|
||||||
bPortalConnected = true;
|
//bPortalConnected = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,27 +164,28 @@ void USkyPortalSubsystem::ChangePortalColor(const FLinearColor& Color)
|
||||||
Write(&req);
|
Write(&req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USkyPortalSubsystem::Write(RWBlock* pb) {
|
void USkyPortalSubsystem::Write(RWBlock *pb) {
|
||||||
// TODO: Need to make this function async
|
|
||||||
if (!ensure(PortalDevice)) {
|
|
||||||
UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pb->buf[0] = 0; // Use report 0
|
if (!ensure(PortalDevice)) {
|
||||||
|
UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found"));
|
||||||
/*
|
|
||||||
for (int attempt = 0; attempt < 10; attempt++) {
|
|
||||||
if (hid_write(PortalDevice, pb->buf, 0x21) == -1) {
|
|
||||||
Sleep(100);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*/
|
pb->buf[0] = 0; // Use report 0
|
||||||
ensureMsgf(hid_write(PortalDevice, pb->buf, 0x21) != -1, TEXT("Unable to write to Portal, %s"), hid_error(PortalDevice));
|
|
||||||
UE_LOG(LogSkyportalIO, Verbose, TEXT("Writed"));
|
|
||||||
|
for (int attempt = 0; attempt < 10; attempt++) {
|
||||||
|
if (hid_write(PortalDevice, pb->buf, 0x21) == -1) {
|
||||||
|
UE_LOG(LogSkyportalIO, Warning, TEXT("Attempt %d: Failed to write to Portal, retrying..."), attempt + 1);
|
||||||
|
FPlatformProcess::Sleep(0.1f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
UE_LOG(LogSkyportalIO, Verbose, TEXT("Successfully wrote to the Portal on attempt %d."), attempt + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//ensureMsgf(hid_write(PortalDevice, pb->buf, 0x21) != -1, TEXT("Unable to write to Portal, %s"), hid_error(PortalDevice));
|
||||||
|
UE_LOG(LogSkyportalIO, Error, TEXT("Unable to write to Portal after multiple attempts. error:\n %s"), hid_error(PortalDevice));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,7 +194,7 @@ void USkyPortalSubsystem::Sleep(int sleepMs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool USkyPortalSubsystem::CheckResponse(RWBlock* res, char expect)
|
bool USkyPortalSubsystem::CheckResponse(RWBlock *res, char expect)
|
||||||
{
|
{
|
||||||
if (!PortalDevice) {
|
if (!PortalDevice) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -284,4 +321,31 @@ bool USkyPortalSubsystem::ReadBlock(unsigned int block, unsigned char data[0x10]
|
||||||
UE_LOG(LogSkyportalIO, Fatal, TEXT("PortalIO:ReadBlock failed after retries"));
|
UE_LOG(LogSkyportalIO, Fatal, TEXT("PortalIO:ReadBlock failed after retries"));
|
||||||
ensureMsgf(false, TEXT("PortalIO: Failed to read block after multiple retries"));
|
ensureMsgf(false, TEXT("PortalIO: Failed to read block after multiple retries"));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool USkyPortalSubsystem::ConnectPortal()
|
||||||
|
{
|
||||||
|
|
||||||
|
bPortalConnected = OpenPortalHandle();
|
||||||
|
if (bPortalConnected) {
|
||||||
|
RestartPortal();
|
||||||
|
ActivatePortal(1);
|
||||||
|
ChangePortalColor(FLinearColor(0xC8, 0xC8, 0xC8));
|
||||||
|
|
||||||
|
UE_LOG(LogSkyportalIO, Log, TEXT("Portal Status: %d\n"), PortalStatus());
|
||||||
|
}
|
||||||
|
return bPortalConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char USkyPortalSubsystem::PortalStatus()
|
||||||
|
{
|
||||||
|
RWBlock req, res;
|
||||||
|
|
||||||
|
memset(req.buf, 0, rw_buf_size);
|
||||||
|
req.buf[1] = 'S';
|
||||||
|
do { Write(&req); } while (CheckResponse(&res, 'S'));
|
||||||
|
|
||||||
|
return res.buf[1];
|
||||||
}
|
}
|
|
@ -22,15 +22,22 @@ class SKYPORTAL_API USkyPortalSubsystem : public UEngineSubsystem
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
//Portal ref used in the subsystem
|
||||||
|
hid_device* PortalDevice;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Override initialization and deinitialization methods
|
// Override initialization and deinitialization methods
|
||||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||||
virtual void Deinitialize() override;
|
virtual void Deinitialize() override;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Connect to Portal, return false if portal is not found
|
// Connect to Portal, return false if portal is not found
|
||||||
UFUNCTION(BlueprintCallable, CallInEditor, meta = (Category = "SkyPortal"))
|
UFUNCTION(BlueprintCallable, CallInEditor, meta = (Category = "SkyPortal"))
|
||||||
bool ConnectPortal();
|
bool ConnectPortal();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
|
||||||
bool bPortalConnected = false;
|
bool bPortalConnected = false;
|
||||||
|
|
||||||
|
@ -42,14 +49,13 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char PortalStatus();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//Portal ref used in the subsystem
|
|
||||||
hid_device* PortalDevice;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char buf[rw_buf_size]; int BytesTransferred;
|
unsigned char buf[rw_buf_size]; int BytesTransferred;
|
||||||
|
@ -58,12 +64,17 @@ private:
|
||||||
|
|
||||||
static void Sleep(int sleepMs);
|
static void Sleep(int sleepMs);
|
||||||
|
|
||||||
|
void ActivatePortal(int active);
|
||||||
|
|
||||||
|
void RestartPortal();
|
||||||
|
|
||||||
|
|
||||||
// Block/byte related data write/read functions
|
// Block/byte related data write/read functions
|
||||||
|
bool OpenPortalHandle();
|
||||||
bool ReadBlock(unsigned int block, unsigned char data[0x10], int skylander);
|
bool ReadBlock(unsigned int block, unsigned char data[0x10], int skylander);
|
||||||
bool WriteBlock(unsigned int, unsigned char[0x10], int);
|
bool WriteBlock(unsigned int, unsigned char[0x10], int);
|
||||||
bool CheckResponse(RWBlock* res, char expect);
|
bool CheckResponse(RWBlock *, char);
|
||||||
void Write(RWBlock* pb);
|
void Write(RWBlock *);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in a new issue