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"));
|
||||
|
||||
// Initialize HIDAPI
|
||||
/*May be not needed
|
||||
int res = hid_init();
|
||||
if (res == 0)
|
||||
{
|
||||
|
@ -26,6 +27,7 @@ void USkyPortalSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
|||
HidError = hid_error(NULL);
|
||||
UE_LOG(LogHIDApi, Error, TEXT("%s"), *HidError);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
@ -42,6 +44,34 @@ void USkyPortalSubsystem::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 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.
|
||||
"list" will point to the head of the linked list of devices,
|
||||
|
@ -90,7 +126,7 @@ bool USkyPortalSubsystem::ConnectPortal() {
|
|||
|
||||
// Free the device list
|
||||
hid_free_enumeration(list);
|
||||
bPortalConnected = true;
|
||||
//bPortalConnected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -128,8 +164,8 @@ void USkyPortalSubsystem::ChangePortalColor(const FLinearColor& Color)
|
|||
Write(&req);
|
||||
}
|
||||
|
||||
void USkyPortalSubsystem::Write(RWBlock* pb) {
|
||||
// TODO: Need to make this function async
|
||||
void USkyPortalSubsystem::Write(RWBlock *pb) {
|
||||
|
||||
if (!ensure(PortalDevice)) {
|
||||
UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found"));
|
||||
return;
|
||||
|
@ -137,18 +173,19 @@ void USkyPortalSubsystem::Write(RWBlock* pb) {
|
|||
|
||||
pb->buf[0] = 0; // Use report 0
|
||||
|
||||
/*
|
||||
|
||||
for (int attempt = 0; attempt < 10; attempt++) {
|
||||
if (hid_write(PortalDevice, pb->buf, 0x21) == -1) {
|
||||
Sleep(100);
|
||||
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, Verbose, TEXT("Writed"));
|
||||
//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) {
|
||||
return false;
|
||||
|
@ -285,3 +322,30 @@ bool USkyPortalSubsystem::ReadBlock(unsigned int block, unsigned char data[0x10]
|
|||
ensureMsgf(false, TEXT("PortalIO: Failed to read block after multiple retries"));
|
||||
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()
|
||||
|
||||
//Portal ref used in the subsystem
|
||||
hid_device* PortalDevice;
|
||||
|
||||
public:
|
||||
// Override initialization and deinitialization methods
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override;
|
||||
|
||||
|
||||
|
||||
// Connect to Portal, return false if portal is not found
|
||||
UFUNCTION(BlueprintCallable, CallInEditor, meta = (Category = "SkyPortal"))
|
||||
bool ConnectPortal();
|
||||
|
||||
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
|
||||
bool bPortalConnected = false;
|
||||
|
||||
|
@ -42,14 +49,13 @@ public:
|
|||
|
||||
|
||||
|
||||
|
||||
unsigned char PortalStatus();
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
//Portal ref used in the subsystem
|
||||
hid_device* PortalDevice;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char buf[rw_buf_size]; int BytesTransferred;
|
||||
|
@ -58,12 +64,17 @@ private:
|
|||
|
||||
static void Sleep(int sleepMs);
|
||||
|
||||
void ActivatePortal(int active);
|
||||
|
||||
void RestartPortal();
|
||||
|
||||
|
||||
// Block/byte related data write/read functions
|
||||
bool OpenPortalHandle();
|
||||
bool ReadBlock(unsigned int block, unsigned char data[0x10], int skylander);
|
||||
bool WriteBlock(unsigned int, unsigned char[0x10], int);
|
||||
bool CheckResponse(RWBlock* res, char expect);
|
||||
void Write(RWBlock* pb);
|
||||
bool CheckResponse(RWBlock *, char);
|
||||
void Write(RWBlock *);
|
||||
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Reference in a new issue