diff --git a/src/monocoque/devices/CMakeLists.txt b/src/monocoque/devices/CMakeLists.txt index 914f18a..8b70ff8 100644 --- a/src/monocoque/devices/CMakeLists.txt +++ b/src/monocoque/devices/CMakeLists.txt @@ -7,6 +7,8 @@ set(devices_source_files sounddevice.c serialdevice.h serialdevice.c + serialadapter.h + serialadapter.c tachdevice.h tachdevice.c wheeldevice.h diff --git a/src/monocoque/devices/hapticeffect.c b/src/monocoque/devices/hapticeffect.c index 0bf949a..90911ec 100644 --- a/src/monocoque/devices/hapticeffect.c +++ b/src/monocoque/devices/hapticeffect.c @@ -90,9 +90,10 @@ int loadtyreconfig(SimData* simdata, char* configfile) { if(simdata->car[0] != '\0' && car[0] != '\0') { + slogt("%s %s %i %i", simdata->car, car, simdata->simexe, sim); if (strcicmp(car, simdata->car) == 0 && sim == simdata->simexe) { - slogt("found saved car %s with tyre diameters %f %f %f %f", car, tyre0, tyre1, tyre2, tyre3); + slogi("found saved car %s with tyre diameters %f %f %f %f", car, tyre0, tyre1, tyre2, tyre3); simdata->tyrediameter[0] = tyre0; simdata->tyrediameter[1] = tyre1; simdata->tyrediameter[2] = tyre2; diff --git a/src/monocoque/devices/serial/arduino.c b/src/monocoque/devices/serial/arduino.c index 68c4abc..a2c135e 100644 --- a/src/monocoque/devices/serial/arduino.c +++ b/src/monocoque/devices/serial/arduino.c @@ -4,6 +4,7 @@ #include #include "arduino.h" +#include "../serialadapter.h" #include "../../slog/slog.h" #define arduino_timeout 5000 @@ -11,92 +12,14 @@ int arduino_update(SerialDevice* serialdevice, void* data, size_t size) { int result = 1; - if (serialdevice->port) - { - slogt("copying %i bytes to arduino device", size); - result = check(sp_blocking_write(serialdevice->port, data, size, arduino_timeout)); - } + slogt("copying %i bytes to arduino device", size); + result = monocoque_serial_write(serialdevice->id, data, size, arduino_timeout); return result; } -//int arduino_shiftlights_update(SerialDevice* serialdevice, SimData* simdata) -//{ -// int result = 1; -// if (serialdevice->port) -// { -// result = check(sp_blocking_write(serialdevice->port, simdata, sizeof(SimData), arduino_timeout)); -// } -// -// return result; -//} -// -//int arduino_simwind_update(SerialDevice* serialdevice, SimData* simdata) -//{ -// int result = 1; -// if (serialdevice->port) -// { -// result = check(sp_blocking_write(serialdevice->port, simdata, sizeof(SimData), arduino_timeout)); -// } -// -// return result; -//} - int arduino_init(SerialDevice* serialdevice, const char* portdev) { - slogi("initializing arduino serial device..."); - int error = 0; - char* port_name = strdup(portdev); - - slogd("Looking for port %s", port_name); - error = check(sp_get_port_by_name(port_name, &serialdevice->port)); - if (error != 0) - { - return error; - } - - slogd("Opening port"); - check(sp_open(serialdevice->port, SP_MODE_READ_WRITE)); - - slogd("Setting port to %i 8N1, no flow control", serialdevice->baudrate); - check(sp_set_baudrate(serialdevice->port, serialdevice->baudrate)); - check(sp_set_bits(serialdevice->port, 8)); - check(sp_set_parity(serialdevice->port, SP_PARITY_NONE)); - check(sp_set_stopbits(serialdevice->port, 1)); - check(sp_set_flowcontrol(serialdevice->port, SP_FLOWCONTROL_NONE)); - - free(port_name); - slogd("Successfully setup arduino serial device..."); - return 0; + serialdevice->id = monocoque_serial_open(serialdevice, portdev); + return serialdevice->id; } - -int arduino_free(SerialDevice* serialdevice) -{ - check(sp_close(serialdevice->port)); - sp_free_port(serialdevice->port); -} - -int check(enum sp_return result) -{ - /* For this example we'll just exit on any error by calling abort(). */ - char* error_message; - - switch (result) - { - case SP_ERR_ARG: - //printf("Error: Invalid argument.\n"); - return 1; - case SP_ERR_FAIL: - error_message = sp_last_error_message(); - sloge("error: serial write failed: %s", error_message); - sp_free_error_message(error_message); - case SP_ERR_SUPP: - printf("Error: Not supported.\n"); - case SP_ERR_MEM: - printf("Error: Couldn't allocate memory.\n"); - case SP_OK: - default: - return result; - } -} - diff --git a/src/monocoque/devices/serial/arduino.h b/src/monocoque/devices/serial/arduino.h index a348988..8bf47c9 100644 --- a/src/monocoque/devices/serial/arduino.h +++ b/src/monocoque/devices/serial/arduino.h @@ -8,6 +8,5 @@ int arduino_update(SerialDevice* serialdevice, void* data, size_t size); int arduino_init(SerialDevice* serialdevice, const char* portdev); int arduino_free(SerialDevice* serialdevice); -int check(enum sp_return result); #endif diff --git a/src/monocoque/devices/serial/moza.c b/src/monocoque/devices/serial/moza.c index 41def00..afda1a8 100644 --- a/src/monocoque/devices/serial/moza.c +++ b/src/monocoque/devices/serial/moza.c @@ -6,6 +6,7 @@ #include #include "moza.h" +#include "../serialadapter.h" #include "../../slog/slog.h" #define MOZA_TIMEOUT 1000 @@ -74,7 +75,7 @@ int moza_update(SerialDevice* serialdevice, unsigned short maxrpm, unsigned shor { slogd("copying %i bytes to moza device", size); slogt("writing bytes %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x from rpm %i maxrpm %i", bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], bytes[8], bytes[9], bytes[10], rpm, maxrpm); - result = moza_serial_check(sp_blocking_write(serialdevice->port, bytes, size, MOZA_TIMEOUT)); + result = monocoque_serial_write(serialdevice->id, bytes, size, MOZA_TIMEOUT); } return result; @@ -82,58 +83,6 @@ int moza_update(SerialDevice* serialdevice, unsigned short maxrpm, unsigned shor int moza_init(SerialDevice* serialdevice, const char* portdev) { - slogi("initializing moza serial device..."); - int error = 0; - char* port_name = strdup(portdev); - - slogd("Looking for port %s.\n", port_name); - error = moza_serial_check(sp_get_port_by_name(port_name, &serialdevice->port)); - if (error != 0) - { - return error; - } - - slogd("Opening port.\n"); - moza_serial_check(sp_open(serialdevice->port, SP_MODE_READ_WRITE)); - - slogd("Setting port to 115200 8N1, no flow control.\n"); - moza_serial_check(sp_set_baudrate(serialdevice->port, 115200)); - moza_serial_check(sp_set_bits(serialdevice->port, 8)); - moza_serial_check(sp_set_parity(serialdevice->port, SP_PARITY_NONE)); - moza_serial_check(sp_set_stopbits(serialdevice->port, 1)); - moza_serial_check(sp_set_flowcontrol(serialdevice->port, SP_FLOWCONTROL_NONE)); - - free(port_name); - slogd("Successfully setup moza serial device..."); - return 0; -} - -int moza_free(SerialDevice* serialdevice) -{ - moza_serial_check(sp_close(serialdevice->port)); - sp_free_port(serialdevice->port); -} - -// i have to move this some place common -int moza_serial_check(enum sp_return result) -{ - /* For this example we'll just exit on any error by calling abort(). */ - char* error_message; - - switch (result) - { - case SP_ERR_ARG: - return 1; - case SP_ERR_FAIL: - error_message = sp_last_error_message(); - sloge("error: serial write failed: %s", error_message); - sp_free_error_message(error_message); - case SP_ERR_SUPP: - printf("Error: Not supported.\n"); - case SP_ERR_MEM: - printf("Error: Couldn't allocate memory.\n"); - case SP_OK: - default: - return result; - } + serialdevice->id = monocoque_serial_open(serialdevice, portdev); + return serialdevice->id; } diff --git a/src/monocoque/devices/serialadapter.c b/src/monocoque/devices/serialadapter.c new file mode 100644 index 0000000..e0a421f --- /dev/null +++ b/src/monocoque/devices/serialadapter.c @@ -0,0 +1,205 @@ +#include +#include +#include +#include + +#include "serialadapter.h" +#include "../slog/slog.h" + +int msastrcicmp(char const *a, char const *b) +{ + for (;; a++, b++) { + int d = tolower((unsigned char)*a) - tolower((unsigned char)*b); + if (d != 0 || !*a) + return d; + } +} + +int check(enum sp_return result) +{ + char* error_message; + + switch (result) + { + case SP_ERR_ARG: + return 1; + case SP_ERR_FAIL: + error_message = sp_last_error_message(); + sloge("error: serial write failed: %s", error_message); + sp_free_error_message(error_message); + case SP_ERR_SUPP: + printf("Error: Not supported.\n"); + case SP_ERR_MEM: + printf("Error: Couldn't allocate memory.\n"); + case SP_OK: + default: + return result; + } +} + +int monocoque_serial_free(SerialDevice* serialdevice) +{ + monocoque_serial_device monocoque_serial_dev = monocoque_serial_devices[serialdevice->id]; + + if(monocoque_serial_dev.open == true) + { + while(monocoque_serial_dev.busy == true) + { + slogt("hopefully this doesn't happen long"); + continue; + } + + monocoque_serial_devices[serialdevice->id].busy = true; + monocoque_serial_devices[serialdevice->id].refs--; + + if(monocoque_serial_devices[serialdevice->id].refs == 0) + { + slogd("freeing physical device %s", monocoque_serial_devices[serialdevice->id].portname); + sp_close(monocoque_serial_devices[serialdevice->id].port); + sp_free_port(monocoque_serial_devices[serialdevice->id].port); + monocoque_serial_devices[serialdevice->id].busy = false; + monocoque_serial_devices[serialdevice->id].open = false; + monocoque_serial_devices[serialdevice->id].openfail = false; + free(monocoque_serial_devices[serialdevice->id].portname); + } + else + { + monocoque_serial_devices[serialdevice->id].busy = false; + } + + } +} + +int monocoque_serial_write(uint8_t serialdevicenum, void* data, size_t size, int timeout) +{ + slogt("serial device id %i", serialdevicenum); + monocoque_serial_device monocoque_serial_dev = monocoque_serial_devices[serialdevicenum]; + + slogt("port name: %s, busy %i, open %i, openfail %i", monocoque_serial_dev.portname, monocoque_serial_dev.busy, monocoque_serial_dev.open, monocoque_serial_dev.busy); + + if(monocoque_serial_dev.port == NULL) + { + sloge("port is null"); + } + + int result = -1; + if(monocoque_serial_dev.busy == false && monocoque_serial_dev.open == true) + { + monocoque_serial_dev.busy = true; + result = sp_blocking_write(monocoque_serial_dev.port, data, size, timeout); + } + else + { + slogw("serial device data update ignored due to busy or lost device"); + result = -1; + } + slogt("write result is %i", result); + monocoque_serial_dev.busy = false; + return result; +} + +int monocoque_serial_write_block(uint8_t serialdevicenum, void* data, size_t size, int timeout) +{ + slogt("serial device id %i", serialdevicenum); + monocoque_serial_device monocoque_serial_dev = monocoque_serial_devices[serialdevicenum]; + + slogt("port name: %s, busy %i, open %i, openfail %i", monocoque_serial_dev.portname, monocoque_serial_dev.busy, monocoque_serial_dev.open, monocoque_serial_dev.busy); + + if(monocoque_serial_dev.port == NULL) + { + sloge("port is null"); + } + + int result = -1; + if(monocoque_serial_dev.open == true) + { + while(monocoque_serial_dev.busy == true) + { + slogt("hopefully this doesn't happen long"); + continue; + } + + monocoque_serial_dev.busy = true; + result = sp_blocking_write(monocoque_serial_dev.port, data, size, timeout); + slogi("actually performed write"); + } + + monocoque_serial_dev.busy = false; + return result; +} + +int monocoque_serial_open(SerialDevice* serialdevice, const char* portdev) +{ + int serial_device_num = -1; + bool notfound = true; + slogi("looking to open physical serialdevice %s", portdev); + for(int i = 0; i < 10; i++) + { + if(monocoque_serial_devices[i].open == true || monocoque_serial_devices[i].openfail == true) + { + if(msastrcicmp(monocoque_serial_devices[i].portname, portdev) == 0) + { + notfound = false; + serial_device_num = i; + monocoque_serial_devices[i].refs++; + slogd("found exisiting handle to serial device %s", portdev); + } + } + } + + if(notfound == true) + { + slogd("no existing connections found, looking to create new"); + int i = -1; + bool avail = false; + while(avail == false) + { + i++; + if(monocoque_serial_devices[i].open == false && monocoque_serial_devices[i].openfail == false) + { + avail = true; + break; + } + } + + + slogi("opening physical serial device..."); + int error = 0; + char* port_name = strdup(portdev); + monocoque_serial_devices[i].portname = strdup(port_name); + + struct sp_port* sp; + slogd("Looking for port %s", port_name); + error = check(sp_get_port_by_name(port_name, &sp)); + if (error != 0) + { + monocoque_serial_devices[i].open = false; + monocoque_serial_devices[i].openfail = true; + return -1; + } + + slogd("Opening port"); + check(sp_open(sp, SP_MODE_READ_WRITE)); + + slogd("Setting port to %i 8N1, no flow control", serialdevice->baudrate); + check(sp_set_baudrate(sp, serialdevice->baudrate)); + check(sp_set_bits(sp, 8)); + check(sp_set_parity(sp, SP_PARITY_NONE)); + check(sp_set_stopbits(sp, 1)); + check(sp_set_flowcontrol(sp, SP_FLOWCONTROL_NONE)); + + monocoque_serial_devices[i].port = sp; + + monocoque_serial_devices[i].open = true; + monocoque_serial_devices[i].openfail = false; + monocoque_serial_devices[i].busy = false; + monocoque_serial_devices[i].refs++; + + serial_device_num = i; + + free(port_name); + slogd("Successfully setup arduino serial device..."); + } + + return serial_device_num; +} diff --git a/src/monocoque/devices/serialadapter.h b/src/monocoque/devices/serialadapter.h new file mode 100644 index 0000000..bc023aa --- /dev/null +++ b/src/monocoque/devices/serialadapter.h @@ -0,0 +1,28 @@ +#ifndef _SERIALADAPTER_H +#define _SERIALADAPTER_H + +#include +#include +#include + +#include "simdevice.h" + +typedef struct +{ + char* portname; + struct sp_port* port; + uint8_t refs; + bool open; + bool openfail; + bool busy; +} +monocoque_serial_device; + +static monocoque_serial_device monocoque_serial_devices[10]; + +int monocoque_serial_write(uint8_t serialdevicenum, void* data, size_t size, int timeout); +int monocoque_serial_write_block(uint8_t serialdevicenum, void* data, size_t size, int timeout); +int monocoque_serial_open(SerialDevice* serialdevice, const char* port); +int monocoque_serial_free(SerialDevice* serialdevice); + +#endif diff --git a/src/monocoque/devices/serialdevice.c b/src/monocoque/devices/serialdevice.c index 34d0c6e..d607396 100644 --- a/src/monocoque/devices/serialdevice.c +++ b/src/monocoque/devices/serialdevice.c @@ -6,6 +6,7 @@ #include "simdevice.h" #include "serialdevice.h" +#include "serialadapter.h" #include "hapticeffect.h" #include "serial/arduino.h" #include "serial/moza.h" @@ -134,9 +135,29 @@ int serialdev_free(SimDevice* this) { SerialDevice* serialdevice = (void *) this->derived; - arduino_free(serialdevice); + switch (serialdevice->devicetype) { + case (ARDUINODEV__HAPTIC): + + serialdevice->u.simhapticdata.effect1 = 0; + serialdevice->u.simhapticdata.motor1 = 1; + serialdevice->u.simhapticdata.effect2 = 0; + serialdevice->u.simhapticdata.motor2 = 1; + serialdevice->u.simhapticdata.effect3 = 0; + serialdevice->u.simhapticdata.motor3 = 1; + serialdevice->u.simhapticdata.effect4 = 0; + serialdevice->u.simhapticdata.motor4 = 1; + serialdevice->state = 0; + + size_t size = sizeof(SimHapticData); + monocoque_serial_write_block(serialdevice->id, &serialdevice->u.simhapticdata, size, 9000); + slogi("set zero to arduino device"); + } + + + monocoque_serial_free(serialdevice); free(serialdevice); + return 0; } @@ -144,9 +165,10 @@ int serial_wheel_free(SimDevice* this) { SerialDevice* serialdevice = (void *) this->derived; - moza_free(serialdevice); + monocoque_serial_free(serialdevice); free(serialdevice); + return 0; } @@ -250,7 +272,7 @@ SerialDevice* new_serial_device(DeviceSettings* ds, MonocoqueSettings* ms) { int error = serialdev_init(this, ds); - if (error != 0) + if (error < 0) { free(this); return NULL; diff --git a/src/monocoque/gameloop/gameloop.c b/src/monocoque/gameloop/gameloop.c index a8e6949..6cbc6be 100644 --- a/src/monocoque/gameloop/gameloop.c +++ b/src/monocoque/gameloop/gameloop.c @@ -15,6 +15,7 @@ #include "../helper/parameters.h" #include "../helper/confighelper.h" #include "../devices/simdevice.h" +#include "../devices/serialadapter.h" #include "../simulatorapi/simapi/simapi/simdata.h" #include "../simulatorapi/simapi/simapi/simmapper.h" #include "../slog/slog.h" @@ -242,6 +243,10 @@ void looprun(MonocoqueSettings* ms, loop_data* f, SimData* simdata) slogd("loading confignum %i, with %i devices.", confignum, configureddevices); f->numdevices = uiloadconfig(ms->config_str, confignum, configureddevices, ms, ds); + if(ms->useconfig == 1) + { + ms->configcheck = 0; + } f->simdevices = malloc(f->numdevices * sizeof(SimDevice)); int initdevices = devinit(f->simdevices, configureddevices, ds, ms); @@ -253,6 +258,14 @@ void looprun(MonocoqueSettings* ms, loop_data* f, SimData* simdata) free(ds); + for(int d = 0; d < 10; d++) + { + monocoque_serial_devices[d].open = false; + monocoque_serial_devices[d].openfail = false; + monocoque_serial_devices[d].busy = false; + monocoque_serial_devices[d].refs = 0; + } + int numdevices = f->numdevices; SimDevice* devices = f->simdevices; @@ -350,6 +363,15 @@ void shmdatamapcallback(uv_timer_t* handle) } } free(devices); + + for(int d = 0; d < 10; d++) + { + if(monocoque_serial_devices[d].portname != NULL) + { + free(monocoque_serial_devices[d].portname); + } + } + int r = simfree(simdata, simmap, f->map); slogd("simfree returned %i", r); f->numdevices = 0;