#define LOG_MODULE "extiodrv-extio" #include "extio.h" #include "core/log.h" // static uint8_t _extiodrv_extio_sensor_read_mode_map[5] = { // 1, // all // 2, // up // 3, // down // 4, // left // 5, // right // }; HRESULT extiodrv_extio_transfer( HANDLE handle, enum extiodrv_extio_sensor_read_mode sensor_read_mode, const struct extiodrv_extio_pad_lights pad_lights[EXTIO_PAD_LIGHT_MAX_PLAYERS], bool neons) { HRESULT hr; struct extio_cmd_write write; struct extio_cmd_read read; size_t bytes_written; size_t bytes_read; const uint8_t *raw; log_assert(handle != INVALID_HANDLE_VALUE); memset(&write, 0, sizeof(write)); // TODO this doesn't seem to work, yet // write.sensor_read_mode = // 0;//_extiodrv_extio_sensor_read_mode_map[sensor_read_mode]; 0 = all 1 = // mess? 2 = mess? 3 = mess? 4 = mess? 5 = mess? 6 = right sensor only 7 = // right sensor only 8 = right sensor only write.sensor_read_mode = 0; for (uint8_t i = 0; i < EXTIO_PAD_LIGHT_MAX_PLAYERS; i++) { write.pad_lights[i].up = pad_lights[i].up ? 1 : 0; write.pad_lights[i].down = pad_lights[i].down ? 1 : 0; write.pad_lights[i].left = pad_lights[i].left ? 1 : 0; write.pad_lights[i].right = pad_lights[i].right ? 1 : 0; } write.neons = neons ? 1 : 0; // This MUST be set but only on the p1 packet // Not setting it or also setting it on the p2 packet results in the EXTIO // not responding at all write.pad_lights[0].unknown_80 = 1; write.checksum = extio_cmd_checksum(&write); raw = (uint8_t *) &write; log_misc("Raw write paket: %X %X %X %X", raw[0], raw[1], raw[2], raw[3]); hr = extiodrv_device_write(handle, &write, sizeof(write), &bytes_written); if (FAILED(hr)) { log_warning("Writing extio device failed"); return hr; } if (bytes_written != sizeof(write)) { log_warning( "Writing extio device failed, expected bytes %d != actual bytes %d", (uint32_t) sizeof(write), (uint32_t) bytes_written); return HRESULT_FROM_WIN32(ERROR_BAD_LENGTH); } // Read loop to keep reading until a full message is read // There are various occasions, especially if polling from the host side is // faster than the device can put the response to the wire. this can result // in empty reads while (true) { hr = extiodrv_device_read(handle, &read, sizeof(read), &bytes_read); if (FAILED(hr)) { log_warning("Reading extio device failed"); return hr; } if (bytes_read < sizeof(read)) { log_misc("Empty read, retry read"); continue; } if (bytes_read != sizeof(read)) { log_warning( "Reading extio device failed, expected bytes %d != actual " "bytes %d", (uint32_t) sizeof(read), (uint32_t) bytes_read); return HRESULT_FROM_WIN32(ERROR_BAD_LENGTH); } break; } if (read.status != EXTIO_STATUS_OK) { log_warning("Status not ok: 0x%X", read.status); return HRESULT_FROM_WIN32(ERROR_GEN_FAILURE); } return S_OK; }